yaxunl updated this revision to Diff 55600.
yaxunl added a comment.

Add defining macro cl_khr_ for supported extensions or optional core features.

Enable supported extensions or optional core features only if it is available 
in the OpenCL version the program is compiled with.

Add spir triple to tests using extensions.

Generated  full diffs.


http://reviews.llvm.org/D19484

Files:
  include/clang/Basic/LangOptions.h
  include/clang/Basic/OpenCLExtensions.def
  include/clang/Basic/OpenCLOptions.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TargetOptions.h
  lib/Basic/Targets.cpp
  lib/Frontend/InitPreprocessor.cpp
  lib/Parse/ParsePragma.cpp
  lib/Sema/Sema.cpp
  test/CodeGenOpenCL/builtins-r600.cl
  test/CodeGenOpenCL/fpmath.cl
  test/CodeGenOpenCL/half.cl
  test/Lexer/opencl-half-literal.cl
  test/Misc/languageOptsOpenCL.cl
  test/PCH/opencl-extensions.cl
  test/Parser/opencl-astype.cl
  test/Parser/opencl-atomics-cl20.cl
  test/Parser/opencl-pragma.cl
  test/Parser/opencl-storage-class.cl
  test/SemaOpenCL/extension-fp64-cl1.1.cl
  test/SemaOpenCL/extension-fp64.cl
  test/SemaOpenCL/extensions.cl
  test/SemaOpenCL/half.cl
  test/SemaOpenCL/invalid-kernel-parameters.cl
  test/SemaOpenCL/invalid-logical-ops-1.2.cl
  test/SemaOpenCL/optional-core-fp64-cl1.2.cl
  test/SemaOpenCL/optional-core-fp64-cl2.0.cl

Index: test/SemaOpenCL/optional-core-fp64-cl2.0.cl
===================================================================
--- test/SemaOpenCL/optional-core-fp64-cl2.0.cl
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0
-// expected-no-diagnostics
-
-void f1(double da) {
-  double d;
-  (void) 1.0;
-}
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-void f2(void) {
-  double d;
-  (void) 1.0;
-}
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : disable
-
-void f3(void) {
-  double d;
-}
Index: test/SemaOpenCL/optional-core-fp64-cl1.2.cl
===================================================================
--- test/SemaOpenCL/optional-core-fp64-cl1.2.cl
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2
-// expected-no-diagnostics
-
-void f1(double da) {
-  double d;
-  (void) 1.0;
-}
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-void f2(void) {
-  double d;
-  (void) 1.0;
-}
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : disable
-
-void f3(void) {
-  double d;
-}
Index: test/SemaOpenCL/invalid-logical-ops-1.2.cl
===================================================================
--- test/SemaOpenCL/invalid-logical-ops-1.2.cl
+++ test/SemaOpenCL/invalid-logical-ops-1.2.cl
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 %s -verify -cl-std=CL1.2 -triple x86_64-unknown-linux-gnu
 
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable // expected-warning{{unknown OpenCL extension 'cl_khr_fp64' - ignoring}}
+
 typedef __attribute__((ext_vector_type(4))) float float4;
 typedef __attribute__((ext_vector_type(4))) double double4;
 typedef __attribute__((ext_vector_type(4))) int int4;
Index: test/SemaOpenCL/invalid-kernel-parameters.cl
===================================================================
--- test/SemaOpenCL/invalid-kernel-parameters.cl
+++ test/SemaOpenCL/invalid-kernel-parameters.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple spir-unknown-unknown
 
 #pragma OPENCL EXTENSION cl_khr_fp16 : enable
 
Index: test/SemaOpenCL/half.cl
===================================================================
--- test/SemaOpenCL/half.cl
+++ test/SemaOpenCL/half.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -Wno-unused-value
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -Wno-unused-value -triple spir-unknown-unknown
 
 #pragma OPENCL EXTENSION cl_khr_fp16 : disable
 constant float f = 1.0h; // expected-error{{half precision constant requires cl_khr_fp16}}
Index: test/SemaOpenCL/extensions.cl
===================================================================
--- /dev/null
+++ test/SemaOpenCL/extensions.cl
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.1
+
+// Test with a target not supporting fp64.
+// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64
+
+void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}}
+  double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
+  (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}}
+}
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+#ifdef NOFP64
+// expected-warning@-2{{unknown OpenCL extension 'cl_khr_fp64' - ignoring}}
+#endif
+
+void f2(void) {
+  double d;
+#ifdef NOFP64
+// expected-error@-2{{use of type 'double' requires cl_khr_fp64 extension to be enabled}}
+#endif
+
+  (void) 1.0;
+#ifdef NOFP64
+// expected-warning@-2{{double precision constant requires cl_khr_fp64, casting to single precision}}
+#endif
+}
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : disable
+#ifdef NOFP64
+// expected-warning@-2{{unknown OpenCL extension 'cl_khr_fp64' - ignoring}}
+#endif
+
+void f3(void) {
+  double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
+}
Index: test/SemaOpenCL/extension-fp64.cl
===================================================================
--- test/SemaOpenCL/extension-fp64.cl
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
-
-void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}}
-  double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
-  (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}}
-}
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-void f2(void) {
-  double d;
-  (void) 1.0;
-}
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : disable
-
-void f3(void) {
-  double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
-}
Index: test/SemaOpenCL/extension-fp64-cl1.1.cl
===================================================================
--- test/SemaOpenCL/extension-fp64-cl1.1.cl
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.1
-
-void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}}
-  double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
-  (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}}
-}
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
-
-void f2(void) {
-  double d;
-  (void) 1.0;
-}
-
-#pragma OPENCL EXTENSION cl_khr_fp64 : disable
-
-void f3(void) {
-  double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
-}
Index: test/Parser/opencl-storage-class.cl
===================================================================
--- test/Parser/opencl-storage-class.cl
+++ test/Parser/opencl-storage-class.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -triple spir-unknown-unknown
 
 void test_storage_class_specs()
 {
Index: test/Parser/opencl-pragma.cl
===================================================================
--- test/Parser/opencl-pragma.cl
+++ test/Parser/opencl-pragma.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -pedantic -Wno-empty-translation-unit -fsyntax-only
+// RUN: %clang_cc1 %s -verify -pedantic -Wno-empty-translation-unit -fsyntax-only -triple spir-unknown-unknown
 
 #pragma OPENCL EXTENSION cl_khr_fp16 : enable
 
Index: test/Parser/opencl-atomics-cl20.cl
===================================================================
--- test/Parser/opencl-atomics-cl20.cl
+++ test/Parser/opencl-atomics-cl20.cl
@@ -1,11 +1,14 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
-// RUN: %clang_cc1 %s -verify  -fsyntax-only -cl-std=CL2.0 -DCL20
-// RUN: %clang_cc1 %s -verify  -fsyntax-only -cl-std=CL2.0 -DCL20 -DEXT
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20 -DEXT
 
 #ifdef EXT
 #pragma OPENCL EXTENSION cl_khr_int64_base_atomics:enable
 #pragma OPENCL EXTENSION cl_khr_int64_extended_atomics:enable
 #pragma OPENCL EXTENSION cl_khr_fp64:enable
+#if __OPENCL_C_VERSION__ >= CL_VERSION_1_2
+// expected-warning@-2{{unknown OpenCL extension 'cl_khr_fp64' - ignoring}}
+#endif
 #endif
 
 void atomic_types_test() {
@@ -44,15 +47,14 @@
 // expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics extension to be enabled}}
 // expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics extension to be enabled}}
 // expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics extension to be enabled}}
-// expected-error@-29 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_fp64 extension to be enabled}}
-// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
-// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
-// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
-// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
-// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
-// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
-// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
-// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-27 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-28 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-29 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-30 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
 #endif
 
 #ifdef CL20
Index: test/Parser/opencl-astype.cl
===================================================================
--- test/Parser/opencl-astype.cl
+++ test/Parser/opencl-astype.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple spir-unknown-unknown
 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
 
 void test_astype() {
Index: test/PCH/opencl-extensions.cl
===================================================================
--- test/PCH/opencl-extensions.cl
+++ test/PCH/opencl-extensions.cl
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-pch -o %t %s
-// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s 
+// RUN: %clang_cc1 -emit-pch -o %t %s -triple spir-unknown-unknown
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s  -triple spir-unknown-unknown
 
 #ifndef HEADER
 #define HEADER
Index: test/Misc/languageOptsOpenCL.cl
===================================================================
--- test/Misc/languageOptsOpenCL.cl
+++ test/Misc/languageOptsOpenCL.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -x cl %s -verify
+// RUN: %clang_cc1 -x cl %s -verify -triple spir-unknown-unknown
 // expected-no-diagnostics
 
 // Test the forced language options for OpenCL are set correctly.
Index: test/Lexer/opencl-half-literal.cl
===================================================================
--- test/Lexer/opencl-half-literal.cl
+++ test/Lexer/opencl-half-literal.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple spir-unknown-unknown
 
 #pragma OPENCL EXTENSION cl_khr_fp16 : enable
 
Index: test/CodeGenOpenCL/half.cl
===================================================================
--- test/CodeGenOpenCL/half.cl
+++ test/CodeGenOpenCL/half.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
 
 #pragma OPENCL EXTENSION cl_khr_fp16 : enable
 
Index: test/CodeGenOpenCL/fpmath.cl
===================================================================
--- test/CodeGenOpenCL/fpmath.cl
+++ test/CodeGenOpenCL/fpmath.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
 
 typedef __attribute__(( ext_vector_type(4) )) float float4;
 
Index: test/CodeGenOpenCL/builtins-r600.cl
===================================================================
--- test/CodeGenOpenCL/builtins-r600.cl
+++ test/CodeGenOpenCL/builtins-r600.cl
@@ -1,5 +1,5 @@
 // REQUIRES: amdgpu-registered-target
-// RUN: %clang_cc1 -triple r600-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple r600-unknown-unknown -target-cpu rv670 -S -emit-llvm -o - %s | FileCheck %s
 
 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
 
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -206,8 +206,14 @@
     addImplicitTypedef("size_t", Context.getSizeType());
   }
 
-  // Initialize predefined OpenCL types.
+  // Initialize predefined OpenCL types and supported optional core features.
   if (getLangOpts().OpenCL) {
+#define OPENCLEXT(Ext) \
+     if (Context.getTargetInfo().getSupportedOpenCLOpts().is_##Ext##_supported_core( \
+         getLangOpts().OpenCLVersion)) \
+       getOpenCLOptions().Ext = 1;
+#include "clang/Basic/OpenCLExtensions.def"
+
     addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
     addImplicitTypedef("event_t", Context.OCLEventTy);
     if (getLangOpts().OpenCLVersion >= 200) {
Index: lib/Parse/ParsePragma.cpp
===================================================================
--- lib/Parse/ParsePragma.cpp
+++ lib/Parse/ParsePragma.cpp
@@ -470,14 +470,19 @@
   ConsumeToken(); // The annotation token.
 
   OpenCLOptions &f = Actions.getOpenCLOptions();
+  auto CLVer = getLangOpts().OpenCLVersion;
+  auto &Supp = getTargetInfo().getSupportedOpenCLOpts();
   // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
   // overriding all previously issued extension directives, but only if the
   // behavior is set to disable."
   if (state == 0 && ename->isStr("all")) {
-#define OPENCLEXT(nm)   f.nm = 0;
+#define OPENCLEXT(nm) \
+    if (Supp.is_##nm##_supported_extension(CLVer)) \
+      f.nm = 0;
 #include "clang/Basic/OpenCLExtensions.def"
   }
-#define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
+#define OPENCLEXT(nm) else if (ename->isStr(#nm) \
+   && Supp.is_##nm##_supported_extension(CLVer)) { f.nm = state; }
 #include "clang/Basic/OpenCLExtensions.def"
   else {
     PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
Index: lib/Frontend/InitPreprocessor.cpp
===================================================================
--- lib/Frontend/InitPreprocessor.cpp
+++ lib/Frontend/InitPreprocessor.cpp
@@ -938,6 +938,15 @@
     Builder.defineMacro("__CUDA_ARCH__");
   }
 
+  // OpenCL definitions.
+  if (LangOpts.OpenCL) {
+#define OPENCLEXT(Ext) \
+    if (TI.getSupportedOpenCLOpts().is_##Ext##_supported( \
+        LangOpts.OpenCLVersion)) \
+      Builder.defineMacro(#Ext);
+#include "clang/Basic/OpenCLExtensions.def"
+  }
+
   // Get other target #defines.
   TI.getTargetDefines(LangOpts, Builder);
 }
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -1871,17 +1871,6 @@
       Builder.defineMacro("__HAS_FMAF__");
     if (hasLDEXPF)
       Builder.defineMacro("__HAS_LDEXPF__");
-    if (hasFP64 && Opts.OpenCL)
-      Builder.defineMacro("cl_khr_fp64");
-    if (Opts.OpenCL) {
-      if (GPU >= GK_NORTHERN_ISLANDS) {
-        Builder.defineMacro("cl_khr_byte_addressable_store");
-        Builder.defineMacro("cl_khr_global_int32_base_atomics");
-        Builder.defineMacro("cl_khr_global_int32_extended_atomics");
-        Builder.defineMacro("cl_khr_local_int32_base_atomics");
-        Builder.defineMacro("cl_khr_local_int32_extended_atomics");
-      }
-    }
   }
 
   BuiltinVaListKind getBuiltinVaListKind() const override {
@@ -1969,6 +1958,31 @@
 
     return true;
   }
+
+   void setSupportedOpenCLOpts() {
+     auto &Opts = getSupportedOpenCLOpts();
+     Opts.cl_clang_storage_class_specifiers = 1;
+     Opts.cl_khr_gl_sharing = 1;
+     Opts.cl_khr_gl_event = 1;
+     Opts.cl_khr_d3d10_sharing = 1;
+     Opts.cl_khr_subgroups = 1;
+
+     if (hasFP64)
+       Opts.cl_khr_fp64 = 1;
+     if (GPU >= GK_NORTHERN_ISLANDS) {
+       Opts.cl_khr_byte_addressable_store = 1;
+       Opts.cl_khr_global_int32_base_atomics = 1;
+       Opts.cl_khr_global_int32_extended_atomics = 1;
+       Opts.cl_khr_local_int32_base_atomics = 1;
+       Opts.cl_khr_local_int32_extended_atomics = 1;
+     }
+     if (GPU >= GK_SOUTHERN_ISLANDS)
+       Opts.cl_khr_fp16 = 1;
+       Opts.cl_khr_int64_base_atomics = 1;
+       Opts.cl_khr_int64_extended_atomics = 1;
+       Opts.cl_khr_3d_image_writes = 1;
+       Opts.cl_khr_gl_msaa_sharing = 1;
+  }
 };
 
 const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = {
@@ -2588,6 +2602,10 @@
   bool hasSjLjLowering() const override {
     return true;
   }
+
+  void setSupportedOpenCLOpts() {
+    getSupportedOpenCLOpts().setAll();
+  }
 };
 
 bool X86TargetInfo::setFPMath(StringRef Name) {
@@ -7732,6 +7750,12 @@
   CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
     return CC_SpirFunction;
   }
+
+  void setSupportedOpenCLOpts() {
+    // Assume all OpenCL extensions and optional core features are supported
+    // for SPIR since it is a generic target.
+    getSupportedOpenCLOpts().setAll();
+  }
 };
 
 class SPIR32TargetInfo : public SPIRTargetInfo {
@@ -8330,5 +8354,7 @@
   if (!Target->handleTargetFeatures(Opts->Features, Diags))
     return nullptr;
 
+  Target->setSupportedOpenCLOpts();
+
   return Target.release();
 }
Index: include/clang/Basic/TargetOptions.h
===================================================================
--- include/clang/Basic/TargetOptions.h
+++ include/clang/Basic/TargetOptions.h
@@ -17,6 +17,7 @@
 
 #include <string>
 #include <vector>
+#include "clang/Basic/OpenCLOptions.h"
 
 namespace clang {
 
@@ -50,6 +51,9 @@
   std::vector<std::string> Features;
 
   std::vector<std::string> Reciprocals;
+
+  /// Supported OpenCL extensions and optional core features.
+  OpenCLOptions SupportedOpenCLOptions;
 };
 
 }  // end namespace clang
Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -956,6 +956,19 @@
   /// \brief Whether target allows to overalign ABI-specified prefered alignment
   virtual bool allowsLargerPreferedTypeAlignment() const { return true; }
 
+  /// \brief Set supported OpenCL extensions and optional core features.
+  virtual void setSupportedOpenCLOpts() {}
+
+  /// \brief Get supported OpenCL extensions and optional core features.
+  OpenCLOptions &getSupportedOpenCLOpts() {
+    return getTargetOpts().SupportedOpenCLOptions;
+  }
+
+  /// \brief Get const supported OpenCL extensions and optional core features.
+  const OpenCLOptions &getSupportedOpenCLOpts() const {
+      return getTargetOpts().SupportedOpenCLOptions;
+  }
+
 protected:
   virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
     return PointerWidth;
Index: include/clang/Basic/OpenCLOptions.h
===================================================================
--- /dev/null
+++ include/clang/Basic/OpenCLOptions.h
@@ -0,0 +1,68 @@
+//===--- OpenCLOptions.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::OpenCLOptions class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
+#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// \brief OpenCL supported extensions and optional core features
+class OpenCLOptions {
+public:
+#define OPENCLEXT(nm) unsigned nm : 1;
+#include "clang/Basic/OpenCLExtensions.def"
+
+  OpenCLOptions() {
+#define OPENCLEXT(nm)   nm = 0;
+#include "clang/Basic/OpenCLExtensions.def"
+  }
+
+  // Enable all options.
+  void setAll() {
+#define OPENCLEXT(nm)   nm = 1;
+#include "clang/Basic/OpenCLExtensions.def"
+  }
+
+  // Is supported with OpenCL version \p OCLVer.
+#define OPENCLEXT_INTERNAL(Ext, Avail, ...) \
+  bool is_##Ext##_supported(unsigned OCLVer) const { \
+    return Ext && OCLVer >= Avail; \
+  }
+#include "clang/Basic/OpenCLExtensions.def"
+
+
+  // Is supported OpenCL extension with OpenCL version \p OCLVer.
+  // For supported optional core feature, return false.
+#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \
+  bool is_##Ext##_supported_extension(unsigned CLVer) const { \
+    return is_##Ext##_supported(CLVer) && (Core == ~0U || CLVer < Core); \
+  }
+#include "clang/Basic/OpenCLExtensions.def"
+
+  // Is supported OpenCL core features with OpenCL version \p OCLVer.
+  // For supported extension, return false.
+#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \
+  bool is_##Ext##_supported_core(unsigned CLVer) const { \
+    return is_##Ext##_supported(CLVer) && Core != ~0U && CLVer >= Core; \
+  }
+#include "clang/Basic/OpenCLExtensions.def"
+
+};
+
+}  // end namespace clang
+
+#endif
Index: include/clang/Basic/OpenCLExtensions.def
===================================================================
--- include/clang/Basic/OpenCLExtensions.def
+++ include/clang/Basic/OpenCLExtensions.def
@@ -11,25 +11,59 @@
 //
 //===----------------------------------------------------------------------===//
 
+#ifndef OPENCLEXT_INTERNAL
+#ifndef OPENCLEXT
+#pragma error "macro OPENCLEXT or OPENCLEXT_INTERNAL is required"
+#else
+#define OPENCLEXT_INTERNAL(ext, ...) OPENCLEXT(ext)
+#endif // OPENCLEXT
+#endif // OPENCLEXT_INTERNAL
+
+// OPENCLEXT_INTERNAL(name, avail, core):
+// name - name of the extension or optional core feature.
+// avail - minimum OpenCL version supporting it.
+// core - minimum OpenCL version when the extension becomes optional core
+//        feature or core feature. ~0U indicates not a core feature or an
+//        optional core feature.
+
+// OpenCL 1.0.
+OPENCLEXT_INTERNAL(cl_khr_3d_image_writes, 100, 120)
+OPENCLEXT_INTERNAL(cl_khr_byte_addressable_store, 100, 110)
+OPENCLEXT_INTERNAL(cl_khr_fp16, 100, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_fp64, 100, 120)
+OPENCLEXT_INTERNAL(cl_khr_global_int32_base_atomics, 100, 110)
+OPENCLEXT_INTERNAL(cl_khr_global_int32_extended_atomics, 100, 110)
+OPENCLEXT_INTERNAL(cl_khr_gl_sharing, 100, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_icd, 100, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_local_int32_base_atomics, 100, 110)
+OPENCLEXT_INTERNAL(cl_khr_local_int32_extended_atomics, 100, 110)
+
 // OpenCL 1.1.
-OPENCLEXT(cl_khr_fp64)
-OPENCLEXT(cl_khr_int64_base_atomics)
-OPENCLEXT(cl_khr_int64_extended_atomics)
-OPENCLEXT(cl_khr_fp16)
-OPENCLEXT(cl_khr_gl_sharing)
-OPENCLEXT(cl_khr_gl_event)
-OPENCLEXT(cl_khr_d3d10_sharing)
-OPENCLEXT(cl_khr_global_int32_base_atomics)
-OPENCLEXT(cl_khr_global_int32_extended_atomics)
-OPENCLEXT(cl_khr_local_int32_base_atomics)
-OPENCLEXT(cl_khr_local_int32_extended_atomics)
-OPENCLEXT(cl_khr_byte_addressable_store)
-OPENCLEXT(cl_khr_3d_image_writes)
-
-// OpenCL 2.0
-OPENCLEXT(cl_khr_gl_msaa_sharing)
+OPENCLEXT_INTERNAL(cl_khr_d3d10_sharing, 110, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_gl_event, 110, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_int64_base_atomics, 110, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_int64_extended_atomics, 110, ~0U)
+
+// OpenCL 1.2.
+OPENCLEXT_INTERNAL(cl_khr_d3d11_sharing, 120, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_dx9_media_sharing, 120, ~0U)
+
+// OpenCL 2.0.
+OPENCLEXT_INTERNAL(cl_khr_egl_event, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_egl_image, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_gl_depth_images, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_gl_msaa_sharing, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_initialize_memory, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_spir, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_srgb_image_writes, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_subgroups, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_terminate_context, 200, ~0U)
 
 // Clang Extensions.
-OPENCLEXT(cl_clang_storage_class_specifiers)
+OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U)
+
+#undef OPENCLEXT_INTERNAL
 
+#ifdef OPENCLEXT
 #undef OPENCLEXT
+#endif
Index: include/clang/Basic/LangOptions.h
===================================================================
--- include/clang/Basic/LangOptions.h
+++ include/clang/Basic/LangOptions.h
@@ -160,18 +160,6 @@
     fp_contract(LangOpts.DefaultFPContract) {}
 };
 
-/// \brief OpenCL volatile options
-class OpenCLOptions {
-public:
-#define OPENCLEXT(nm)  unsigned nm : 1;
-#include "clang/Basic/OpenCLExtensions.def"
-
-  OpenCLOptions() {
-#define OPENCLEXT(nm)   nm = 0;
-#include "clang/Basic/OpenCLExtensions.def"
-  }
-};
-
 /// \brief Describes the kind of translation unit being processed.
 enum TranslationUnitKind {
   /// \brief The translation unit is a complete translation unit.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to