Anastasia created this revision. Anastasia added a reviewer: mantognini. Herald added subscribers: ebevhan, kerbowa, yaxunl, nhaehnle, jvesely, jholewinski. Anastasia requested review of this revision.
This feature is primarily important in C++ mode because it opens up more opportunities to describe metaprogramming algorithms with function types. This is clang and not a vendor extension and therefore it is only intended for internal or experimental use. The full feature will require changes in vendor toolchains that can be provided in the future via either vendor extensions or Khronos extensions. This patch is implemented on top of related extension: https://reviews.llvm.org/D94021 https://reviews.llvm.org/D94027 Files: clang/docs/LanguageExtensions.rst clang/include/clang/Basic/OpenCLExtensions.def clang/lib/Basic/Targets/AMDGPU.h clang/lib/Basic/Targets/NVPTX.h clang/lib/Sema/SemaType.cpp clang/test/Misc/amdgcn.languageOptsOpenCL.cl clang/test/Misc/nvptx.languageOptsOpenCL.cl clang/test/Misc/r600.languageOptsOpenCL.cl clang/test/SemaOpenCL/func.cl
Index: clang/test/SemaOpenCL/func.cl =================================================================== --- clang/test/SemaOpenCL/func.cl +++ clang/test/SemaOpenCL/func.cl @@ -1,18 +1,31 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -triple spir-unknown-unknown // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -triple spir-unknown-unknown -DFUNCPTREXT +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -triple spir-unknown-unknown -DVARARG #ifdef FUNCPTREXT #pragma OPENCL EXTENSION __cl_clang_function_pointers : enable #endif +#ifdef VARARGEXT +#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable +#endif // Variadic functions -void vararg_f(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} +void vararg_f(int, ...); +#ifndef VARARGEXT +// expected-error@-2 {{invalid prototype, variadic arguments are not allowed in OpenCL}} +#endif void __vararg_f(int, ...); -typedef void (*vararg_fptr_t)(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} +typedef void (*vararg_fptr_t)(int, ...); +#ifndef VARARGEXT +// expected-error@-2 {{invalid prototype, variadic arguments are not allowed in OpenCL}} +#endif #ifndef FUNCPTREXT -// expected-error@-2 {{pointers to functions are not allowed}} +// expected-error@-5 {{pointers to functions are not allowed}} +#endif +int printf(__constant const char *st, ...); +#ifndef VARARGEXT +// expected-error@-2 {{invalid prototype, variadic arguments are not allowed in OpenCL}} #endif -int printf(__constant const char *st, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} // Struct type with function pointer field typedef struct s Index: clang/test/Misc/r600.languageOptsOpenCL.cl =================================================================== --- clang/test/Misc/r600.languageOptsOpenCL.cl +++ clang/test/Misc/r600.languageOptsOpenCL.cl @@ -35,6 +35,11 @@ #endif #pragma OPENCL EXTENSION __cl_clang_function_pointers : enable +#ifndef __cl_clang_variadic_functions +#error "Missing __cl_clang_variadic_functions define" +#endif +#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable + #ifdef cl_khr_fp16 #error "Incorrect cl_khr_fp16 define" #endif Index: clang/test/Misc/nvptx.languageOptsOpenCL.cl =================================================================== --- clang/test/Misc/nvptx.languageOptsOpenCL.cl +++ clang/test/Misc/nvptx.languageOptsOpenCL.cl @@ -27,6 +27,11 @@ #endif #pragma OPENCL EXTENSION __cl_clang_function_pointers : enable +#ifndef __cl_clang_variadic_functions +#error "Missing __cl_clang_variadic_functions define" +#endif +#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable + #ifdef cl_khr_fp16 #error "Incorrect cl_khr_fp16 define" #endif Index: clang/test/Misc/amdgcn.languageOptsOpenCL.cl =================================================================== --- clang/test/Misc/amdgcn.languageOptsOpenCL.cl +++ clang/test/Misc/amdgcn.languageOptsOpenCL.cl @@ -19,6 +19,11 @@ #endif #pragma OPENCL EXTENSION __cl_clang_function_pointers : enable +#ifndef __cl_clang_variadic_functions +#error "Missing __cl_clang_variadic_functions define" +#endif +#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable + #ifndef cl_khr_fp16 #error "Missing cl_khr_fp16 define" #endif Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -5019,6 +5019,7 @@ // (s6.9.e and s6.12.5 OpenCL v2.0) except for printf. // We also allow here any toolchain reserved identifiers. if (FTI.isVariadic && + !S.getOpenCLOptions().isEnabled("__cl_clang_variadic_functions") && !(D.getIdentifier() && ((D.getIdentifier()->getName() == "printf" && (LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) || Index: clang/lib/Basic/Targets/NVPTX.h =================================================================== --- clang/lib/Basic/Targets/NVPTX.h +++ clang/lib/Basic/Targets/NVPTX.h @@ -129,6 +129,7 @@ auto &Opts = getSupportedOpenCLOpts(); Opts.support("cl_clang_storage_class_specifiers"); Opts.support("__cl_clang_function_pointers"); + Opts.support("__cl_clang_variadic_functions"); Opts.support("cl_khr_fp64"); Opts.support("cl_khr_byte_addressable_store"); Index: clang/lib/Basic/Targets/AMDGPU.h =================================================================== --- clang/lib/Basic/Targets/AMDGPU.h +++ clang/lib/Basic/Targets/AMDGPU.h @@ -286,6 +286,7 @@ auto &Opts = getSupportedOpenCLOpts(); Opts.support("cl_clang_storage_class_specifiers"); Opts.support("__cl_clang_function_pointers"); + Opts.support("__cl_clang_variadic_functions"); bool IsAMDGCN = isAMDGCN(getTriple()); Index: clang/include/clang/Basic/OpenCLExtensions.def =================================================================== --- clang/include/clang/Basic/OpenCLExtensions.def +++ clang/include/clang/Basic/OpenCLExtensions.def @@ -70,6 +70,7 @@ // Clang Extensions. OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U) OPENCLEXT_INTERNAL(__cl_clang_function_pointers, 100, ~0U) +OPENCLEXT_INTERNAL(__cl_clang_variadic_functions, 100, ~0U) // AMD OpenCL extensions OPENCLEXT_INTERNAL(cl_amd_media_ops, 100, ~0U) Index: clang/docs/LanguageExtensions.rst =================================================================== --- clang/docs/LanguageExtensions.rst +++ clang/docs/LanguageExtensions.rst @@ -1770,6 +1770,31 @@ void (*fp)(); // error - pointers to function are not allowed } +``__cl_clang_variadic_functions`` +--------------------------------- + +With this extension it is possible to enable variadic arguments in functions +using regular OpenCL extension pragma mechanism detailed in `the OpenCL +Extension Specification, section 1.2 +<https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#extensions-overview>`_ + +This is not conformant behavior and it can only be used portably when the +functions with variadic prototypes do not get generated in binary e.g. the +variadic prototype is used to spesify a function type with any number of +arguments in metaprogramming algorithms in C++ for OpenCL. + +This extensions can also be used when the kernel code is intended for targets +supporting the variadic arguments e.g. majority of CPU targets. + +**Example of Use**: + +.. code-block:: c++ + + #pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable + void foo(int a, ...); // compiled - no diagnostic generated + + #pragma OPENCL EXTENSION __cl_clang_variadic_functions : disable + void bar(int a, ...); // error - variadic prototype is not allowed Builtin Functions =================
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits