Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -7967,7 +7967,7 @@ // Blocks def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks" - " or %select{pick a deployment target that supports them|for OpenCL 2.0 or above}0">; + " or %select{pick a deployment target that supports them|for OpenCL 2.0}0">; def err_block_returning_array_function : Error< "block cannot return %select{array|function}0 type %1">; Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -188,7 +188,8 @@ LANGOPT(ShortEnums , 1, 0, "short enum types") LANGOPT(OpenCL , 1, 0, "OpenCL") -LANGOPT(OpenCLVersion , 32, 0, "OpenCL version") +LANGOPT(OpenCLVersion , 32, 0, "OpenCL C version") +LANGOPT(OpenCLCPlusPlusVersion , 32, 0, "OpenCL C++ version") LANGOPT(NativeHalfType , 1, 0, "Native half type support") LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns") LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns") Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -514,7 +514,7 @@ def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, Group, Flags<[CC1Option]>, HelpText<"OpenCL only. Allow use of less precise no signed zeros computations in the generated binary.">; def cl_std_EQ : Joined<["-"], "cl-std=">, Group, Flags<[CC1Option]>, - HelpText<"OpenCL language standard to compile for.">, Values<"cl,CL,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0">; + HelpText<"OpenCL language standard to compile for.">, Values<"cl,CL,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0,c++">; def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, Group, Flags<[CC1Option]>, HelpText<"OpenCL only. Allow denormals to be flushed to zero.">; def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-rounded-divide-sqrt">, Group, Flags<[CC1Option]>, Index: include/clang/Frontend/LangStandards.def =================================================================== --- include/clang/Frontend/LangStandards.def +++ include/clang/Frontend/LangStandards.def @@ -155,6 +155,9 @@ LANGSTANDARD(opencl20, "cl2.0", OpenCL, "OpenCL 2.0", LineComment | C99 | Digraphs | HexFloat | OpenCL) +LANGSTANDARD(openclcpp, "c++", + OpenCL, "OpenCL C++ 1.0", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs | OpenCL) LANGSTANDARD_ALIAS_DEPR(opencl10, "CL") LANGSTANDARD_ALIAS_DEPR(opencl11, "CL1.1") Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1872,6 +1872,8 @@ Opts.OpenCLVersion = 120; else if (LangStd == LangStandard::lang_opencl20) Opts.OpenCLVersion = 200; + else if (LangStd == LangStandard::lang_openclcpp) + Opts.OpenCLCPlusPlusVersion = 100; // OpenCL has some additional defaults. if (Opts.OpenCL) { @@ -2063,6 +2065,7 @@ .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11) .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12) .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20) + .Case("c++", LangStandard::lang_openclcpp) .Default(LangStandard::lang_unspecified); if (OpenCLLangStd == LangStandard::lang_unspecified) { @@ -2275,7 +2278,7 @@ Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti); Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data); Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL - && Opts.OpenCLVersion >= 200); + && Opts.OpenCLVersion == 200); Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); Opts.CoroutinesTS = Args.hasArg(OPT_fcoroutines_ts); Index: lib/Frontend/InitPreprocessor.cpp =================================================================== --- lib/Frontend/InitPreprocessor.cpp +++ lib/Frontend/InitPreprocessor.cpp @@ -426,39 +426,47 @@ // 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.CPlusPlus) { + if (LangOpts.OpenCLCPlusPlusVersion == 100) + Builder.defineMacro("__OPENCL_CPP_VERSION__", "100"); + else + llvm_unreachable("Unsupported OpenCL C++ version"); + Builder.defineMacro("__CL_CPP_VERSION_1_0__", "100"); + } else { + // 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 (TI.isLittleEndian()) - Builder.defineMacro("__ENDIAN_LITTLE__"); + if (TI.isLittleEndian()) + Builder.defineMacro("__ENDIAN_LITTLE__"); - if (LangOpts.FastRelaxedMath) - Builder.defineMacro("__FAST_RELAXED_MATH__"); + if (LangOpts.FastRelaxedMath) + Builder.defineMacro("__FAST_RELAXED_MATH__"); + } } // Not "standard" per se, but available even with the -undef flag. if (LangOpts.AsmPreprocessor) Index: test/Driver/autocomplete.c =================================================================== --- test/Driver/autocomplete.c +++ test/Driver/autocomplete.c @@ -33,7 +33,8 @@ // RUN: %clang --autocomplete=-cl-std=,CL2 | FileCheck %s -check-prefix=CLSTD // CLSTD: CL2.0 // RUN: %clang --autocomplete=-cl-std= | FileCheck %s -check-prefix=CLSTDALL -// CLSTDALL: cl +// CLSTDALL: c++ +// CLSTDALL-NEXT: cl // CLSTDALL-NEXT: CL // CLSTDALL-NEXT: cl1.1 // CLSTDALL-NEXT: CL1.1 Index: test/Driver/opencl.cl =================================================================== --- test/Driver/opencl.cl +++ test/Driver/opencl.cl @@ -2,6 +2,7 @@ // RUN: %clang -S -### -cl-std=CL1.1 %s 2>&1 | FileCheck --check-prefix=CHECK-CL11 %s // RUN: %clang -S -### -cl-std=CL1.2 %s 2>&1 | FileCheck --check-prefix=CHECK-CL12 %s // RUN: %clang -S -### -cl-std=CL2.0 %s 2>&1 | FileCheck --check-prefix=CHECK-CL20 %s +// RUN: %clang -S -### -cl-std=c++ %s 2>&1 | FileCheck --check-prefix=CHECK-CLCPP %s // RUN: %clang -S -### -cl-opt-disable %s 2>&1 | FileCheck --check-prefix=CHECK-OPT-DISABLE %s // RUN: %clang -S -### -cl-strict-aliasing %s 2>&1 | FileCheck --check-prefix=CHECK-STRICT-ALIASING %s // RUN: %clang -S -### -cl-single-precision-constant %s 2>&1 | FileCheck --check-prefix=CHECK-SINGLE-PRECISION-CONST %s @@ -21,6 +22,7 @@ // CHECK-CL11: "-cc1" {{.*}} "-cl-std=CL1.1" // CHECK-CL12: "-cc1" {{.*}} "-cl-std=CL1.2" // CHECK-CL20: "-cc1" {{.*}} "-cl-std=CL2.0" +// CHECK-CLCPP: "-cc1" {{.*}} "-cl-std=c++" // CHECK-OPT-DISABLE: "-cc1" {{.*}} "-cl-opt-disable" // CHECK-STRICT-ALIASING: "-cc1" {{.*}} "-cl-strict-aliasing" // CHECK-SINGLE-PRECISION-CONST: "-cc1" {{.*}} "-cl-single-precision-constant" Index: test/Driver/unknown-std.cl =================================================================== --- test/Driver/unknown-std.cl +++ test/Driver/unknown-std.cl @@ -10,6 +10,7 @@ // CHECK-NEXT: note: use 'cl1.1' for 'OpenCL 1.1' standard // CHECK-NEXT: note: use 'cl1.2' for 'OpenCL 1.2' standard // CHECK-NEXT: note: use 'cl2.0' for 'OpenCL 2.0' standard +// CHECK-NEXT: note: use 'c++' for 'OpenCL C++ 1.0' standard // Make sure that no other output is present. // CHECK-NOT: {{^.+$}} Index: test/Frontend/opencl.cl =================================================================== --- test/Frontend/opencl.cl +++ test/Frontend/opencl.cl @@ -1,24 +1,33 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only -// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL1.1 -// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL1.2 -// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL2.0 -// RUN: %clang_cc1 %s -verify -fsyntax-only -fblocks -DBLOCKS -// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL1.1 -fblocks -DBLOCKS -// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL1.2 -fblocks -DBLOCKS -// RUN: %clang_cc1 %s -triple amdgcn--amdhsa -x c -std=c99 -verify -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only -DSYNTAX +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL1.1 -DSYNTAX +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL1.2 -DSYNTAX +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL2.0 -DSYNTAX +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=c++ -DSYNTAX +// RUN: %clang_cc1 %s -verify -fsyntax-only -fblocks -DBLOCKS -DSYNTAX +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL1.1 -fblocks -DBLOCKS -DSYNTAX +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL1.2 -fblocks -DBLOCKS -DSYNTAX +// RUN: %clang_cc1 %s -triple amdgcn--amdhsa -x c -std=c99 -verify -fsyntax-only -DSYNTAX // RUN: %clang_cc1 -cl-std=CL1.1 -cl-strict-aliasing -fblocks %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-OPENCL-VERSION11 %s // RUN: %clang_cc1 -cl-std=CL1.2 -cl-strict-aliasing -fblocks %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-OPENCL-VERSION12 %s // RUN: %clang_cc1 -cl-std=CL2.0 -cl-strict-aliasing %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-OPENCL-VERSION20 %s +#ifdef SYNTAX +class test{ +int member; +}; +#ifndef __OPENCL_CPP_VERSION__ +//expected-error@-4{{unknown type name 'class'}} +//expected-error@-5{{expected ';' after top level declarator}} +#endif +#endif + void f(void (^g)(void)) { -#ifdef __OPENCL_C_VERSION__ -#if __OPENCL_C_VERSION__ < CL_VERSION_2_0 && !defined(BLOCKS) - // expected-error@-3{{blocks support disabled - compile with -fblocks or for OpenCL 2.0 or above}} -#else - // expected-no-diagnostics +#if defined(__OPENCL_C_VERSION__) || defined(__OPENCL_CPP_VERSION__) +#if !defined(BLOCKS) && (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ != CL_VERSION_2_0) + // expected-error@-3{{blocks support disabled - compile with -fblocks or for OpenCL 2.0}} #endif #else - // expected-error@-8{{blocks support disabled - compile with -fblocks or pick a deployment target that supports them}} + // expected-error@-6{{blocks support disabled - compile with -fblocks or pick a deployment target that supports them}} #endif } Index: test/Frontend/stdlang.c =================================================================== --- test/Frontend/stdlang.c +++ test/Frontend/stdlang.c @@ -4,6 +4,7 @@ // 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: %clang_cc1 -x cl -cl-std=c++ -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 Index: test/Preprocessor/predefined-macros.c =================================================================== --- test/Preprocessor/predefined-macros.c +++ test/Preprocessor/predefined-macros.c @@ -159,6 +159,8 @@ // 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 +// RUN: %clang_cc1 %s -E -dM -o - -x cl -cl-std=c++ \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-CLCPP10 // CHECK-CL10: #define CL_VERSION_1_0 100 // CHECK-CL10: #define CL_VERSION_1_1 110 // CHECK-CL10: #define CL_VERSION_1_2 120 @@ -184,6 +186,10 @@ // CHECK-CL20: #define __OPENCL_C_VERSION__ 200 // CHECK-CL20-NOT: #define __FAST_RELAXED_MATH__ 1 // CHECK-FRM: #define __FAST_RELAXED_MATH__ 1 +// CHECK-CLCPP10: #define __CL_CPP_VERSION_1_0__ 100 +// CHECK-CLCPP10: #define __OPENCL_CPP_VERSION__ 100 +// CHECK-CLCPP10-NOT: #define __FAST_RELAXED_MATH__ 1 +// CHECK-CLCPP10-NOT: #define __ENDIAN_LITTLE__ 1 // RUN: %clang_cc1 %s -E -dM -o - -x cl \ // RUN: | FileCheck %s --check-prefix=MSCOPE