diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1961,6 +1961,30 @@ global OnlySL *d, ); +Remove address space builtin function +------------------------------------- + +``__remove_address_space`` allows to derive types in C++ for OpenCL +that have address space qualifiers removed. This utility only affects +address space qualifiers, therefore, other type qualifiers such as +``const`` or ``volatile`` remain unchanged. + +**Example of Use**: + +.. code-block:: c++ + + template + void foo(T *par){ + T var1; // error - local function variable with global address space + __private T var2; // error - conflicting address space qualifiers + __private __remove_address_space var3; // var3 is __private int + } + + void bar(){ + __global int* ptr; + foo(ptr); + } + Legacy 1.x atomics with generic address space --------------------------------------------- diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h --- a/clang/lib/Headers/opencl-c-base.h +++ b/clang/lib/Headers/opencl-c-base.h @@ -572,6 +572,26 @@ #define as_intptr_t(x) __builtin_astype((x), intptr_t) #define as_uintptr_t(x) __builtin_astype((x), uintptr_t) +// C++ for OpenCL - __remove_address_space +#if defined(__OPENCL_CPP_VERSION__) +template struct __remove_address_space { using type = _Tp; }; +template struct __remove_address_space<__generic _Tp> { + using type = _Tp; +}; +template struct __remove_address_space<__global _Tp> { + using type = _Tp; +}; +template struct __remove_address_space<__private _Tp> { + using type = _Tp; +}; +template struct __remove_address_space<__local _Tp> { + using type = _Tp; +}; +template struct __remove_address_space<__constant _Tp> { + using type = _Tp; +}; +#endif + // OpenCL v1.1 s6.9, v1.2/2.0 s6.10 - Function qualifiers #define __kernel_exec(X, typen) __kernel \ diff --git a/clang/test/CodeGenOpenCLCXX/remove-address-space.clcpp b/clang/test/CodeGenOpenCLCXX/remove-address-space.clcpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenOpenCLCXX/remove-address-space.clcpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 %s -cl-std=clc++ -fdeclare-opencl-builtins -finclude-default-header + +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +void test_is_same() { + static_assert(is_same::value); + static_assert(!is_same::value); + static_assert(!is_same<__private int, int>::value); +} + +void test_remove_address_space() { + static_assert(is_same<__remove_address_space::type, int>::value, + "type without an address space unexpectedly modified by __remove_address_space"); + static_assert(is_same<__remove_address_space<__generic int>::type, int>::value, + "__generic address space not removed by __remove_address_space"); + static_assert(is_same<__remove_address_space<__global char>::type, char>::value, + "__global address space not removed by __remove_address_space"); + static_assert(is_same<__remove_address_space<__private ulong>::type, ulong>::value, + "__private address space not removed by __remove_address_space"); + static_assert(is_same<__remove_address_space<__local short>::type, short>::value, + "__local address space not removed by __remove_address_space"); + static_assert(is_same<__remove_address_space<__constant int3>::type, int3>::value, + "__constant address space not removed by __remove_address_space"); + static_assert(is_same<__remove_address_space::type, const volatile int>::value, + "non-address-space qualifiers inappropriately removed by __remove_address_space"); +}