1c30dd2daSAlexey Bataev // RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
2c30dd2daSAlexey Bataev // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
3c30dd2daSAlexey Bataev // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
4a8a9153aSAlexey Bataev 
5a8a9153aSAlexey Bataev // RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
6a8a9153aSAlexey Bataev // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
7a8a9153aSAlexey Bataev // RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
8c30dd2daSAlexey Bataev // expected-no-diagnostics
9c30dd2daSAlexey Bataev 
10c30dd2daSAlexey Bataev #ifndef HEADER
11c30dd2daSAlexey Bataev #define HEADER
12c30dd2daSAlexey Bataev 
foo()13c30dd2daSAlexey Bataev void foo() {}
14c30dd2daSAlexey Bataev 
15169d96a2SAlexey Bataev struct S1 {
S1S116169d96a2SAlexey Bataev   S1(): a(0) {}
S1S117169d96a2SAlexey Bataev   S1(int v) : a(v) {}
18169d96a2SAlexey Bataev   int a;
19169d96a2SAlexey Bataev   typedef int type;
20169d96a2SAlexey Bataev   S1& operator +(const S1&);
21169d96a2SAlexey Bataev   S1& operator *(const S1&);
22169d96a2SAlexey Bataev   S1& operator &&(const S1&);
23169d96a2SAlexey Bataev   S1& operator ^(const S1&);
24169d96a2SAlexey Bataev };
25169d96a2SAlexey Bataev 
26169d96a2SAlexey Bataev template <typename T>
27169d96a2SAlexey Bataev class S7 : public T {
28169d96a2SAlexey Bataev protected:
29169d96a2SAlexey Bataev   T a;
30169d96a2SAlexey Bataev   T b[100];
S7()31169d96a2SAlexey Bataev   S7() : a(0) {}
32169d96a2SAlexey Bataev 
33169d96a2SAlexey Bataev public:
S7(typename T::type v)34169d96a2SAlexey Bataev   S7(typename T::type v) : a(v) {
35169d96a2SAlexey Bataev #pragma omp taskgroup task_reduction(+ : a) task_reduction(*: b[:])
36169d96a2SAlexey Bataev     for (int k = 0; k < a.a; ++k)
37169d96a2SAlexey Bataev       ++this->a.a;
38169d96a2SAlexey Bataev   }
operator =(S7 & s)39169d96a2SAlexey Bataev   S7 &operator=(S7 &s) {
40169d96a2SAlexey Bataev #pragma omp taskgroup task_reduction(&& : this->a) task_reduction(^: b[s.a.a])
41169d96a2SAlexey Bataev     for (int k = 0; k < s.a.a; ++k)
42169d96a2SAlexey Bataev       ++s.a.a;
43169d96a2SAlexey Bataev     return *this;
44169d96a2SAlexey Bataev   }
45169d96a2SAlexey Bataev };
46169d96a2SAlexey Bataev 
47169d96a2SAlexey Bataev // CHECK: #pragma omp taskgroup task_reduction(+: this->a) task_reduction(*: this->b[:])
48169d96a2SAlexey Bataev // CHECK: #pragma omp taskgroup task_reduction(&&: this->a) task_reduction(^: this->b[s.a.a])
49169d96a2SAlexey Bataev // CHECK: #pragma omp taskgroup task_reduction(+: this->a) task_reduction(*: this->b[:])
50169d96a2SAlexey Bataev 
51169d96a2SAlexey Bataev class S8 : public S7<S1> {
S8()52169d96a2SAlexey Bataev   S8() {}
53169d96a2SAlexey Bataev 
54169d96a2SAlexey Bataev public:
S8(int v)55169d96a2SAlexey Bataev   S8(int v) : S7<S1>(v){
56169d96a2SAlexey Bataev #pragma omp taskgroup task_reduction(^ : S7 < S1 > ::a) task_reduction(+ : S7 < S1 > ::b[ : S7 < S1 > ::a.a])
57169d96a2SAlexey Bataev     for (int k = 0; k < a.a; ++k)
58169d96a2SAlexey Bataev       ++this->a.a;
59169d96a2SAlexey Bataev   }
operator =(S8 & s)60169d96a2SAlexey Bataev   S8 &operator=(S8 &s) {
61169d96a2SAlexey Bataev #pragma omp taskgroup task_reduction(* : this->a) task_reduction(&&:this->b[a.a:])
62169d96a2SAlexey Bataev     for (int k = 0; k < s.a.a; ++k)
63169d96a2SAlexey Bataev       ++s.a.a;
64169d96a2SAlexey Bataev     return *this;
65169d96a2SAlexey Bataev   }
66169d96a2SAlexey Bataev };
67169d96a2SAlexey Bataev 
68169d96a2SAlexey Bataev // CHECK: #pragma omp taskgroup task_reduction(^: this->S7<S1>::a) task_reduction(+: this->S7<S1>::b[:this->S7<S1>::a.a])
69169d96a2SAlexey Bataev // CHECK: #pragma omp taskgroup task_reduction(*: this->a) task_reduction(&&: this->b[this->a.a:])
70169d96a2SAlexey Bataev 
main(int argc,char ** argv)71c30dd2daSAlexey Bataev int main (int argc, char **argv) {
72c30dd2daSAlexey Bataev   int b = argc, c, d, e, f, g;
73c30dd2daSAlexey Bataev   static int a;
74c30dd2daSAlexey Bataev // CHECK: static int a;
75c30dd2daSAlexey Bataev #pragma omp taskgroup
76c30dd2daSAlexey Bataev   a=2;
77*cbecfdfeSAlexey Bataev // CHECK-NEXT: #pragma omp taskgroup{{$}}
78c30dd2daSAlexey Bataev // CHECK-NEXT: a = 2;
79c30dd2daSAlexey Bataev // CHECK-NEXT: ++a;
80c30dd2daSAlexey Bataev   ++a;
81169d96a2SAlexey Bataev #pragma omp taskgroup task_reduction(min: a)
82c30dd2daSAlexey Bataev   foo();
83169d96a2SAlexey Bataev // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: a)
84c30dd2daSAlexey Bataev // CHECK-NEXT: foo();
85c30dd2daSAlexey Bataev // CHECK-NEXT: return 0;
86c30dd2daSAlexey Bataev   return 0;
87c30dd2daSAlexey Bataev }
88c30dd2daSAlexey Bataev 
89c30dd2daSAlexey Bataev #endif
90