Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1495,9 +1495,8 @@ << A->getAsString(Args) << "C++/ObjC++"; break; case IK_OpenCL: - if (!Std.isC99()) - Diags.Report(diag::err_drv_argument_not_allowed_with) - << A->getAsString(Args) << "OpenCL"; + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "OpenCL"; break; case IK_CUDA: case IK_PreprocessedCuda: Index: lib/Frontend/InitPreprocessor.cpp =================================================================== --- lib/Frontend/InitPreprocessor.cpp +++ lib/Frontend/InitPreprocessor.cpp @@ -408,6 +408,39 @@ if (LangOpts.ObjC1) Builder.defineMacro("__OBJC__"); + // OpenCL v1.0/1.1 s6.9, v1.2/2.0 s6.10: Preprocessor Directives and Macros. + if (LangOpts.OpenCL) { + // OpenCL v1.0 and v1.1 do not have a predefined macro to indicate the + // language standard with which the program is compiled. __OPENCL_VERSION__ + // is for the OpenCL version supported by the OpenCL device, which is not + // necessarily the language standard with which the program is compiled. + // A shared OpenCL header file requires a macro to indicate the language + // standard. As a workaround, __OPENCL_C_VERSION__ is defined for + // OpenCL v1.0 and v1.1. + switch (LangOpts.OpenCLVersion) { + case 100: + Builder.defineMacro("__OPENCL_C_VERSION__", "100"); + break; + case 110: + Builder.defineMacro("__OPENCL_C_VERSION__", "110"); + break; + case 120: + Builder.defineMacro("__OPENCL_C_VERSION__", "120"); + break; + case 200: + Builder.defineMacro("__OPENCL_C_VERSION__", "200"); + break; + default: + llvm_unreachable("Unsupported OpenCL version"); + } + Builder.defineMacro("CL_VERSION_1_0", "100"); + Builder.defineMacro("CL_VERSION_1_1", "110"); + Builder.defineMacro("CL_VERSION_1_2", "120"); + Builder.defineMacro("CL_VERSION_2_0", "200"); + + if (LangOpts.FastRelaxedMath) + Builder.defineMacro("__FAST_RELAXED_MATH__"); + } // Not "standard" per se, but available even with the -undef flag. if (LangOpts.AsmPreprocessor) Builder.defineMacro("__ASSEMBLER__"); Index: test/Frontend/std.cl =================================================================== --- test/Frontend/std.cl +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 %s -fsyntax-only -cl-std=CL -// RUN: %clang_cc1 %s -fsyntax-only -cl-std=CL1.1 -// RUN: %clang_cc1 %s -fsyntax-only -cl-std=CL1.2 -// RUN: %clang_cc1 %s -fsyntax-only -cl-std=CL2.0 -// RUN: not %clang_cc1 %s -fsyntax-only -cl-std=invalid -DINVALID 2>&1 | FileCheck %s - -#ifdef INVALID -// CHECK: invalid value 'invalid' in '-cl-std=invalid' -#endif Index: test/Frontend/stdlang.c =================================================================== --- test/Frontend/stdlang.c +++ test/Frontend/stdlang.c @@ -1,6 +1,13 @@ // RUN: %clang_cc1 -x cuda -std=c++11 -DCUDA %s -// RUN: %clang_cc1 -x cl -std=c99 -DOPENCL %s -// expected-no-diagnostics +// RUN: %clang_cc1 -x cl -DOPENCL %s +// RUN: %clang_cc1 -x cl -cl-std=CL -DOPENCL %s +// RUN: %clang_cc1 -x cl -cl-std=CL1.1 -DOPENCL %s +// RUN: %clang_cc1 -x cl -cl-std=CL1.2 -DOPENCL %s +// RUN: %clang_cc1 -x cl -cl-std=CL2.0 -DOPENCL %s +// RUN: not %clang_cc1 -x cl -std=c99 -DOPENCL %s 2>&1 | FileCheck --check-prefix=CHECK-C99 %s +// RUN: not %clang_cc1 -x cl -cl-std=invalid -DOPENCL %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID %s +// CHECK-C99: error: invalid argument '-std=c99' not allowed with 'OpenCL' +// CHECK-INVALID: error: invalid value 'invalid' in '-cl-std=invalid' #if defined(CUDA) __attribute__((device)) void f_device(); Index: test/Preprocessor/predefined-macros.c =================================================================== --- test/Preprocessor/predefined-macros.c +++ test/Preprocessor/predefined-macros.c @@ -146,3 +146,36 @@ // CHECK-SYNC_CAS_MIPS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 // CHECK-SYNC_CAS_MIPS32-NOT: __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 // CHECK-SYNC_CAS_MIPS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 + +// RUN: %clang_cc1 %s -E -dM -o - -x cl \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-CL10 +// RUN: %clang_cc1 %s -E -dM -o - -x cl -cl-std=CL1.1 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-CL11 +// RUN: %clang_cc1 %s -E -dM -o - -x cl -cl-std=CL1.2 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-CL12 +// RUN: %clang_cc1 %s -E -dM -o - -x cl -cl-std=CL2.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-CL20 +// RUN: %clang_cc1 %s -E -dM -o - -x cl -cl-fast-relaxed-math \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-FRM +// CHECK-CL10: #define CL_VERSION_1_0 100 +// CHECK-CL10: #define CL_VERSION_1_1 110 +// CHECK-CL10: #define CL_VERSION_1_2 120 +// CHECK-CL10: #define CL_VERSION_2_0 200 +// CHECK-CL10: #define __OPENCL_C_VERSION__ 100 +// CHECK-CL11: #define CL_VERSION_1_0 100 +// CHECK-CL11: #define CL_VERSION_1_1 110 +// CHECK-CL11: #define CL_VERSION_1_2 120 +// CHECK-CL11: #define CL_VERSION_2_0 200 +// CHECK-CL11: #define __OPENCL_C_VERSION__ 110 +// CHECK-CL12: #define CL_VERSION_1_0 100 +// CHECK-CL12: #define CL_VERSION_1_1 110 +// CHECK-CL12: #define CL_VERSION_1_2 120 +// CHECK-CL12: #define CL_VERSION_2_0 200 +// CHECK-CL12: #define __OPENCL_C_VERSION__ 120 +// CHECK-CL20: #define CL_VERSION_1_0 100 +// CHECK-CL20: #define CL_VERSION_1_1 110 +// CHECK-CL20: #define CL_VERSION_1_2 120 +// CHECK-CL20: #define CL_VERSION_2_0 200 +// CHECK-CL20: #define __OPENCL_C_VERSION__ 200 +// CHECK-FRM: #define __FAST_RELAXED_MATH__ 1 +