OpenCL 1.0 support: explicit casts to ext-vector types


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74247 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a01fbb1..3d22321 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2876,12 +2876,15 @@
     return Diag(castExpr->getLocStart(),
                 diag::err_typecheck_expect_scalar_operand)
       << castExpr->getType() << castExpr->getSourceRange();
-  } else if (castExpr->getType()->isVectorType()) {
-    if (CheckVectorCast(TyR, castExpr->getType(), castType))
+  } else if (castType->isExtVectorType()) {
+    if (CheckExtVectorCast(TyR, castType, castExpr->getType()))
       return true;
   } else if (castType->isVectorType()) {
     if (CheckVectorCast(TyR, castType, castExpr->getType()))
       return true;
+  } else if (castExpr->getType()->isVectorType()) {
+    if (CheckVectorCast(TyR, castExpr->getType(), castType))
+      return true;
   } else if (getLangOptions().ObjC1 && isa<ObjCSuperExpr>(castExpr)) {
     return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast) << TyR;
   } else if (!castType->isArithmeticType()) {
@@ -2919,6 +2922,35 @@
   return false;
 }
 
+bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) {
+  assert(DestTy->isExtVectorType() && "Not an extended vector type!");
+  
+  // If SrcTy is also an ExtVectorType, the types must be identical unless 
+  // lax vector conversions is enabled.
+  if (SrcTy->isExtVectorType()) {
+    if (getLangOptions().LaxVectorConversions &&
+        Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy))
+      return false;
+    if (DestTy != SrcTy)
+      return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
+      << DestTy << SrcTy << R;
+    return false;
+  }
+  
+  // If SrcTy is a VectorType, then only the total size must match.
+  if (SrcTy->isVectorType()) {
+    if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
+      return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
+        << DestTy << SrcTy << R;
+    return false;
+  }
+
+  // All scalar -> ext vector "c-style" casts are legal; the appropriate
+  // conversion will take place first from scalar to elt type, and then
+  // splat from elt type to vector.
+  return false;
+}
+
 Action::OwningExprResult
 Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
                     SourceLocation RParenLoc, ExprArg Op) {