1// RUN: %clang_cc1 -verify -fopenmp %s
2
3void foo() {
4}
5
6bool foobool(int argc) {
7  return argc;
8}
9
10struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
11extern S1 a;
12class S2 {
13  mutable int a;
14
15public:
16  S2() : a(0) {}
17};
18const S2 b;
19const S2 ba[5];
20class S3 {
21  int a;
22
23public:
24  S3() : a(0) {}
25};
26const S3 ca[5];
27class S4 {
28  int a;
29  S4(); // expected-note {{implicitly declared private here}}
30
31public:
32  S4(int v) : a(v) {
33#pragma omp single private(a) private(this->a)
34    for (int k = 0; k < v; ++k)
35      ++this->a;
36  }
37};
38class S5 {
39  int a;
40  S5() : a(0) {} // expected-note {{implicitly declared private here}}
41
42public:
43  S5(int v) : a(v) {}
44  S5 &operator=(S5 &s) {
45#pragma omp single private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
46    for (int k = 0; k < s.a; ++k)
47      ++s.a;
48    return *this;
49  }
50};
51
52template <typename T>
53class S6 {
54public:
55  T a;
56
57  S6() : a(0) {}
58  S6(T v) : a(v) {
59#pragma omp single private(a) private(this->a)
60    for (int k = 0; k < v; ++k)
61      ++this->a;
62  }
63  S6 &operator=(S6 &s) {
64#pragma omp single private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
65    for (int k = 0; k < s.a; ++k)
66      ++s.a;
67    return *this;
68  }
69};
70
71template <typename T>
72class S7 : public T {
73  T a;
74  S7() : a(0) {}
75
76public:
77  S7(T v) : a(v) {
78#pragma omp single private(a) private(this->a) private(T::a)
79    for (int k = 0; k < a.a; ++k)
80      ++this->a.a;
81  }
82  S7 &operator=(S7 &s) {
83#pragma omp single private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
84    for (int k = 0; k < s.a.a; ++k)
85      ++s.a.a;
86    return *this;
87  }
88};
89
90S3 h;
91#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
92
93template <class I, class C>
94int foomain(I argc, C **argv) {
95  I e(4);
96  I g(5);
97  int i;
98  int &j = i;
99#pragma omp single private // expected-error {{expected '(' after 'private'}}
100  foo();
101#pragma omp single private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
102  foo();
103#pragma omp single private() // expected-error {{expected expression}}
104  foo();
105#pragma omp single private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
106  foo();
107#pragma omp single private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
108  foo();
109#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
110  foo();
111#pragma omp single private(argc)
112  foo();
113#pragma omp single private(S1) // expected-error {{'S1' does not refer to a value}}
114  foo();
115#pragma omp single private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
116  foo();
117#pragma omp single private(argv[1]) // expected-error {{expected variable name}}
118  foo();
119#pragma omp single private(e, g)
120  foo();
121#pragma omp single private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
122  foo();
123#pragma omp single shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp single'}}
124  foo();
125#pragma omp parallel
126  {
127    int v = 0;
128    int i;
129#pragma omp single private(i)
130    foo();
131    v += i;
132  }
133#pragma omp parallel shared(i)
134#pragma omp parallel private(i)
135#pragma omp single private(j)
136  foo();
137#pragma omp single private(i)
138  foo();
139  return 0;
140}
141
142namespace A {
143double x;
144#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
145}
146namespace B {
147using A::x;
148}
149
150int main(int argc, char **argv) {
151  S4 e(4);
152  S5 g(5);
153  S6<float> s6(0.0) , s6_0(1.0);
154  S7<S6<float> > s7(0.0) , s7_0(1.0);
155  int i;
156  int &j = i;
157#pragma omp single private // expected-error {{expected '(' after 'private'}}
158  foo();
159#pragma omp single private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
160  foo();
161#pragma omp single private() // expected-error {{expected expression}}
162  foo();
163#pragma omp single private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
164  foo();
165#pragma omp single private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
166  foo();
167#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
168  foo();
169#pragma omp single private(argc)
170  foo();
171#pragma omp single private(S1) // expected-error {{'S1' does not refer to a value}}
172  foo();
173#pragma omp single private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
174  foo();
175#pragma omp single private(argv[1]) // expected-error {{expected variable name}}
176  foo();
177#pragma omp single private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
178  foo();
179#pragma omp single private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
180  foo();
181#pragma omp single shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp single'}}
182  foo();
183#pragma omp parallel
184  {
185    int i;
186#pragma omp single private(i)
187    foo();
188  }
189#pragma omp parallel shared(i)
190#pragma omp parallel private(i)
191#pragma omp single private(j)
192  foo();
193#pragma omp single private(i)
194  foo();
195  static int m;
196#pragma omp single private(m) // OK
197  foo();
198
199  s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
200  s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
201  return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
202}
203
204