OpenCL 1.0 support: explicit casts to ext-vector types

llvm-svn: 74247
This commit is contained in:
Nate Begeman 2009-06-26 00:50:28 +00:00
parent 2aaad91bbe
commit c69b740df4
5 changed files with 69 additions and 4 deletions

View File

@ -1860,6 +1860,9 @@ def err_selector_element_type : Error<
def err_collection_expr_type : Error<
"collection expression type %0 is not a valid object">;
def err_invalid_conversion_between_ext_vectors : Error<
"invalid conversion between ext-vector type %0 and %1">;
// Type
def ext_invalid_sign_spec : Extension<"'%0' cannot be signed or unsigned">;
def warn_receiver_forward_class : Warning<

View File

@ -3063,6 +3063,13 @@ public:
// returns true if the cast is invalid
bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
// CheckExtVectorCast - check type constraints for extended vectors.
// Since vectors are an extension, there are no C standard reference for this.
// 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);
/// CheckMessageArgumentTypes - Check types in an Obj-C message send.
/// \param Method - May be null.
/// \param [out] ReturnType - The return type of the send.

View File

@ -2876,12 +2876,15 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) {
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 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty) {
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) {

View File

@ -0,0 +1,23 @@
// RUN: clang-cc -fsyntax-only -verify %s
typedef __attribute__(( ext_vector_type(2) )) float float2;
typedef __attribute__(( ext_vector_type(4) )) int int4;
typedef __attribute__(( ext_vector_type(4) )) float float4;
typedef float t3 __attribute__ ((vector_size (16)));
static void test() {
float2 vec2;
float4 vec4, vec4_2;
int4 ivec4;
t3 vec4_3;
vec4 = (float4)5.0f;
vec4 = (float4)5;
vec4 = (float4)vec4_3;
ivec4 = (int4)5.0f;
ivec4 = (int4)5;
ivec4 = (int4)vec4_3;
vec4 = (float4)vec2; // expected-error {{invalid conversion between ext-vector type 'float4' and 'float2'}}
}

View File

@ -11,9 +11,9 @@ void f()
t3 v3;
v2 = (t2)v1; // -expected-error {{invalid conversion between vector type \
't1' and 't2' of different size}}
v1 = (t1)v2; // -expected-error {{invalid conversion between vector type \
't2' and 't1' of different size}}
v1 = (t1)v2; // -expected-error {{invalid conversion between vector type \
't1' and 't2' of different size}}
v3 = (t3)v2;
v1 = (t1)(char *)10; // -expected-error {{invalid conversion between vector \