1 // RUN: %clang_cc1 -verify -triple x86_64-unknown-linux -fopenmp -fopenmp-version=51 -std=c++11 -o - %s 2 // RUN: %clang_cc1 -verify -triple x86_64-unknown-linux -fopenmp -fopenmp-version=51 -std=c++11 \ 3 // RUN: -DNO_INTEROP_T_DEF -o - %s 4 // RUN: %clang_cc1 -verify -triple x86_64-unknown-linux -fopenmp -fopenmp-version=50 -std=c++11 -o - %s 5 // RUN: %clang_cc1 -verify -triple x86_64-unknown-linux -fopenmp -fopenmp-version=51 -DC -x c -o - %s 6 // RUN: %clang_cc1 -verify -triple x86_64-pc-windows-msvc -fms-compatibility \ 7 // RUN: -fopenmp -fopenmp-version=51 -DC -DWIN -x c -o - %s 8 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}) 14 void foo_v1(float *); 15 #else 16 typedef void *omp_interop_t; 17 18 int Other; 19 20 #if _OPENMP >= 202011 // At least OpenMP 5.1 21 #ifdef __cplusplus 22 class A { 23 public: 24 void memberfoo_v0(float *A, float *B, int *I); 25 void memberfoo_v1(float *A, float *B, int *I, omp_interop_t IOp); 26 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)) 30 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; } 35 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); 38 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)) 42 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; } 47 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); 50 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)) 54 55 #pragma omp declare variant(vmemberfoo_v1) match(construct={dispatch}) \ 56 append_args(interop(target)) 57 58 // expected-error@+1 {{'#pragma omp declare variant' does not support virtual functions}} 59 virtual void vmemberbar(float *A, float *B, int *I) { return; } 60 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; 63 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)) 67 68 #pragma omp declare variant(pvmemberfoo_v1) match(construct={dispatch}) \ 69 append_args(interop(target)) 70 71 // expected-error@+1 {{'#pragma omp declare variant' does not support virtual functions}} 72 virtual void pvmemberbar(float *A, float *B, int *I) = 0; 73 }; 74 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) {} 78 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)) 82 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) {} 87 #endif // __cplusplus 88 #endif // _OPENMP >= 202011 89 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; } 94 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; } 101 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; } 106 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) 111 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) 116 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)}) 121 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)}) 126 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)}) 130 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)}) 134 135 // expected-error@+1 {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} 136 #pragma omp declare variant(foo_v1) 137 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 140 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)) 144 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)) 149 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}) 153 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)) 157 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)) 161 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)) 165 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()) 169 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)) 173 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)) 177 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)) 181 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)) 185 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}) 188 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 198 199 void foo(float *AAA, float *BBB, int *I) { return; } 200 201 #endif // NO_INTEROP_T_DEF 202 203 #ifdef C 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}) 208 void c_base() {} 209 #ifdef WIN 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() {} 215 #endif // WIN 216 #endif 217