1 // RUN: %clang_cc1 -verify -triple x86_64-unknown-linux -fopenmp -std=c++11 -o - %s
2 // RUN: %clang_cc1 -verify -triple x86_64-unknown-linux -fopenmp -std=c++11 \
3 // RUN: -DNO_INTEROP_T_DEF -o - %s
4 // RUN: %clang_cc1 -verify -triple x86_64-unknown-linux -fopenmp -std=c++11 -o - %s
5 // RUN: %clang_cc1 -verify -triple x86_64-unknown-linux -fopenmp -Wno-strict-prototypes -DC -x c -o - %s
6 // RUN: %clang_cc1 -verify -triple x86_64-pc-windows-msvc -fms-compatibility \
7 // RUN: -fopenmp -Wno-strict-prototypes -DC -DWIN -x c -o - %s
9 #ifdef NO_INTEROP_T_DEF
10 void foo_v1(float *, void *);
11 // expected-error@+1 {{'omp_interop_t' must be defined when 'append_args' clause is used; include <omp.h>}}
12 #pragma omp declare variant(foo_v1) append_args(interop(target)) \
13 match(construct={dispatch})
16 typedef void *omp_interop_t
;
20 #if _OPENMP >= 202011 // At least OpenMP 5.1
24 void memberfoo_v0(float *A
, float *B
, int *I
);
25 void memberfoo_v1(float *A
, float *B
, int *I
, omp_interop_t IOp
);
27 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (A::*)(float *, float *, int *)' is incompatible with type 'void (A::*)(float *, float *, int *, omp_interop_t)' with appended arguments}}
28 #pragma omp declare variant(memberfoo_v0) match(construct={dispatch}) \
29 append_args(interop(target))
31 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (A::*)(float *, float *, int *, omp_interop_t)' is incompatible with type 'void (A::*)(float *, float *, int *, omp_interop_t, omp_interop_t)' with appended arguments}}
32 #pragma omp declare variant(memberfoo_v1) match(construct={dispatch}) \
33 append_args(interop(target),interop(target))
34 void memberbar(float *A
, float *B
, int *I
) { return; }
36 static void smemberfoo_v0(float *A
, float *B
, int *I
);
37 static void smemberfoo_v1(float *A
, float *B
, int *I
, omp_interop_t IOp
);
39 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (float *, float *, int *)' is incompatible with type 'void (float *, float *, int *)' with appended arguments}}
40 #pragma omp declare variant(smemberfoo_v0) match(construct={dispatch}) \
41 append_args(interop(target))
43 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (float *, float *, int *, omp_interop_t)' (aka 'void (float *, float *, int *, void *)') is incompatible with type 'void (float *, float *, int *)' with appended arguments}}
44 #pragma omp declare variant(smemberfoo_v1) match(construct={dispatch}) \
45 append_args(interop(target),interop(target))
46 static void smemberbar(float *A
, float *B
, int *I
) { return; }
48 virtual void vmemberfoo_v0(float *A
, float *B
, int *I
);
49 virtual void vmemberfoo_v1(float *A
, float *B
, int *I
, omp_interop_t IOp
);
51 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (A::*)(float *, float *, int *)' is incompatible with type 'void (A::*)(float *, float *, int *, omp_interop_t)' with appended arguments}}
52 #pragma omp declare variant(vmemberfoo_v0) match(construct={dispatch}) \
53 append_args(interop(target))
55 #pragma omp declare variant(vmemberfoo_v1) match(construct={dispatch}) \
56 append_args(interop(target))
58 // expected-error@+1 {{'#pragma omp declare variant' does not support virtual functions}}
59 virtual void vmemberbar(float *A
, float *B
, int *I
) { return; }
61 virtual void pvmemberfoo_v0(float *A
, float *B
, int *I
) = 0;
62 virtual void pvmemberfoo_v1(float *A
, float *B
, int *I
, omp_interop_t IOp
) = 0;
64 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (A::*)(float *, float *, int *)' is incompatible with type 'void (A::*)(float *, float *, int *, omp_interop_t)' with appended arguments}}
65 #pragma omp declare variant(pvmemberfoo_v0) match(construct={dispatch}) \
66 append_args(interop(target))
68 #pragma omp declare variant(pvmemberfoo_v1) match(construct={dispatch}) \
69 append_args(interop(target))
71 // expected-error@+1 {{'#pragma omp declare variant' does not support virtual functions}}
72 virtual void pvmemberbar(float *A
, float *B
, int *I
) = 0;
75 template <typename T
> void templatefoo_v0(const T
& t
);
76 template <typename T
> void templatefoo_v1(const T
& t
, omp_interop_t I
);
77 template <typename T
> void templatebar(const T
& t
) {}
79 // expected-error@+1 {{variant in '#pragma omp declare variant' with type '<overloaded function type>' is incompatible with type 'void (const int &)' with appended arguments}}
80 #pragma omp declare variant(templatefoo_v0<int>) match(construct={dispatch}) \
81 append_args(interop(target))
83 // expected-error@+1 {{variant in '#pragma omp declare variant' with type '<overloaded function type>' is incompatible with type 'void (const int &)' with appended arguments}}
84 #pragma omp declare variant(templatefoo_v1<int>) match(construct={dispatch}) \
85 append_args(interop(target),interop(target))
86 void templatebar(const int &t
) {}
88 #endif // _OPENMP >= 202011
90 void foo_v1(float *AAA
, float *BBB
, int *I
) { return; }
91 void foo_v2(float *AAA
, float *BBB
, int *I
) { return; }
92 void foo_v3(float *AAA
, float *BBB
, int *I
) { return; }
93 void foo_v4(float *AAA
, float *BBB
, int *I
, omp_interop_t IOp
) { return; }
95 #if _OPENMP >= 202011 // At least OpenMP 5.1
96 void vararg_foo(const char *fmt
, omp_interop_t it
, ...);
97 // expected-error@+3 {{'append_args' is not allowed with varargs functions}}
98 #pragma omp declare variant(vararg_foo) match(construct={dispatch}) \
99 append_args(interop(target))
100 void vararg_bar(const char *fmt
, ...) { return; }
102 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (const char *, omp_interop_t, ...)' (aka 'void (const char *, void *, ...)') is incompatible with type 'void (const char *)' with appended arguments}}
103 #pragma omp declare variant(vararg_foo) match(construct={dispatch}) \
104 append_args(interop(target))
105 void vararg_bar2(const char *fmt
) { return; }
107 // expected-error@+3 {{'adjust_arg' argument 'AAA' used in multiple clauses}}
108 #pragma omp declare variant(foo_v1) \
109 match(construct={dispatch}, device={arch(arm)}) \
110 adjust_args(need_device_ptr:AAA,BBB) adjust_args(need_device_ptr:AAA)
112 // expected-error@+3 {{'adjust_arg' argument 'AAA' used in multiple clauses}}
113 #pragma omp declare variant(foo_v1) \
114 match(construct={dispatch}, device={arch(ppc)}), \
115 adjust_args(need_device_ptr:AAA) adjust_args(nothing:AAA)
117 // expected-error@+2 {{use of undeclared identifier 'J'}}
118 #pragma omp declare variant(foo_v1) \
119 adjust_args(nothing:J) \
120 match(construct={dispatch}, device={arch(x86,x86_64)})
122 // expected-error@+2 {{expected reference to one of the parameters of function 'foo'}}
123 #pragma omp declare variant(foo_v3) \
124 adjust_args(nothing:Other) \
125 match(construct={dispatch}, device={arch(x86,x86_64)})
127 // expected-error@+2 {{'adjust_args' clause requires 'dispatch' context selector}}
128 #pragma omp declare variant(foo_v3) \
129 adjust_args(nothing:BBB) match(construct={target}, device={arch(arm)})
131 // expected-error@+2 {{'adjust_args' clause requires 'dispatch' context selector}}
132 #pragma omp declare variant(foo_v3) \
133 adjust_args(nothing:BBB) match(device={arch(ppc)})
135 // expected-error@+1 {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
136 #pragma omp declare variant(foo_v1)
138 // expected-error@+1 {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
139 #pragma omp declare variant(foo_v1) other
141 // expected-error@+2 {{unexpected operation specified in 'append_args' clause, expected 'interop'}}
142 #pragma omp declare variant(foo_v1) match(construct={dispatch}) \
143 append_args(foobar(target))
145 // expected-error@+2 {{directive '#pragma omp declare variant' cannot contain more than one 'append_args' clause}}
146 #pragma omp declare variant(foo_v1) match(construct={dispatch}) \
147 append_args(interop(target)) \
148 append_args(interop(targetsync))
150 // expected-error@+2 {{'append_args' clause requires 'dispatch' context selector}}
151 #pragma omp declare variant(foo_v4) \
152 append_args(interop(target)) match(construct={target})
154 // expected-error@+2 {{'append_args' clause requires 'dispatch' context selector}}
155 #pragma omp declare variant(foo_v4) \
156 match(construct={target}) append_args(interop(target))
158 // expected-warning@+2 {{interop type 'target' cannot be specified more than once}}
159 #pragma omp declare variant(foo_v4) match(construct={dispatch}) \
160 append_args(interop(target,target))
162 // expected-warning@+2 {{interop type 'targetsync' cannot be specified more than once}}
163 #pragma omp declare variant(foo_v4) match(construct={dispatch}) \
164 append_args(interop(targetsync,targetsync))
166 // expected-error@+2 {{expected interop type: 'target' and/or 'targetsync'}}
167 #pragma omp declare variant(foo_v4) match(construct={dispatch}) \
168 append_args(interop())
170 // expected-error@+2 {{expected interop type: 'target' and/or 'targetsync'}}
171 #pragma omp declare variant(foo_v4) match(construct={dispatch}) \
172 append_args(interop(somethingelse))
174 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (float *, float *, int *)' is incompatible with type 'void (float *, float *, int *)' with appended arguments}}
175 #pragma omp declare variant(foo_v1) match(construct={dispatch}) \
176 append_args(interop(target))
178 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (float *, float *, int *)' is incompatible with type 'void (float *, float *, int *)' with appended arguments}}
179 #pragma omp declare variant(foo_v1) match(construct={dispatch}) \
180 append_args(interop(target),interop(targetsync))
182 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (float *, float *, int *, omp_interop_t)' (aka 'void (float *, float *, int *, void *)') is incompatible with type 'void (float *, float *, int *)' with appended arguments}}
183 #pragma omp declare variant(foo_v4) match(construct={dispatch}) \
184 append_args(interop(target),interop(targetsync))
186 // expected-error@+1 {{variant in '#pragma omp declare variant' with type 'void (float *, float *, int *, omp_interop_t)' (aka 'void (float *, float *, int *, void *)') is incompatible with type 'void (float *, float *, int *)'}}
187 #pragma omp declare variant(foo_v4) match(construct={dispatch})
189 #endif // _OPENMP >= 202011
190 #if _OPENMP < 202011 // OpenMP 5.0 or lower
191 // expected-error@+2 {{expected 'match' clause on 'omp declare variant' directive}}
192 #pragma omp declare variant(foo_v1) \
193 adjust_args(need_device_ptr:AAA) match(device={arch(arm)})
194 // expected-error@+2 {{expected 'match' clause on 'omp declare variant' directive}}
195 #pragma omp declare variant(foo_v1) \
196 append_args(interop(target)) match(device={arch(arm)})
197 #endif // _OPENMP < 202011
199 void foo(float *AAA
, float *BBB
, int *I
) { return; }
201 #endif // NO_INTEROP_T_DEF
204 void c_variant(omp_interop_t
);
205 // expected-error@+3 {{function with '#pragma omp declare variant' must have a prototype when 'append_args' is used}}
206 #pragma omp declare variant(c_variant) \
207 append_args(interop(target)) match(construct={dispatch})
210 void _cdecl
win_c_variant(omp_interop_t
);
211 // expected-error@+3 {{function with '#pragma omp declare variant' must have a prototype when 'append_args' is used}}
212 #pragma omp declare variant(win_c_variant) \
213 append_args(interop(target)) match(construct={dispatch})
214 void _cdecl
win_c_base() {}