Update support for vector component access on ExtVectors.
llvm-svn: 62440
This commit is contained in:
parent
95439108e8
commit
bb70bf6dbb
|
@ -900,7 +900,7 @@ protected:
|
|||
Type(Vector, canonType, vecType->isDependentType()),
|
||||
ElementType(vecType), NumElements(nElements) {}
|
||||
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
|
||||
QualType canonType)
|
||||
QualType canonType)
|
||||
: Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
|
||||
NumElements(nElements) {}
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
|
@ -945,29 +945,31 @@ public:
|
|||
case 'w': return 3;
|
||||
}
|
||||
}
|
||||
static int getColorAccessorIdx(char c) {
|
||||
static int getNumericAccessorIdx(char c) {
|
||||
switch (c) {
|
||||
default: return -1;
|
||||
case 'r': return 0;
|
||||
case 'g': return 1;
|
||||
case 'b': return 2;
|
||||
case 'a': return 3;
|
||||
default: return -1;
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a': return 10;
|
||||
case 'b': return 11;
|
||||
case 'c': return 12;
|
||||
case 'd': return 13;
|
||||
case 'e': return 14;
|
||||
case 'f': return 15;
|
||||
}
|
||||
}
|
||||
static int getTextureAccessorIdx(char c) {
|
||||
switch (c) {
|
||||
default: return -1;
|
||||
case 's': return 0;
|
||||
case 't': return 1;
|
||||
case 'p': return 2;
|
||||
case 'q': return 3;
|
||||
}
|
||||
};
|
||||
|
||||
static int getAccessorIdx(char c) {
|
||||
if (int idx = getPointAccessorIdx(c)+1) return idx-1;
|
||||
if (int idx = getColorAccessorIdx(c)+1) return idx-1;
|
||||
return getTextureAccessorIdx(c);
|
||||
return getNumericAccessorIdx(c);
|
||||
}
|
||||
|
||||
bool isAccessorWithinNumElements(char c) const {
|
||||
|
|
|
@ -1173,12 +1173,15 @@ bool ExtVectorElementExpr::containsDuplicateElements() const {
|
|||
/// getEncodedElementAccess - We encode the fields as a llvm ConstantArray.
|
||||
void ExtVectorElementExpr::getEncodedElementAccess(
|
||||
llvm::SmallVectorImpl<unsigned> &Elts) const {
|
||||
bool isHi = Accessor.isStr("hi");
|
||||
bool isLo = Accessor.isStr("lo");
|
||||
bool isEven = Accessor.isStr("e");
|
||||
bool isOdd = Accessor.isStr("o");
|
||||
|
||||
const char *compStr = Accessor.getName();
|
||||
if (*compStr == 's')
|
||||
compStr++;
|
||||
|
||||
bool isHi = !strcmp(compStr, "hi");
|
||||
bool isLo = !strcmp(compStr, "lo");
|
||||
bool isEven = !strcmp(compStr, "even");
|
||||
bool isOdd = !strcmp(compStr, "odd");
|
||||
|
||||
for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
|
||||
uint64_t Index;
|
||||
|
||||
|
|
|
@ -1325,64 +1325,61 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
|
|||
IdentifierInfo &CompName, SourceLocation CompLoc) {
|
||||
const ExtVectorType *vecType = baseType->getAsExtVectorType();
|
||||
|
||||
// This flag determines whether or not the component is to be treated as a
|
||||
// special name, or a regular GLSL-style component access.
|
||||
bool SpecialComponent = false;
|
||||
|
||||
// The vector accessor can't exceed the number of elements.
|
||||
const char *compStr = CompName.getName();
|
||||
if (strlen(compStr) > vecType->getNumElements()) {
|
||||
Diag(OpLoc, diag::err_ext_vector_component_exceeds_length)
|
||||
<< baseType << SourceRange(CompLoc);
|
||||
return QualType();
|
||||
}
|
||||
|
||||
// This flag determines whether or not the component is one of the four
|
||||
// special names that indicate a subset of exactly half the elements are
|
||||
// to be selected.
|
||||
bool HalvingSwizzle = false;
|
||||
|
||||
// This flag determines whether or not CompName has an 's' char prefix,
|
||||
// indicating that it is a string of hex values to be used as vector indices.
|
||||
bool HexSwizzle = *compStr == 's';
|
||||
|
||||
// Check that we've found one of the special components, or that the component
|
||||
// names must come from the same set.
|
||||
if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") ||
|
||||
!strcmp(compStr, "e") || !strcmp(compStr, "o")) {
|
||||
SpecialComponent = true;
|
||||
!strcmp(compStr, "even") || !strcmp(compStr, "odd")) {
|
||||
HalvingSwizzle = true;
|
||||
} else if (vecType->getPointAccessorIdx(*compStr) != -1) {
|
||||
do
|
||||
compStr++;
|
||||
while (*compStr && vecType->getPointAccessorIdx(*compStr) != -1);
|
||||
} else if (vecType->getColorAccessorIdx(*compStr) != -1) {
|
||||
} else if (HexSwizzle || vecType->getNumericAccessorIdx(*compStr) != -1) {
|
||||
do
|
||||
compStr++;
|
||||
while (*compStr && vecType->getColorAccessorIdx(*compStr) != -1);
|
||||
} else if (vecType->getTextureAccessorIdx(*compStr) != -1) {
|
||||
do
|
||||
compStr++;
|
||||
while (*compStr && vecType->getTextureAccessorIdx(*compStr) != -1);
|
||||
while (*compStr && vecType->getNumericAccessorIdx(*compStr) != -1);
|
||||
}
|
||||
|
||||
if (!SpecialComponent && *compStr) {
|
||||
|
||||
if (!HalvingSwizzle && *compStr) {
|
||||
// We didn't get to the end of the string. This means the component names
|
||||
// didn't come from the same set *or* we encountered an illegal name.
|
||||
Diag(OpLoc, diag::err_ext_vector_component_name_illegal)
|
||||
<< std::string(compStr,compStr+1) << SourceRange(CompLoc);
|
||||
return QualType();
|
||||
}
|
||||
// Each component accessor can't exceed the vector type.
|
||||
compStr = CompName.getName();
|
||||
while (*compStr) {
|
||||
if (vecType->isAccessorWithinNumElements(*compStr))
|
||||
|
||||
// Ensure no component accessor exceeds the width of the vector type it
|
||||
// operates on.
|
||||
if (!HalvingSwizzle) {
|
||||
compStr = CompName.getName();
|
||||
|
||||
if (HexSwizzle)
|
||||
compStr++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!SpecialComponent && *compStr) {
|
||||
// We didn't get to the end of the string. This means a component accessor
|
||||
// exceeds the number of elements in the vector.
|
||||
Diag(OpLoc, diag::err_ext_vector_component_exceeds_length)
|
||||
<< baseType << SourceRange(CompLoc);
|
||||
return QualType();
|
||||
|
||||
while (*compStr) {
|
||||
if (!vecType->isAccessorWithinNumElements(*compStr++)) {
|
||||
Diag(OpLoc, diag::err_ext_vector_component_exceeds_length)
|
||||
<< baseType << SourceRange(CompLoc);
|
||||
return QualType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a special component name, verify that the current vector length
|
||||
// is an even number, since all special component names return exactly half
|
||||
// the elements.
|
||||
if (SpecialComponent && (vecType->getNumElements() & 1U)) {
|
||||
// If this is a halving swizzle, verify that the base type has an even
|
||||
// number of elements.
|
||||
if (HalvingSwizzle && (vecType->getNumElements() & 1U)) {
|
||||
Diag(OpLoc, diag::err_ext_vector_component_requires_even)
|
||||
<< baseType << SourceRange(CompLoc);
|
||||
return QualType();
|
||||
|
@ -1391,9 +1388,13 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
|
|||
// The component accessor looks fine - now we need to compute the actual type.
|
||||
// The vector type is implied by the component accessor. For example,
|
||||
// vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc.
|
||||
// vec4.s0 is a float, vec4.s23 is a vec3, etc.
|
||||
// vec4.hi, vec4.lo, vec4.e, and vec4.o all return vec2.
|
||||
unsigned CompSize = SpecialComponent ? vecType->getNumElements() / 2
|
||||
: CompName.getLength();
|
||||
unsigned CompSize = HalvingSwizzle ? vecType->getNumElements() / 2
|
||||
: CompName.getLength();
|
||||
if (HexSwizzle)
|
||||
CompSize--;
|
||||
|
||||
if (CompSize == 1)
|
||||
return vecType->getElementType();
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
typedef __attribute__(( ext_vector_type(2) )) float float2;
|
||||
typedef __attribute__(( ext_vector_type(3) )) float float3;
|
||||
typedef __attribute__(( ext_vector_type(4) )) float float4;
|
||||
|
||||
static void test() {
|
||||
float2 vec2, vec2_2;
|
||||
float3 vec3;
|
||||
float4 vec4, vec4_2;
|
||||
float f;
|
||||
|
||||
vec2.z; // expected-error {{vector component access exceeds type 'float2'}}
|
||||
vec2.rgba; // expected-error {{vector component access exceeds type 'float2'}}
|
||||
vec4.rgba; // expected-warning {{expression result unused}}
|
||||
vec4.rgbc; // expected-error {{illegal vector component name 'c'}}
|
||||
vec3 = vec4.rgb; // legal, shorten
|
||||
f = vec2.x; // legal, shorten
|
||||
|
||||
vec4_2.rgbr = vec4.rgba; // expected-error {{vector is not assignable (contains duplicate components)}}
|
||||
vec4_2.rgbb = vec4.rgba; // expected-error {{vector is not assignable (contains duplicate components)}}
|
||||
vec4_2.rgga = vec4.rgba; // expected-error {{vector is not assignable (contains duplicate components)}}
|
||||
vec2.x = f;
|
||||
vec2.xx = vec2_2.xy; // expected-error {{vector is not assignable (contains duplicate components)}}
|
||||
vec2.yx = vec2_2.xy;
|
||||
vec4 = (float4){ 1,2,3,4 };
|
||||
vec4.rg.a; // expected-error {{vector component access exceeds type 'float2'}}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
typedef __attribute__(( ext_vector_type(2) )) float float2;
|
||||
typedef __attribute__(( ext_vector_type(3) )) float float3;
|
||||
typedef __attribute__(( ext_vector_type(4) )) float float4;
|
||||
|
||||
static void test() {
|
||||
float2 vec2, vec2_2;
|
||||
float3 vec3;
|
||||
float4 vec4, vec4_2;
|
||||
float f;
|
||||
|
||||
vec2.z; // expected-error {{vector component access exceeds type 'float2'}}
|
||||
vec2.xyzw; // expected-error {{vector component access exceeds type 'float2'}}
|
||||
vec4.xyzw; // expected-warning {{expression result unused}}
|
||||
vec4.xyzc; // expected-error {{illegal vector component name 'c'}}
|
||||
vec4.s01z; // expected-error {{illegal vector component name 'z'}}
|
||||
vec2 = vec4.s01; // legal, shorten
|
||||
|
||||
vec3 = vec4.xyz; // legal, shorten
|
||||
f = vec2.x; // legal, shorten
|
||||
f = vec4.xy.x; // legal, shorten
|
||||
|
||||
vec2 = vec3.hi; // expected-error {{vector component access invalid for odd-sized type 'float3'}}
|
||||
|
||||
vec4_2.xyzx = vec4.xyzw; // expected-error {{vector is not assignable (contains duplicate components)}}
|
||||
vec4_2.xyzz = vec4.xyzw; // expected-error {{vector is not assignable (contains duplicate components)}}
|
||||
vec4_2.xyyw = vec4.xyzw; // expected-error {{vector is not assignable (contains duplicate components)}}
|
||||
vec2.x = f;
|
||||
vec2.xx = vec2_2.xy; // expected-error {{vector is not assignable (contains duplicate components)}}
|
||||
vec2.yx = vec2_2.xy;
|
||||
vec4 = (float4){ 1,2,3,4 };
|
||||
vec4.xy.w; // expected-error {{vector component access exceeds type 'float2'}}
|
||||
vec4.s06; // expected-error {{vector component access exceeds type 'float4'}}
|
||||
}
|
Loading…
Reference in New Issue