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