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 S {
12   S(): a(0) {}
13   S(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 for private(a) private(this->a) private(T::a)
27     for (int k = 0; k < a.a; ++k)
28       ++this->a.a;
29 #pragma omp for lastprivate(a) lastprivate(this->a) lastprivate(T::a)
30     for (int k = 0; k < a.a; ++k)
31       ++this->a.a;
32   }
33   S7 &operator=(S7 &s) {
34 #pragma omp for private(a) private(this->a)
35     for (int k = 0; k < s.a.a; ++k)
36       ++s.a.a;
37 #pragma omp for lastprivate(a) lastprivate(this->a)
38     for (int k = 0; k < s.a.a; ++k)
39       ++s.a.a;
40     return *this;
41   }
42 };
43 
44 // CHECK: #pragma omp for private(this->a) private(this->a) private(this->S::a)
45 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S::a)
46 // CHECK: #pragma omp for private(this->a) private(this->a) private(T::a)
47 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(T::a)
48 // CHECK: #pragma omp for private(this->a) private(this->a)
49 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a)
50 
51 class S8 : public S7<S> {
52   S8() {}
53 
54 public:
55   S8(int v) : S7<S>(v){
56 #pragma omp for private(a) private(this->a) private(S7<S>::a)
57     for (int k = 0; k < a.a; ++k)
58       ++this->a.a;
59 #pragma omp for lastprivate(a) lastprivate(this->a) lastprivate(S7<S>::a)
60     for (int k = 0; k < a.a; ++k)
61       ++this->a.a;
62   }
63   S8 &operator=(S8 &s) {
64 #pragma omp for private(a) private(this->a)
65     for (int k = 0; k < s.a.a; ++k)
66       ++s.a.a;
67 #pragma omp for lastprivate(a) lastprivate(this->a)
68     for (int k = 0; k < s.a.a; ++k)
69       ++s.a.a;
70     return *this;
71   }
72 };
73 
74 // CHECK: #pragma omp for private(this->a) private(this->a) private(this->S7<S>::a)
75 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S7<S>::a)
76 // CHECK: #pragma omp for private(this->a) private(this->a)
77 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a)
78 
79 template <class T, int N>
80 T tmain(T argc) {
81   T b = argc, c, d, e, f, g;
82   static T a;
83 // CHECK: static T a;
84 #pragma omp for schedule(dynamic) linear(a)
85   // CHECK-NEXT: #pragma omp for schedule(dynamic) linear(a)
86   for (int i = 0; i < 2; ++i)
87     a = 2;
88 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
89 // CHECK-NEXT: a = 2;
90 #pragma omp parallel
91 #pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) nowait
92   for (int i = 0; i < 2; ++i)
93     for (int j = 0; j < 2; ++j)
94       for (int j = 0; j < 2; ++j)
95         for (int j = 0; j < 2; ++j)
96           for (int j = 0; j < 2; ++j)
97   for (int i = 0; i < 2; ++i)
98     for (int j = 0; j < 2; ++j)
99       for (int j = 0; j < 2; ++j)
100         for (int j = 0; j < 2; ++j)
101           for (int j = 0; j < 2; ++j)
102             foo();
103   // CHECK-NEXT: #pragma omp parallel
104   // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) nowait
105   // CHECK-NEXT: for (int i = 0; i < 2; ++i)
106   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
107   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
108   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
109   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
110   // CHECK-NEXT: for (int i = 0; i < 2; ++i)
111   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
112   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
113   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
114   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
115   // CHECK-NEXT: foo();
116   return T();
117 }
118 
119 int main(int argc, char **argv) {
120   int b = argc, c, d, e, f, g;
121   static int a;
122 // CHECK: static int a;
123 #pragma omp for schedule(guided, argc)
124   // CHECK-NEXT: #pragma omp for schedule(guided, argc)
125   for (int i = 0; i < 2; ++i)
126     a = 2;
127 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
128 // CHECK-NEXT: a = 2;
129 #pragma omp parallel
130 #pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered nowait linear(g:-1)
131   for (int i = 0; i < 10; ++i)
132     for (int j = 0; j < 10; ++j)
133       foo();
134   // CHECK-NEXT: #pragma omp parallel
135   // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered nowait linear(g: -1)
136   // CHECK-NEXT: for (int i = 0; i < 10; ++i)
137   // CHECK-NEXT: for (int j = 0; j < 10; ++j)
138   // CHECK-NEXT: foo();
139   char buf[9] = "01234567";
140   char *p, *q;
141 #pragma omp parallel
142 #pragma omp for
143   for (p = buf; p < &buf[8]; p++)
144     for (q = &buf[0]; q <= buf + 7; q++)
145       foo();
146   // CHECK: #pragma omp parallel
147   // CHECK-NEXT: #pragma omp for
148   // CHECK-NEXT: for (p = buf; p < &buf[8]; p++)
149   // CHECK-NEXT: for (q = &buf[0]; q <= buf + 7; q++)
150   // CHECK-NEXT: foo();
151   return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
152 }
153 
154 #endif
155