pirama created this revision. pirama added subscribers: cfe-commits, srhines.
This patch enables .rgba accessors to ext_vector_type types and adds tests for syntax validation and code generation. 'a' and 'b' can appear either in the point access mode or the numeric access mode (for indices 10 and 11). To disambiguate between the two usages, the accessor type is explicitly passed to relevant methods. http://reviews.llvm.org/D20602 Files: include/clang/AST/Type.h lib/AST/Expr.cpp lib/Sema/SemaExprMember.cpp test/CodeGen/ext-vector.c test/Sema/ext_vector_components.c
Index: test/Sema/ext_vector_components.c =================================================================== --- test/Sema/ext_vector_components.c +++ test/Sema/ext_vector_components.c @@ -39,6 +39,33 @@ vec4.x = vec16.sF; vec4p->yz = vec4p->xy; + + vec2.a; // 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.rgbz; // expected-error {{illegal vector component name 'z'}} + vec4.rgbc; // expected-error {{illegal vector component name 'c'}} + vec4.xyzr; // expected-error {{illegal vector component name 'r'}} + vec4.s01b; // expected-error {{vector component access exceeds type 'float4'}} + + vec3 = vec4.rgb; // legal, shorten + f = vec2.r; // legal, shorten + f = vec4.rg.r; // legal, shorten + vec4_2.rgba = vec4.xyzw; // legal, no intermingling + + 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.rr = vec2_2.rg; // expected-error {{vector is not assignable (contains duplicate components)}} + vec2.gr = vec2_2.rg; + vec2.gr.g = vec2_2.r; + vec4 = (float4){ 1,2,3,4 }; + vec4.rg.b; // expected-error {{vector component access exceeds type 'float2'}} + vec4.r = vec16.sf; + vec4.g = vec16.sF; + + vec4p->gb = vec4p->rg; } float2 lo(float3 x) { return x.lo; } Index: test/CodeGen/ext-vector.c =================================================================== --- test/CodeGen/ext-vector.c +++ test/CodeGen/ext-vector.c @@ -301,3 +301,40 @@ char valC; char16 destVal = valC ? valA : valB; } + +typedef __attribute__(( ext_vector_type(16) )) float float16; + +float16 vec16, vec16_2; + +// CHECK: @test_rgba +void test_rgba() { + // CHECK: fadd <4 x float> + vec4_2 = vec4.abgr + vec4; + + // CHECK: shufflevector {{.*}} <i32 0, i32 1> + vec2 = vec4.rg; + // CHECK: shufflevector {{.*}} <i32 2, i32 3> + vec2_2 = vec4.ba; + // CHECK: extractelement {{.*}} 2 + f = vec4.b; + // CHECK: shufflevector {{.*}} <i32 2, i32 2, i32 2, i32 2> + vec4_2 = vec4_2.bbbb; + + // CHECK: insertelement {{.*}} 0 + vec2.r = f; + // CHECK: shufflevector {{.*}} <i32 1, i32 0> + vec2.gr = vec2; + + // CHECK: extractelement {{.*}} 0 + f = vec4_2.rg.r; + // CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0> + // CHECK: shufflevector {{.*}} <i32 0, i32 1, i32 2, i32 undef> + // CHECK: shufflevector {{.*}} <i32 4, i32 5, i32 6, i32 3> + vec4.rgb = vec4.bgr; + + // CHECK: extractelement {{.*}} 11 + // CHECK: insertelement {{.*}} 2 + vec4.b = vec16.sb; + // CHECK: shufflevector {{.*}} <i32 10, i32 11, i32 12, i32 13> + vec4_2 = vec16.sabcd; +} Index: lib/Sema/SemaExprMember.cpp =================================================================== --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -268,6 +268,20 @@ llvm_unreachable("unexpected instance member access kind"); } +/// Determine whether input char is from rgba component set. +static bool +IsRGBA(char c) { + switch (c) { + case 'r': + case 'g': + case 'b': + case 'a': + return true; + default: + return false; + } +} + /// Check an ext-vector component access expression. /// /// VK should be set in advance to the value kind of the base @@ -307,7 +321,11 @@ HalvingSwizzle = true; } else if (!HexSwizzle && (Idx = vecType->getPointAccessorIdx(*compStr)) != -1) { + bool HasRGBA = IsRGBA(*compStr); do { + // Ensure that xyzw and rgba components don't intermingle. + if (HasRGBA != IsRGBA(*compStr)) + break; if (HasIndex[Idx]) HasRepeated = true; HasIndex[Idx] = true; compStr++; @@ -338,7 +356,7 @@ compStr++; while (*compStr) { - if (!vecType->isAccessorWithinNumElements(*compStr++)) { + if (!vecType->isAccessorWithinNumElements(*compStr++, HexSwizzle)) { S.Diag(OpLoc, diag::err_ext_vector_component_exceeds_length) << baseType << SourceRange(CompLoc); return QualType(); Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -3383,8 +3383,11 @@ void ExtVectorElementExpr::getEncodedElementAccess( SmallVectorImpl<uint32_t> &Elts) const { StringRef Comp = Accessor->getName(); - if (Comp[0] == 's' || Comp[0] == 'S') + bool isNumericAccessor = false; + if (Comp[0] == 's' || Comp[0] == 'S') { Comp = Comp.substr(1); + isNumericAccessor = true; + } bool isHi = Comp == "hi"; bool isLo = Comp == "lo"; @@ -3403,7 +3406,7 @@ else if (isOdd) Index = 2 * i + 1; else - Index = ExtVectorType::getAccessorIdx(Comp[i]); + Index = ExtVectorType::getAccessorIdx(Comp[i], isNumericAccessor); Elts.push_back(Index); } Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -2794,19 +2794,20 @@ /// __attribute__((ext_vector_type(n)), where "n" is the number of elements. /// Unlike vector_size, ext_vector_type is only allowed on typedef's. This /// class enables syntactic extensions, like Vector Components for accessing -/// points, colors, and textures (modeled after OpenGL Shading Language). +/// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL +/// Shading Language). class ExtVectorType : public VectorType { ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} friend class ASTContext; // ASTContext creates these. public: static int getPointAccessorIdx(char c) { switch (c) { default: return -1; - case 'x': return 0; - case 'y': return 1; - case 'z': return 2; - case 'w': return 3; + case 'x': case 'r': return 0; + case 'y': case 'g': return 1; + case 'z': case 'b': return 2; + case 'w': case 'a': return 3; } } static int getNumericAccessorIdx(char c) { @@ -2837,13 +2838,15 @@ } } - static int getAccessorIdx(char c) { - if (int idx = getPointAccessorIdx(c)+1) return idx-1; - return getNumericAccessorIdx(c); + static int getAccessorIdx(char c, bool isNumericAccessor) { + if (isNumericAccessor) + return getNumericAccessorIdx(c); + else + return getPointAccessorIdx(c); } - bool isAccessorWithinNumElements(char c) const { - if (int idx = getAccessorIdx(c)+1) + bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const { + if (int idx = getAccessorIdx(c, isNumericAccessor)+1) return unsigned(idx-1) < getNumElements(); return false; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits