Skip to content

Commit 0e874fc

Browse files
author
Anastasia Stulova
committed
[OpenCL] Add clang extension for variadic functions.
With the internal clang extension '__cl_clang_variadic_functions' variadic functions are accepted by the frontend. This is not a fully supported vendor/Khronos extension as it can only be used on targets with variadic prototype support or in metaprogramming to represent functions with generic prototype without calling such functions in the kernel code. Tags: #clang Differential Revision: https://reviews.llvm.org/D94027
1 parent 4fde2b6 commit 0e874fc

File tree

10 files changed

+66
-4
lines changed

10 files changed

+66
-4
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,31 @@ correctly in any circumstances. It can be used if:
17731773
void (*fp)(); // error - pointers to function are not allowed
17741774
}
17751775
1776+
``__cl_clang_variadic_functions``
1777+
---------------------------------
1778+
1779+
With this extension it is possible to enable variadic arguments in functions
1780+
using regular OpenCL extension pragma mechanism detailed in `the OpenCL
1781+
Extension Specification, section 1.2
1782+
<https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#extensions-overview>`_.
1783+
1784+
This is not conformant behavior and it can only be used portably when the
1785+
functions with variadic prototypes do not get generated in binary e.g. the
1786+
variadic prototype is used to spesify a function type with any number of
1787+
arguments in metaprogramming algorithms in C++ for OpenCL.
1788+
1789+
This extensions can also be used when the kernel code is intended for targets
1790+
supporting the variadic arguments e.g. majority of CPU targets.
1791+
1792+
**Example of Use**:
1793+
1794+
.. code-block:: c++
1795+
1796+
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
1797+
void foo(int a, ...); // compiled - no diagnostic generated
1798+
1799+
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : disable
1800+
void bar(int a, ...); // error - variadic prototype is not allowed
17761801
17771802
Builtin Functions
17781803
=================

clang/include/clang/Basic/OpenCLExtensions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ OPENCLEXT_INTERNAL(cl_khr_subgroups, 200, ~0U)
7070
// Clang Extensions.
7171
OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U)
7272
OPENCLEXT_INTERNAL(__cl_clang_function_pointers, 100, ~0U)
73+
OPENCLEXT_INTERNAL(__cl_clang_variadic_functions, 100, ~0U)
7374

7475
// AMD OpenCL extensions
7576
OPENCLEXT_INTERNAL(cl_amd_media_ops, 100, ~0U)

clang/lib/Basic/Targets/AMDGPU.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
286286
auto &Opts = getSupportedOpenCLOpts();
287287
Opts.support("cl_clang_storage_class_specifiers");
288288
Opts.support("__cl_clang_function_pointers");
289+
Opts.support("__cl_clang_variadic_functions");
289290

290291
bool IsAMDGCN = isAMDGCN(getTriple());
291292

clang/lib/Basic/Targets/NVPTX.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
129129
auto &Opts = getSupportedOpenCLOpts();
130130
Opts.support("cl_clang_storage_class_specifiers");
131131
Opts.support("__cl_clang_function_pointers");
132+
Opts.support("__cl_clang_variadic_functions");
132133

133134
Opts.support("cl_khr_fp64");
134135
Opts.support("cl_khr_byte_addressable_store");

clang/lib/Sema/SemaType.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5019,6 +5019,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
50195019
// (s6.9.e and s6.12.5 OpenCL v2.0) except for printf.
50205020
// We also allow here any toolchain reserved identifiers.
50215021
if (FTI.isVariadic &&
5022+
!S.getOpenCLOptions().isEnabled("__cl_clang_variadic_functions") &&
50225023
!(D.getIdentifier() &&
50235024
((D.getIdentifier()->getName() == "printf" &&
50245025
(LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) ||

clang/test/Misc/amdgcn.languageOptsOpenCL.cl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
#endif
2020
#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
2121

22+
#ifndef __cl_clang_variadic_functions
23+
#error "Missing __cl_clang_variadic_functions define"
24+
#endif
25+
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
26+
2227
#ifndef cl_khr_fp16
2328
#error "Missing cl_khr_fp16 define"
2429
#endif

clang/test/Misc/nvptx.languageOptsOpenCL.cl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
#endif
2828
#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
2929

30+
#ifndef __cl_clang_variadic_functions
31+
#error "Missing __cl_clang_variadic_functions define"
32+
#endif
33+
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
34+
3035
#ifdef cl_khr_fp16
3136
#error "Incorrect cl_khr_fp16 define"
3237
#endif

clang/test/Misc/r600.languageOptsOpenCL.cl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535
#endif
3636
#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
3737

38+
#ifndef __cl_clang_variadic_functions
39+
#error "Missing __cl_clang_variadic_functions define"
40+
#endif
41+
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
42+
3843
#ifdef cl_khr_fp16
3944
#error "Incorrect cl_khr_fp16 define"
4045
#endif

clang/test/SemaOpenCL/extension-version.cl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
#endif
2525
#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
2626

27+
#ifndef __cl_clang_variadic_functions
28+
#error "Missing __cl_clang_variadic_functions define"
29+
#endif
30+
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
31+
2732
#ifndef cl_khr_fp16
2833
#error "Missing cl_khr_fp16 define"
2934
#endif

clang/test/SemaOpenCL/func.cl

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,31 @@
11
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -triple spir-unknown-unknown
22
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -triple spir-unknown-unknown -DFUNCPTREXT
3+
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -triple spir-unknown-unknown -DVARARG
34

45
#ifdef FUNCPTREXT
56
#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
67
#endif
8+
#ifdef VARARGEXT
9+
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
10+
#endif
711

812
// Variadic functions
9-
void vararg_f(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}}
13+
void vararg_f(int, ...);
14+
#ifndef VARARGEXT
15+
// expected-error@-2 {{invalid prototype, variadic arguments are not allowed in OpenCL}}
16+
#endif
1017
void __vararg_f(int, ...);
11-
typedef void (*vararg_fptr_t)(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}}
18+
typedef void (*vararg_fptr_t)(int, ...);
19+
#ifndef VARARGEXT
20+
// expected-error@-2 {{invalid prototype, variadic arguments are not allowed in OpenCL}}
21+
#endif
1222
#ifndef FUNCPTREXT
13-
// expected-error@-2 {{pointers to functions are not allowed}}
23+
// expected-error@-5 {{pointers to functions are not allowed}}
24+
#endif
25+
int printf(__constant const char *st, ...);
26+
#ifndef VARARGEXT
27+
// expected-error@-2 {{invalid prototype, variadic arguments are not allowed in OpenCL}}
1428
#endif
15-
int printf(__constant const char *st, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}}
1629

1730
// Struct type with function pointer field
1831
typedef struct s

0 commit comments

Comments
 (0)