forked from OSchip/llvm-project
OpenCL 1.0 support: explicit casts to ext-vector types
llvm-svn: 74247
This commit is contained in:
parent
2aaad91bbe
commit
c69b740df4
|
@ -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<
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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'}}
|
||||
}
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue