1 // RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
3 // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
4 // expected-no-diagnostics
5 
6 #ifndef HEADER
7 #define HEADER
8 
9 void foo() {}
10 
11 struct S1 {
12   S1(): a(0) {}
13   S1(int v) : a(v) {}
14   int a;
15   typedef int type;
16 };
17 
18 template <typename T>
19 class S7 : public T {
20 protected:
21   T a;
22   S7() : a(0) {}
23 
24 public:
25   S7(typename T::type v) : a(v) {
26 #pragma omp parallel private(a) private(this->a) private(T::a)
27     for (int k = 0; k < a.a; ++k)
28       ++this->a.a;
29 #pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(T::a)
30     for (int k = 0; k < a.a; ++k)
31       ++this->a.a;
32 #pragma omp parallel shared(a) shared(this->a) shared(T::a)
33     for (int k = 0; k < a.a; ++k)
34       ++this->a.a;
35   }
36   S7 &operator=(S7 &s) {
37 #pragma omp parallel private(a) private(this->a)
38     for (int k = 0; k < s.a.a; ++k)
39       ++s.a.a;
40 #pragma omp parallel firstprivate(a) firstprivate(this->a)
41     for (int k = 0; k < s.a.a; ++k)
42       ++s.a.a;
43 #pragma omp parallel shared(a) shared(this->a)
44     for (int k = 0; k < s.a.a; ++k)
45       ++s.a.a;
46     return *this;
47   }
48 };
49 
50 // CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S1::a)
51 // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(this->S1::a)
52 // CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(this->S1::a)
53 // CHECK: #pragma omp parallel private(this->a) private(this->a) private(T::a)
54 // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(T::a)
55 // CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(T::a)
56 // CHECK: #pragma omp parallel private(this->a) private(this->a)
57 // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a)
58 // CHECK: #pragma omp parallel shared(this->a) shared(this->a)
59 
60 class S8 : public S7<S1> {
61   S8() {}
62 
63 public:
64   S8(int v) : S7<S1>(v){
65 #pragma omp parallel private(a) private(this->a) private(S7 < S1 > ::a)
66     for (int k = 0; k < a.a; ++k)
67       ++this->a.a;
68 #pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(S7 < S1 > ::a)
69     for (int k = 0; k < a.a; ++k)
70       ++this->a.a;
71 #pragma omp parallel shared(a) shared(this->a) shared(S7 < S1 > ::a)
72     for (int k = 0; k < a.a; ++k)
73       ++this->a.a;
74   }
75   S8 &operator=(S8 &s) {
76 #pragma omp parallel private(a) private(this->a)
77     for (int k = 0; k < s.a.a; ++k)
78       ++s.a.a;
79 #pragma omp parallel firstprivate(a) firstprivate(this->a)
80     for (int k = 0; k < s.a.a; ++k)
81       ++s.a.a;
82 #pragma omp parallel shared(a) shared(this->a)
83     for (int k = 0; k < s.a.a; ++k)
84       ++s.a.a;
85     return *this;
86   }
87 };
88 
89 // CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S7<S1>::a)
90 // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(this->S7<S1>::a)
91 // CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(this->S7<S1>::a)
92 // CHECK: #pragma omp parallel private(this->a) private(this->a)
93 // CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a)
94 // CHECK: #pragma omp parallel shared(this->a) shared(this->a)
95 
96 template <class T>
97 struct S {
98   operator T() {return T();}
99   static T TS;
100   #pragma omp threadprivate(TS)
101 };
102 
103 // CHECK:      template <class T = int> struct S {
104 // CHECK:        static int TS;
105 // CHECK-NEXT:   #pragma omp threadprivate(S<int>::TS)
106 // CHECK-NEXT: }
107 // CHECK:      template <class T = long> struct S {
108 // CHECK:        static long TS;
109 // CHECK-NEXT:   #pragma omp threadprivate(S<long>::TS)
110 // CHECK-NEXT: }
111 // CHECK:      template <class T> struct S {
112 // CHECK:        static T TS;
113 // CHECK-NEXT:   #pragma omp threadprivate(S::TS)
114 // CHECK:      };
115 
116 template <typename T, int C>
117 T tmain(T argc, T *argv) {
118   T b = argc, c, d, e, f, g;
119   static T a;
120   S<T> s;
121   T arr[C][10], arr1[C];
122 #pragma omp parallel
123   a=2;
124 #pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
125   foo();
126 #pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g)
127   foo();
128   return 0;
129 }
130 
131 // CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
132 // CHECK-NEXT: int b = argc, c, d, e, f, g;
133 // CHECK-NEXT: static int a;
134 // CHECK-NEXT: S<int> s;
135 // CHECK-NEXT: int arr[5][10], arr1[5];
136 // CHECK-NEXT: #pragma omp parallel
137 // CHECK-NEXT: a = 2;
138 // CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
139 // CHECK-NEXT: foo()
140 // CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g)
141 // CHECK-NEXT: foo()
142 // CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) {
143 // CHECK-NEXT: long b = argc, c, d, e, f, g;
144 // CHECK-NEXT: static long a;
145 // CHECK-NEXT: S<long> s;
146 // CHECK-NEXT: long arr[1][10], arr1[1];
147 // CHECK-NEXT: #pragma omp parallel
148 // CHECK-NEXT: a = 2;
149 // CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
150 // CHECK-NEXT: foo()
151 // CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g)
152 // CHECK-NEXT: foo()
153 // CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
154 // CHECK-NEXT: T b = argc, c, d, e, f, g;
155 // CHECK-NEXT: static T a;
156 // CHECK-NEXT: S<T> s;
157 // CHECK-NEXT: T arr[C][10], arr1[C];
158 // CHECK-NEXT: #pragma omp parallel
159 // CHECK-NEXT: a = 2;
160 // CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
161 // CHECK-NEXT: foo()
162 // CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g)
163 // CHECK-NEXT: foo()
164 
165 enum Enum { };
166 
167 int main (int argc, char **argv) {
168   long x;
169   int b = argc, c, d, e, f, g;
170   static int a;
171   #pragma omp threadprivate(a)
172   int arr[10][argc], arr1[2];
173   Enum ee;
174 // CHECK: Enum ee;
175 #pragma omp parallel
176 // CHECK-NEXT: #pragma omp parallel
177   a=2;
178 // CHECK-NEXT: a = 2;
179 #pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d, arr1[argc]) reduction(* : e, arr[:10][0:argc])
180 // CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d,arr1[argc]) reduction(*: e,arr[:10][0:argc])
181   foo();
182 // CHECK-NEXT: foo();
183 // CHECK-NEXT: #pragma omp parallel if(b) num_threads(c) proc_bind(close) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10])
184 // CHECK-NEXT: foo()
185 #pragma omp parallel if (b) num_threads(c) proc_bind(close) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10])
186   foo();
187   return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
188 }
189 
190 template <class T>
191 struct Foo {
192   int foo;
193 };
194 
195 void foo(const Foo<int> &arg) {
196 // CHECK: #pragma omp parallel
197 #pragma omp parallel
198   {
199 // CHECK: #pragma omp for schedule(static)
200 #pragma omp for schedule(static)
201     for (int idx = 0; idx < 1234; ++idx) {
202       //arg.foo = idx;
203       idx = arg.foo;
204     }
205   }
206 }
207 
208 #endif
209