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