pirama updated this revision to Diff 60425.
pirama added a comment.

Convert error to warning, update tests, and rename variable name.


http://reviews.llvm.org/D20602

Files:
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/AST/Expr.cpp
  lib/Sema/SemaExprMember.cpp
  test/CodeGen/ext-vector.c
  test/Misc/warning-flags.c
  test/Sema/ext_vector_components.c
  test/SemaOpenCL/ext_vectors.cl

Index: test/SemaOpenCL/ext_vectors.cl
===================================================================
--- /dev/null
+++ test/SemaOpenCL/ext_vectors.cl
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.1
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+
+void test_ext_vector_accessors(float4 V) {
+  V = V.wzyx;
+  V = V.abgr; // expected-warning {{vector component name 'a' is an OpenCL version 2.2 feature}}
+  V = V.xyzr; // expected-warning {{vector component name 'r' is an OpenCL version 2.2 feature}} \
+              // expected-error {{illegal vector component name 'r'}}
+}
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/Misc/warning-flags.c
===================================================================
--- test/Misc/warning-flags.c
+++ test/Misc/warning-flags.c
@@ -18,15 +18,16 @@
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (84):
+CHECK: Warnings without flags (85):
 CHECK-NEXT:   ext_excess_initializers
 CHECK-NEXT:   ext_excess_initializers_in_char_array_initializer
 CHECK-NEXT:   ext_expected_semi_decl_list
 CHECK-NEXT:   ext_explicit_specialization_storage_class
 CHECK-NEXT:   ext_initializer_string_for_char_array_too_long
 CHECK-NEXT:   ext_missing_declspec
 CHECK-NEXT:   ext_missing_whitespace_after_macro_name
 CHECK-NEXT:   ext_new_paren_array_nonconst
+CHECK-NEXT:   ext_opencl_ext_vector_type_rgba_selector
 CHECK-NEXT:   ext_plain_complex
 CHECK-NEXT:   ext_template_arg_extra_parens
 CHECK-NEXT:   ext_typecheck_comparison_of_pointer_integer
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,11 +321,25 @@
     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++;
     } while (*compStr && (Idx = vecType->getPointAccessorIdx(*compStr)) != -1);
+
+    // Emit a warning if an rgba selector is used earlier than OpenCL 2.2
+    if (HasRGBA || (*compStr && IsRGBA(*compStr))) {
+      if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion < 220) {
+        const char *DiagBegin = HasRGBA ? CompName->getNameStart() : compStr;
+        S.Diag(OpLoc, diag::ext_opencl_ext_vector_type_rgba_selector)
+          << StringRef(DiagBegin, 1)
+          << S.getLangOpts().OpenCLVersion << SourceRange(CompLoc);
+      }
+    }
   } else {
     if (HexSwizzle) compStr++;
     while ((Idx = vecType->getNumericAccessorIdx(*compStr)) != -1) {
@@ -338,7 +366,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/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -7901,6 +7901,10 @@
   "invalid number of arguments to function: %0">;
 def err_opencl_builtin_to_addr_invalid_arg : Error<
   "invalid argument %0 to function: %1, expecting a generic pointer argument">;
+
+// OpenCL v2.2 s2.1.2.3 - Vector Component Access
+def ext_opencl_ext_vector_type_rgba_selector: ExtWarn<
+  "vector component name '%0' is an OpenCL version 2.2 feature">;
 } // end of sema category
 
 let CategoryName = "OpenMP Issue" in {
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -2807,19 +2807,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) {
@@ -2850,13 +2851,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

Reply via email to