Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -313,8 +313,7 @@ // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide. addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy)); - auto AtomicSizeT = Context.getAtomicType(Context.getSizeType()); - addImplicitTypedef("atomic_size_t", AtomicSizeT); + // OpenCL v2.0 s6.13.11.6: // - The atomic_long and atomic_ulong types are supported if the @@ -327,6 +326,23 @@ // atomic_intptr_t, atomic_uintptr_t, atomic_size_t and // atomic_ptrdiff_t are supported if the cl_khr_int64_base_atomics and // cl_khr_int64_extended_atomics extensions are supported. + + auto AddPointerSizeDependentTypes = [&]() { + auto AtomicSizeT = Context.getAtomicType(Context.getSizeType()); + auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); + auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); + auto AtomicPtrDiffT = + Context.getAtomicType(Context.getPointerDiffType()); + addImplicitTypedef("atomic_size_t", AtomicSizeT); + addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); + addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); + addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); + }; + + if (Context.getTypeSize(Context.getSizeType()) == 32) { + AddPointerSizeDependentTypes(); + } + std::vector Atomic64BitTypes; if (getOpenCLOptions().isSupported("cl_khr_int64_base_atomics", getLangOpts()) && @@ -335,35 +351,18 @@ if (getOpenCLOptions().isSupported("cl_khr_fp64", getLangOpts())) { auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); addImplicitTypedef("atomic_double", AtomicDoubleT); - setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64"); Atomic64BitTypes.push_back(AtomicDoubleT); } auto AtomicLongT = Context.getAtomicType(Context.LongTy); auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); - auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); - auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); - auto AtomicPtrDiffT = - Context.getAtomicType(Context.getPointerDiffType()); - addImplicitTypedef("atomic_long", AtomicLongT); addImplicitTypedef("atomic_ulong", AtomicULongT); - addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); - addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); - addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); - Atomic64BitTypes.push_back(AtomicLongT); - Atomic64BitTypes.push_back(AtomicULongT); - if (Context.getTypeSize(AtomicSizeT) == 64) { - Atomic64BitTypes.push_back(AtomicSizeT); - Atomic64BitTypes.push_back(AtomicIntPtrT); - Atomic64BitTypes.push_back(AtomicUIntPtrT); - Atomic64BitTypes.push_back(AtomicPtrDiffT); + + if (Context.getTypeSize(Context.getSizeType()) == 64) { + AddPointerSizeDependentTypes(); } } - - for (auto &I : Atomic64BitTypes) - setOpenCLExtensionForType(I, - "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"); } setOpenCLExtensionForType(Context.DoubleTy, "cl_khr_fp64"); Index: clang/test/Parser/opencl-atomics-cl20.cl =================================================================== --- clang/test/Parser/opencl-atomics-cl20.cl +++ clang/test/Parser/opencl-atomics-cl20.cl @@ -1,66 +1,78 @@ // 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 spir64-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 -Wpedantic-core-features +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -cl-ext=-cl_khr_int64_base_atomics +// RUN: %clang_cc1 %s -triple spir64-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 +// RUN: %clang_cc1 %s -triple spir64-unknown-unknown -verify -fsyntax-only -cl-std=CLC++ +// RUN: %clang_cc1 %s -triple spir64-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -cl-ext=-cl_khr_int64_base_atomics -#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{{OpenCL extension 'cl_khr_fp64' is core feature or supported optional core feature - ignoring}} -#endif +#if defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= CL_VERSION_1_2 +#define LANG_VER_OK #endif void atomic_types_test() { // OpenCL v2.0 s6.13.11.6 defines supported atomic types. + +// Non-optional types atomic_int i; atomic_uint ui; + atomic_float f; + atomic_flag fl; +#if !defined(LANG_VER_OK) +// expected-error@-5 {{use of undeclared identifier 'atomic_int'}} +// expected-error@-5 {{use of undeclared identifier 'atomic_uint'}} +// expected-error@-5 {{use of undeclared identifier 'atomic_float'}} +// expected-error@-5 {{use of undeclared identifier 'atomic_flag'}} +#endif + +// Optional types atomic_long l; atomic_ulong ul; - atomic_float f; atomic_double d; - atomic_flag fl; + atomic_size_t s; atomic_intptr_t ip; atomic_uintptr_t uip; - atomic_size_t s; atomic_ptrdiff_t pd; +// Optional type identifiers are not added in earlier version or if at least +// one of the extensions is not supported. Here we check with +// `cl_khr_int64_base_atomics` only. +#if !defined(LANG_VER_OK) || !defined(cl_khr_int64_base_atomics) +// expected-error@-8 {{use of undeclared identifier 'atomic_long'}} +// expected-error@-8 {{use of undeclared identifier 'atomic_ulong'}} +// expected-error@-8 {{use of undeclared identifier 'atomic_double'}} +#if defined(LANG_VER_OK) +// expected-error@-12 {{expected ';' after expression}} +// expected-error@-13 {{use of undeclared identifier 'l'}} +// expected-error@-13 {{expected ';' after expression}} +// expected-error@-14 {{use of undeclared identifier 'ul'}} +#endif +#if !defined(LANG_VER_OK) || defined(__SPIR64__) +// expected-error@-15 {{use of undeclared identifier 'atomic_size_t'}} +// expected-error@-13 {{use of undeclared identifier 'atomic_ptrdiff_t'}} +#if !defined(LANG_VER_OK) +// expected-error@-17 {{use of undeclared identifier 'atomic_intptr_t'}} +// expected-error@-17 {{use of undeclared identifier 'atomic_uintptr_t'}} +#else +// expected-error@-21 {{expected ';' after expression}} +// expected-error@-22 {{use of undeclared identifier 's'}} +// expected-error@-22 {{unknown type name 'atomic_intptr_t'; did you mean 'atomic_int'?}} +// expected-note@* {{'atomic_int' declared here}} +// expected-error@-23 {{unknown type name 'atomic_uintptr_t'; did you mean 'atomic_uint'?}} +// expected-note@* {{'atomic_uint' declared here}} +#endif +#endif +#endif + // OpenCL v2.0 s6.13.11.8, _Atomic type specifier and _Atomic type qualifier // are not supported by OpenCL. - _Atomic int i; // expected-error {{use of undeclared identifier '_Atomic'}} -} -#ifndef CL20 -// expected-error@-16 {{use of undeclared identifier 'atomic_int'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_uint'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_long'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_ulong'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_float'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_double'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_flag'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_intptr_t'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_uintptr_t'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_size_t'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_ptrdiff_t'}} -#elif !EXT -// expected-error@-26 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_base_atomics support}} -// expected-error@-27 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_extended_atomics support}} -// expected-error@-27 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_base_atomics support}} -// expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics support}} -// expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics support}} -// expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics support}} -#if __LP64__ -// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} -// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} -// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} -// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} -// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} -// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} -// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} -// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} -#endif + _Atomic int i; +#ifdef __OPENCL_C_VERSION__ +// expected-error@-2 {{use of undeclared identifier '_Atomic'}} +#else + // expected-error@-4 {{unknown type name '_Atomic'}} #endif +} -#ifdef CL20 +#if defined(LANG_VER_OK) +int atomic_uint; //expected-error{{redefinition of 'atomic_uint' as different kind of symbol}} void foo(atomic_int * ptr) {} void atomic_ops_test() { atomic_int i; @@ -71,4 +83,6 @@ i += 1; // expected-error {{invalid operands to binary expression ('__private atomic_int' (aka '__private _Atomic(int)') and 'int')}} i = i + i; // expected-error {{invalid operands to binary expression ('__private atomic_int' (aka '__private _Atomic(int)') and '__private atomic_int')}} } +#else +__constant int atomic_uint = 1; #endif