| // RUN: %clang_cc1 -verify -Wno-vla -fopenmp -ast-print %s | FileCheck %s | |
| // RUN: %clang_cc1 -verify -Wno-vla -fopenmp -fopenmp-version=60 -DOMP60 -ast-print %s | FileCheck %s --check-prefix=CHECK60 | |
| // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s | |
| // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -verify -Wno-vla %s -ast-print | FileCheck %s | |
| // RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -ast-print %s | FileCheck %s | |
| // RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -fopenmp-version=60 -DOMP60 -ast-print %s | FileCheck %s --check-prefix=CHECK60 | |
| // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s | |
| // RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -verify -Wno-vla %s -ast-print | FileCheck %s | |
| // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -ast-dump %s | FileCheck %s --check-prefix=DUMP | |
| // expected-no-diagnostics | |
| #ifndef HEADER | |
| #define HEADER | |
| typedef void *omp_depend_t; | |
| typedef unsigned long omp_event_handle_t; | |
| void foo() {} | |
| struct S1 { | |
| S1(): a(0) {} | |
| S1(int v) : a(v) {} | |
| int a; | |
| typedef int type; | |
| S1 operator +(const S1&); | |
| }; | |
| template <typename T> | |
| class S7 : public T { | |
| protected: | |
| T a, b, c[10], d[10]; | |
| S7() : a(0) {} | |
| public: | |
| S7(typename T::type v) : a(v) { | |
| omp_depend_t x; | |
| omp_event_handle_t evt; | |
| #pragma omp taskgroup allocate(b) task_reduction(+:b) | |
| #pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b) allocate(b) depend(depobj:x) detach(evt) depend(iterator(i=0:10:1, T *k = &a:&b), in: c[i], d[(int)(k-&a)]) affinity(iterator(i=0:10:1, T *k = &a:&b): c[i], d[(int)(k-&a)]) | |
| for (int k = 0; k < a.a; ++k) | |
| ++this->a.a; | |
| } | |
| S7 &operator=(S7 &s) { | |
| #pragma omp task private(a) private(this->a) | |
| for (int k = 0; k < s.a.a; ++k) | |
| ++s.a.a; | |
| return *this; | |
| } | |
| }; | |
| // CHECK: #pragma omp taskgroup allocate(this->b) task_reduction(+: this->b) | |
| // CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt) depend(iterator(int i = 0:10:1, T * k = &this->a:&this->b), in : this->c[i],this->d[(int)(k - &this->a)]) affinity(iterator(int i = 0:10:1, T * k = &this->a:&this->b) : this->c[i],this->d[(int)(k - &this->a)]){{$}} | |
| // CHECK: #pragma omp task private(this->a) private(this->a) | |
| // CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt) depend(iterator(int i = 0:10:1, S1 * k = &this->a:&this->b), in : this->c[i],this->d[(int)(k - &this->a)]) affinity(iterator(int i = 0:10:1, S1 * k = &this->a:&this->b) : this->c[i],this->d[(int)(k - &this->a)]) | |
| class S8 : public S7<S1> { | |
| S8() {} | |
| public: | |
| S8(int v) : S7<S1>(v){ | |
| #pragma omp task private(a) private(this->a) private(S7<S1>::a) | |
| for (int k = 0; k < a.a; ++k) | |
| ++this->a.a; | |
| } | |
| S8 &operator=(S8 &s) { | |
| #pragma omp task private(a) private(this->a) | |
| for (int k = 0; k < s.a.a; ++k) | |
| ++s.a.a; | |
| return *this; | |
| } | |
| }; | |
| // CHECK: #pragma omp task private(this->a) private(this->a) private(this->S7<S1>::a) | |
| // CHECK: #pragma omp task private(this->a) private(this->a) | |
| template <class T> | |
| struct S { | |
| operator T() { return T(); } | |
| static T TS; | |
| #pragma omp threadprivate(TS) | |
| }; | |
| // CHECK: template <class T> struct S { | |
| // CHECK: static T TS; | |
| // CHECK-NEXT: #pragma omp threadprivate(S::TS) | |
| // CHECK: }; | |
| // CHECK: template<> struct S<int> { | |
| // CHECK: static int TS; | |
| // CHECK-NEXT: #pragma omp threadprivate(S<int>::TS) | |
| // CHECK-NEXT: } | |
| template <typename T, int C> | |
| T tmain(T argc, T *argv) { | |
| T b = argc, c, d, e, f, g; | |
| static T a; | |
| S<T> s; | |
| T arr[argc]; | |
| omp_depend_t x; | |
| omp_event_handle_t evt; | |
| double *arr_double; | |
| #pragma omp task untied depend(in : argc, argv[b:argc], arr[:], ([argc][sizeof(T)])argv, arr_double[argc]) if (task : argc > 0) depend(depobj: x) detach(evt) | |
| a = 2; | |
| #pragma omp task default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) final(S<T>::TS > 0) priority(argc) affinity(argc, argv[b:argc], arr[:], ([argc][sizeof(T)])argv) | |
| foo(); | |
| #pragma omp taskgroup task_reduction(+: argc) | |
| #pragma omp task if (C) mergeable priority(C) in_reduction(+: argc) | |
| foo(); | |
| return 0; | |
| } | |
| // CHECK: template <typename T, int C> T tmain(T argc, T *argv) { | |
| // CHECK-NEXT: T b = argc, c, d, e, f, g; | |
| // CHECK-NEXT: static T a; | |
| // CHECK-NEXT: S<T> s; | |
| // CHECK-NEXT: T arr[argc]; | |
| // CHECK-NEXT: omp_depend_t x; | |
| // CHECK-NEXT: omp_event_handle_t evt; | |
| // CHECK-NEXT: double *arr_double; | |
| // CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(T)])argv,arr_double[argc]) if(task: argc > 0) depend(depobj : x) detach(evt) | |
| // CHECK-NEXT: a = 2; | |
| // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<T>::TS > 0) priority(argc) affinity(argc,argv[b:argc],arr[:],([argc][sizeof(T)])argv) | |
| // CHECK-NEXT: foo() | |
| // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: argc) | |
| // CHECK-NEXT: #pragma omp task if(C) mergeable priority(C) in_reduction(+: argc) | |
| // CHECK-NEXT: foo() | |
| // CHECK: template<> int tmain<int, 5>(int argc, int *argv) { | |
| // CHECK-NEXT: int b = argc, c, d, e, f, g; | |
| // CHECK-NEXT: static int a; | |
| // CHECK-NEXT: S<int> s; | |
| // CHECK-NEXT: int arr[argc]; | |
| // CHECK-NEXT: omp_depend_t x; | |
| // CHECK-NEXT: omp_event_handle_t evt; | |
| // CHECK-NEXT: double *arr_double; | |
| // CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(int)])argv,arr_double[argc]) if(task: argc > 0) depend(depobj : x) detach(evt) | |
| // CHECK-NEXT: a = 2; | |
| // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<int>::TS > 0) priority(argc) affinity(argc,argv[b:argc],arr[:],([argc][sizeof(int)])argv) | |
| // CHECK-NEXT: foo() | |
| // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: argc) | |
| // CHECK-NEXT: #pragma omp task if(5) mergeable priority(5) in_reduction(+: argc) | |
| // CHECK-NEXT: foo() | |
| // CHECK: template<> long tmain<long, 1>(long argc, long *argv) { | |
| // CHECK-NEXT: long b = argc, c, d, e, f, g; | |
| // CHECK-NEXT: static long a; | |
| // CHECK-NEXT: S<long> s; | |
| // CHECK-NEXT: long arr[argc]; | |
| // CHECK-NEXT: omp_depend_t x; | |
| // CHECK-NEXT: omp_event_handle_t evt; | |
| // CHECK-NEXT: double *arr_double; | |
| // CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(long)])argv,arr_double[argc]) if(task: argc > 0) depend(depobj : x) detach(evt) | |
| // CHECK-NEXT: a = 2; | |
| // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<long>::TS > 0) priority(argc) affinity(argc,argv[b:argc],arr[:],([argc][sizeof(long)])argv) | |
| // CHECK-NEXT: foo() | |
| // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: argc) | |
| // CHECK-NEXT: #pragma omp task if(1) mergeable priority(1) in_reduction(+: argc) | |
| // CHECK-NEXT: foo() | |
| enum Enum {}; | |
| #ifdef OMP60 | |
| typedef void **omp_impex_t; | |
| extern const omp_impex_t omp_not_impex; | |
| extern const omp_impex_t omp_import; | |
| extern const omp_impex_t omp_export; | |
| extern const omp_impex_t omp_impex; | |
| template <int C> | |
| void TestTaskLoopImpex() { | |
| #pragma omp taskloop transparent(C) | |
| for (int i = 0; i < 10; ++i) {} | |
| } | |
| enum class TaskType { | |
| TypeA, | |
| TypeB, | |
| TypeC | |
| }; | |
| template <typename T> | |
| class TransparentTemplate { | |
| public: | |
| void TestTaskImport() { | |
| #pragma omp task transparent(omp_import) | |
| { | |
| T temp; | |
| } | |
| } | |
| void TestTaskLoopImpex() { | |
| #pragma omp taskloop transparent(omp_impex) | |
| for (int i = 0; i < 10; ++i) {} | |
| } | |
| }; | |
| #endif | |
| int main(int argc, char **argv) { | |
| long x; | |
| int b = argc, c, d, e, f, g; | |
| static int a; | |
| int arr[10], arr1[argc]; | |
| omp_depend_t y; | |
| omp_event_handle_t evt; | |
| #ifdef OMP60 | |
| omp_impex_t v = omp_import; | |
| #endif | |
| #pragma omp threadprivate(a) | |
| Enum ee; | |
| // CHECK: Enum ee; | |
| #pragma omp task untied mergeable depend(out:argv[:a][1], (arr)[0:],([argc][10])argv,b) if(task: argc > 0) priority(f) depend(depobj:y) | |
| // CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:],([argc][10])argv,b) if(task: argc > 0) priority(f) depend(depobj : y) | |
| a = 2; | |
| // CHECK-NEXT: a = 2; | |
| #pragma omp taskgroup task_reduction(min: arr1) | |
| #pragma omp task default(none), private(argc, b) firstprivate(argv, evt) if (argc > 0) final(a > 0) depend(inout : a, argv[:argc],arr[:a], ([10][argc])argv) priority(23) in_reduction(min: arr1), detach(evt) | |
| // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1) | |
| // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv,evt) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a],([10][argc])argv) priority(23) in_reduction(min: arr1) detach(evt) | |
| foo(); | |
| // CHECK-NEXT: foo(); | |
| #pragma omp taskgroup task_reduction(min: arr1) | |
| #pragma omp parallel reduction(+:arr1) | |
| #pragma omp task in_reduction(min: arr1) depend(iterator(i=0:argc, unsigned j=argc:0:a), out: argv[i][j]) | |
| // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1) | |
| // CHECK-NEXT: #pragma omp parallel reduction(+: arr1) | |
| // CHECK-NEXT: #pragma omp task in_reduction(min: arr1) depend(iterator(int i = 0:argc, unsigned int j = argc:0:a), out : argv[i][j]) | |
| foo(); | |
| // CHECK-NEXT: foo(); | |
| // CHECK-NEXT: #pragma omp task in_reduction(+: arr1) | |
| #pragma omp task in_reduction(+: arr1) | |
| foo(); | |
| // CHECK-NEXT: foo(); | |
| // CHECK-NEXT: #pragma omp task depend(out : arr,omp_all_memory) | |
| #pragma omp task depend(out: omp_all_memory, arr) | |
| foo(); | |
| // CHECK-NEXT: foo(); | |
| // CHECK-NEXT: #pragma omp task depend(inout : b,arr,a,x,omp_all_memory) | |
| #pragma omp task depend(inout: b, arr, omp_all_memory, a, x) | |
| foo(); | |
| // CHECK-NEXT: foo(); | |
| // CHECK-NEXT: #pragma omp task depend(inout : omp_all_memory) | |
| #pragma omp task depend(inout: omp_all_memory) | |
| foo(); | |
| // CHECK-NEXT: foo(); | |
| #ifdef OMP60 | |
| #pragma omp task threadset(omp_pool) | |
| #pragma omp task threadset(omp_team) | |
| foo(); | |
| #pragma omp task transparent shared(x) | |
| #pragma omp task transparent(omp_export) shared(x) | |
| #pragma omp task transparent | |
| #pragma omp task transparent(omp_not_impex) | |
| #pragma omp task transparent(omp_import) | |
| #pragma omp task transparent(omp_export) | |
| #pragma omp task transparent(omp_impex) | |
| #pragma omp task transparent(omp_import) | |
| #pragma omp task transparent(v) | |
| #pragma omp task transparent(v ? omp_import : omp_export) | |
| #pragma omp task transparent(omp_import + 0) | |
| #pragma omp task transparent((v)) | |
| foo(); | |
| TestTaskLoopImpex<1>(); | |
| TaskType task = TaskType::TypeA; | |
| #pragma omp task transparent(task) | |
| foo(); | |
| #endif | |
| // CHECK60: #pragma omp taskloop transparent(C) | |
| // CHECK60: #pragma omp taskloop transparent(1) | |
| // CHECK60: #pragma omp task transparent(omp_import) | |
| // CHECK60: #pragma omp taskloop transparent(omp_impex) | |
| // CHECK60: #pragma omp task transparent(omp_import) | |
| // CHECK60: #pragma omp taskloop transparent(omp_impex) | |
| // CHECK60: #pragma omp task threadset(omp_pool) | |
| // CHECK60: #pragma omp task threadset(omp_team) | |
| // CHECK60-NEXT: foo(); | |
| // CHECK60: #pragma omp task transparent(omp_impex) shared(x) | |
| // CHECK60: #pragma omp task transparent(omp_export) shared(x) | |
| // CHECK60: #pragma omp task transparent(omp_impex) | |
| // CHECK60: #pragma omp task transparent(omp_not_impex) | |
| // CHECK60-NEXT: #pragma omp task transparent(omp_import) | |
| // CHECK60-NEXT: #pragma omp task transparent(omp_export) | |
| // CHECK60-NEXT: #pragma omp task transparent(omp_impex) | |
| // CHECK60-NEXT: #pragma omp task transparent(omp_import) | |
| // CHECK60-NEXT: #pragma omp task transparent(v) | |
| // CHECK60-NEXT: #pragma omp task transparent(v ? omp_import : omp_export) | |
| // CHECK60-NEXT: #pragma omp task transparent(omp_import + 0) | |
| // CHECK60-NEXT: #pragma omp task transparent((v)) | |
| // CHECK60-NEXT: foo(); | |
| // CHECK60: #pragma omp task transparent(task) | |
| // CHECK60-NEXT: foo(); | |
| return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x); | |
| } | |
| #ifdef OMP60 | |
| void TestTaskTransparent() { | |
| TransparentTemplate<int> obj; | |
| obj.TestTaskImport(); | |
| obj.TestTaskLoopImpex(); | |
| } | |
| #endif | |
| extern template int S<int>::TS; | |
| extern template long S<long>::TS; | |
| // DUMP-LABEL: FunctionDecl {{.*}} implicit_firstprivate | |
| void | |
| implicit_firstprivate() { | |
| #pragma omp parallel num_threads(1) | |
| { | |
| int i = 0; | |
| // DUMP: OMPTaskDirective | |
| // DUMP-NEXT: OMPFirstprivateClause | |
| // DUMP-NOT: DeclRefExpr {{.+}} 'i' {{.+}} non_odr_use_unevaluated | |
| // DUMP: DeclRefExpr {{.+}} 'i' 'int' refers_to_enclosing_variable_or_capture | |
| // DUMP: CapturedStmt | |
| // DUMP: BinaryOperator {{.+}} 'int' lvalue '=' | |
| // DUMP-NEXT: DeclRefExpr {{.+}} 'j' 'int' | |
| // DUMP: DeclRefExpr {{.+}} 'i' {{.+}} non_odr_use_unevaluated | |
| #pragma omp task | |
| { | |
| int j = sizeof(i); | |
| j = i; | |
| } | |
| } | |
| } | |
| // DUMP-LABEL: FunctionDecl {{.*}} no_implicit_firstprivate | |
| void | |
| no_implicit_firstprivate() { | |
| #pragma omp parallel num_threads(1) | |
| { | |
| int i = 0; | |
| // DUMP: OMPTaskDirective | |
| // DUMP-NEXT: CapturedStmt | |
| // DUMP: DeclRefExpr {{.+}} 'i' {{.+}} non_odr_use_unevaluated refers_to_enclosing_variable_or_capture | |
| #pragma omp task | |
| { | |
| int j = sizeof(i); | |
| } | |
| } | |
| } | |
| #endif |