[cfe-commits] r62440 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Expr.cpp lib/Sema/SemaExpr.cpp test/Parser/ext_vector_components.c test/Sema/ext_vector_components.c

Nate Begeman natebegeman at mac.com
Sat Jan 17 17:47:54 PST 2009


Author: sampo
Date: Sat Jan 17 19:47:54 2009
New Revision: 62440

URL: http://llvm.org/viewvc/llvm-project?rev=62440&view=rev
Log:
Update support for vector component access on ExtVectors.

Added:
    cfe/trunk/test/Sema/ext_vector_components.c
      - copied, changed from r62439, cfe/trunk/test/Parser/ext_vector_components.c
Removed:
    cfe/trunk/test/Parser/ext_vector_components.c
Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=62440&r1=62439&r2=62440&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Jan 17 19:47:54 2009
@@ -900,7 +900,7 @@
     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 @@
     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 {

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=62440&r1=62439&r2=62440&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat Jan 17 19:47:54 2009
@@ -1173,12 +1173,15 @@
 /// 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;
     

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=62440&r1=62439&r2=62440&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Jan 17 19:47:54 2009
@@ -1325,64 +1325,61 @@
                         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 @@
   // 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();
     

Removed: cfe/trunk/test/Parser/ext_vector_components.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/ext_vector_components.c?rev=62439&view=auto

==============================================================================
--- cfe/trunk/test/Parser/ext_vector_components.c (original)
+++ cfe/trunk/test/Parser/ext_vector_components.c (removed)
@@ -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'}}
-}

Copied: cfe/trunk/test/Sema/ext_vector_components.c (from r62439, cfe/trunk/test/Parser/ext_vector_components.c)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ext_vector_components.c?p2=cfe/trunk/test/Sema/ext_vector_components.c&p1=cfe/trunk/test/Parser/ext_vector_components.c&r1=62439&r2=62440&rev=62440&view=diff

==============================================================================
--- cfe/trunk/test/Parser/ext_vector_components.c (original)
+++ cfe/trunk/test/Sema/ext_vector_components.c Sat Jan 17 19:47:54 2009
@@ -11,18 +11,25 @@
     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
+    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.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)}}
+    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.rg.a; // expected-error {{vector component access exceeds type 'float2'}}
+    vec4.xy.w; // expected-error {{vector component access exceeds type 'float2'}}
+    vec4.s06; // expected-error {{vector component access exceeds type 'float4'}}
 }





More information about the cfe-commits mailing list