xref: /llvm-project/clang/lib/Sema/SemaOpenACCClause.cpp (revision 13918f5be867976fc3b6bfd22c4dfd5cb20834f1)
1*2c75bda4Serichkeane //===--- SemaOpenACCClause.cpp - Semantic Analysis for OpenACC clause -----===//
2*2c75bda4Serichkeane //
3*2c75bda4Serichkeane // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2c75bda4Serichkeane // See https://llvm.org/LICENSE.txt for license information.
5*2c75bda4Serichkeane // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*2c75bda4Serichkeane //
7*2c75bda4Serichkeane //===----------------------------------------------------------------------===//
8*2c75bda4Serichkeane /// \file
9*2c75bda4Serichkeane /// This file implements semantic analysis for OpenACC clauses.
10*2c75bda4Serichkeane ///
11*2c75bda4Serichkeane //===----------------------------------------------------------------------===//
12*2c75bda4Serichkeane 
13*2c75bda4Serichkeane #include "clang/AST/OpenACCClause.h"
14*2c75bda4Serichkeane #include "clang/AST/DeclCXX.h"
15*2c75bda4Serichkeane #include "clang/Basic/DiagnosticSema.h"
16*2c75bda4Serichkeane #include "clang/Basic/OpenACCKinds.h"
17*2c75bda4Serichkeane #include "clang/Sema/SemaOpenACC.h"
18*2c75bda4Serichkeane 
19*2c75bda4Serichkeane using namespace clang;
20*2c75bda4Serichkeane 
21*2c75bda4Serichkeane namespace {
22*2c75bda4Serichkeane bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
23*2c75bda4Serichkeane                                 OpenACCClauseKind ClauseKind) {
24*2c75bda4Serichkeane   switch (ClauseKind) {
25*2c75bda4Serichkeane     // FIXME: For each clause as we implement them, we can add the
26*2c75bda4Serichkeane     // 'legalization' list here.
27*2c75bda4Serichkeane   case OpenACCClauseKind::Default:
28*2c75bda4Serichkeane     switch (DirectiveKind) {
29*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
30*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
31*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
32*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
33*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
34*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
35*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
36*2c75bda4Serichkeane       return true;
37*2c75bda4Serichkeane     default:
38*2c75bda4Serichkeane       return false;
39*2c75bda4Serichkeane     }
40*2c75bda4Serichkeane   case OpenACCClauseKind::If:
41*2c75bda4Serichkeane     switch (DirectiveKind) {
42*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
43*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
44*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
45*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
46*2c75bda4Serichkeane     case OpenACCDirectiveKind::EnterData:
47*2c75bda4Serichkeane     case OpenACCDirectiveKind::ExitData:
48*2c75bda4Serichkeane     case OpenACCDirectiveKind::HostData:
49*2c75bda4Serichkeane     case OpenACCDirectiveKind::Init:
50*2c75bda4Serichkeane     case OpenACCDirectiveKind::Shutdown:
51*2c75bda4Serichkeane     case OpenACCDirectiveKind::Set:
52*2c75bda4Serichkeane     case OpenACCDirectiveKind::Update:
53*2c75bda4Serichkeane     case OpenACCDirectiveKind::Wait:
54*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
55*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
56*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
57*2c75bda4Serichkeane       return true;
58*2c75bda4Serichkeane     default:
59*2c75bda4Serichkeane       return false;
60*2c75bda4Serichkeane     }
61*2c75bda4Serichkeane   case OpenACCClauseKind::Self:
62*2c75bda4Serichkeane     switch (DirectiveKind) {
63*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
64*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
65*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
66*2c75bda4Serichkeane     case OpenACCDirectiveKind::Update:
67*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
68*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
69*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
70*2c75bda4Serichkeane       return true;
71*2c75bda4Serichkeane     default:
72*2c75bda4Serichkeane       return false;
73*2c75bda4Serichkeane     }
74*2c75bda4Serichkeane   case OpenACCClauseKind::NumGangs:
75*2c75bda4Serichkeane   case OpenACCClauseKind::NumWorkers:
76*2c75bda4Serichkeane   case OpenACCClauseKind::VectorLength:
77*2c75bda4Serichkeane     switch (DirectiveKind) {
78*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
79*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
80*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
81*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
82*2c75bda4Serichkeane       return true;
83*2c75bda4Serichkeane     default:
84*2c75bda4Serichkeane       return false;
85*2c75bda4Serichkeane     }
86*2c75bda4Serichkeane   case OpenACCClauseKind::FirstPrivate:
87*2c75bda4Serichkeane     switch (DirectiveKind) {
88*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
89*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
90*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
91*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
92*2c75bda4Serichkeane       return true;
93*2c75bda4Serichkeane     default:
94*2c75bda4Serichkeane       return false;
95*2c75bda4Serichkeane     }
96*2c75bda4Serichkeane   case OpenACCClauseKind::Private:
97*2c75bda4Serichkeane     switch (DirectiveKind) {
98*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
99*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
100*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
101*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
102*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
103*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
104*2c75bda4Serichkeane       return true;
105*2c75bda4Serichkeane     default:
106*2c75bda4Serichkeane       return false;
107*2c75bda4Serichkeane     }
108*2c75bda4Serichkeane   case OpenACCClauseKind::NoCreate:
109*2c75bda4Serichkeane     switch (DirectiveKind) {
110*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
111*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
112*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
113*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
114*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
115*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
116*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
117*2c75bda4Serichkeane       return true;
118*2c75bda4Serichkeane     default:
119*2c75bda4Serichkeane       return false;
120*2c75bda4Serichkeane     }
121*2c75bda4Serichkeane   case OpenACCClauseKind::Present:
122*2c75bda4Serichkeane     switch (DirectiveKind) {
123*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
124*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
125*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
126*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
127*2c75bda4Serichkeane     case OpenACCDirectiveKind::Declare:
128*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
129*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
130*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
131*2c75bda4Serichkeane       return true;
132*2c75bda4Serichkeane     default:
133*2c75bda4Serichkeane       return false;
134*2c75bda4Serichkeane     }
135*2c75bda4Serichkeane 
136*2c75bda4Serichkeane   case OpenACCClauseKind::Copy:
137*2c75bda4Serichkeane   case OpenACCClauseKind::PCopy:
138*2c75bda4Serichkeane   case OpenACCClauseKind::PresentOrCopy:
139*2c75bda4Serichkeane     switch (DirectiveKind) {
140*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
141*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
142*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
143*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
144*2c75bda4Serichkeane     case OpenACCDirectiveKind::Declare:
145*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
146*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
147*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
148*2c75bda4Serichkeane       return true;
149*2c75bda4Serichkeane     default:
150*2c75bda4Serichkeane       return false;
151*2c75bda4Serichkeane     }
152*2c75bda4Serichkeane   case OpenACCClauseKind::CopyIn:
153*2c75bda4Serichkeane   case OpenACCClauseKind::PCopyIn:
154*2c75bda4Serichkeane   case OpenACCClauseKind::PresentOrCopyIn:
155*2c75bda4Serichkeane     switch (DirectiveKind) {
156*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
157*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
158*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
159*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
160*2c75bda4Serichkeane     case OpenACCDirectiveKind::EnterData:
161*2c75bda4Serichkeane     case OpenACCDirectiveKind::Declare:
162*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
163*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
164*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
165*2c75bda4Serichkeane       return true;
166*2c75bda4Serichkeane     default:
167*2c75bda4Serichkeane       return false;
168*2c75bda4Serichkeane     }
169*2c75bda4Serichkeane   case OpenACCClauseKind::CopyOut:
170*2c75bda4Serichkeane   case OpenACCClauseKind::PCopyOut:
171*2c75bda4Serichkeane   case OpenACCClauseKind::PresentOrCopyOut:
172*2c75bda4Serichkeane     switch (DirectiveKind) {
173*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
174*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
175*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
176*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
177*2c75bda4Serichkeane     case OpenACCDirectiveKind::ExitData:
178*2c75bda4Serichkeane     case OpenACCDirectiveKind::Declare:
179*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
180*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
181*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
182*2c75bda4Serichkeane       return true;
183*2c75bda4Serichkeane     default:
184*2c75bda4Serichkeane       return false;
185*2c75bda4Serichkeane     }
186*2c75bda4Serichkeane   case OpenACCClauseKind::Create:
187*2c75bda4Serichkeane   case OpenACCClauseKind::PCreate:
188*2c75bda4Serichkeane   case OpenACCClauseKind::PresentOrCreate:
189*2c75bda4Serichkeane     switch (DirectiveKind) {
190*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
191*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
192*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
193*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
194*2c75bda4Serichkeane     case OpenACCDirectiveKind::EnterData:
195*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
196*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
197*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
198*2c75bda4Serichkeane       return true;
199*2c75bda4Serichkeane     default:
200*2c75bda4Serichkeane       return false;
201*2c75bda4Serichkeane     }
202*2c75bda4Serichkeane 
203*2c75bda4Serichkeane   case OpenACCClauseKind::Attach:
204*2c75bda4Serichkeane     switch (DirectiveKind) {
205*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
206*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
207*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
208*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
209*2c75bda4Serichkeane     case OpenACCDirectiveKind::EnterData:
210*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
211*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
212*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
213*2c75bda4Serichkeane       return true;
214*2c75bda4Serichkeane     default:
215*2c75bda4Serichkeane       return false;
216*2c75bda4Serichkeane     }
217*2c75bda4Serichkeane   case OpenACCClauseKind::DevicePtr:
218*2c75bda4Serichkeane     switch (DirectiveKind) {
219*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
220*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
221*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
222*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
223*2c75bda4Serichkeane     case OpenACCDirectiveKind::Declare:
224*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
225*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
226*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
227*2c75bda4Serichkeane       return true;
228*2c75bda4Serichkeane     default:
229*2c75bda4Serichkeane       return false;
230*2c75bda4Serichkeane     }
231*2c75bda4Serichkeane   case OpenACCClauseKind::Async:
232*2c75bda4Serichkeane     switch (DirectiveKind) {
233*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
234*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
235*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
236*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
237*2c75bda4Serichkeane     case OpenACCDirectiveKind::EnterData:
238*2c75bda4Serichkeane     case OpenACCDirectiveKind::ExitData:
239*2c75bda4Serichkeane     case OpenACCDirectiveKind::Set:
240*2c75bda4Serichkeane     case OpenACCDirectiveKind::Update:
241*2c75bda4Serichkeane     case OpenACCDirectiveKind::Wait:
242*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
243*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
244*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
245*2c75bda4Serichkeane       return true;
246*2c75bda4Serichkeane     default:
247*2c75bda4Serichkeane       return false;
248*2c75bda4Serichkeane     }
249*2c75bda4Serichkeane   case OpenACCClauseKind::Wait:
250*2c75bda4Serichkeane     switch (DirectiveKind) {
251*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
252*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
253*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
254*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
255*2c75bda4Serichkeane     case OpenACCDirectiveKind::EnterData:
256*2c75bda4Serichkeane     case OpenACCDirectiveKind::ExitData:
257*2c75bda4Serichkeane     case OpenACCDirectiveKind::Update:
258*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
259*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
260*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
261*2c75bda4Serichkeane       return true;
262*2c75bda4Serichkeane     default:
263*2c75bda4Serichkeane       return false;
264*2c75bda4Serichkeane     }
265*2c75bda4Serichkeane 
266*2c75bda4Serichkeane   case OpenACCClauseKind::Seq:
267*2c75bda4Serichkeane     switch (DirectiveKind) {
268*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
269*2c75bda4Serichkeane     case OpenACCDirectiveKind::Routine:
270*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
271*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
272*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
273*2c75bda4Serichkeane       return true;
274*2c75bda4Serichkeane     default:
275*2c75bda4Serichkeane       return false;
276*2c75bda4Serichkeane     }
277*2c75bda4Serichkeane 
278*2c75bda4Serichkeane   case OpenACCClauseKind::Independent:
279*2c75bda4Serichkeane   case OpenACCClauseKind::Auto:
280*2c75bda4Serichkeane     switch (DirectiveKind) {
281*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
282*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
283*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
284*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
285*2c75bda4Serichkeane       return true;
286*2c75bda4Serichkeane     default:
287*2c75bda4Serichkeane       return false;
288*2c75bda4Serichkeane     }
289*2c75bda4Serichkeane 
290*2c75bda4Serichkeane   case OpenACCClauseKind::Reduction:
291*2c75bda4Serichkeane     switch (DirectiveKind) {
292*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
293*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
294*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
295*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
296*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
297*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
298*2c75bda4Serichkeane       return true;
299*2c75bda4Serichkeane     default:
300*2c75bda4Serichkeane       return false;
301*2c75bda4Serichkeane     }
302*2c75bda4Serichkeane 
303*2c75bda4Serichkeane   case OpenACCClauseKind::DeviceType:
304*2c75bda4Serichkeane   case OpenACCClauseKind::DType:
305*2c75bda4Serichkeane     switch (DirectiveKind) {
306*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
307*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
308*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
309*2c75bda4Serichkeane     case OpenACCDirectiveKind::Data:
310*2c75bda4Serichkeane     case OpenACCDirectiveKind::Init:
311*2c75bda4Serichkeane     case OpenACCDirectiveKind::Shutdown:
312*2c75bda4Serichkeane     case OpenACCDirectiveKind::Set:
313*2c75bda4Serichkeane     case OpenACCDirectiveKind::Update:
314*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
315*2c75bda4Serichkeane     case OpenACCDirectiveKind::Routine:
316*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
317*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
318*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
319*2c75bda4Serichkeane       return true;
320*2c75bda4Serichkeane     default:
321*2c75bda4Serichkeane       return false;
322*2c75bda4Serichkeane     }
323*2c75bda4Serichkeane 
324*2c75bda4Serichkeane   case OpenACCClauseKind::Collapse: {
325*2c75bda4Serichkeane     switch (DirectiveKind) {
326*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
327*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
328*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
329*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
330*2c75bda4Serichkeane       return true;
331*2c75bda4Serichkeane     default:
332*2c75bda4Serichkeane       return false;
333*2c75bda4Serichkeane     }
334*2c75bda4Serichkeane   }
335*2c75bda4Serichkeane   case OpenACCClauseKind::Tile: {
336*2c75bda4Serichkeane     switch (DirectiveKind) {
337*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
338*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
339*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
340*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
341*2c75bda4Serichkeane       return true;
342*2c75bda4Serichkeane     default:
343*2c75bda4Serichkeane       return false;
344*2c75bda4Serichkeane     }
345*2c75bda4Serichkeane   }
346*2c75bda4Serichkeane 
347*2c75bda4Serichkeane   case OpenACCClauseKind::Gang: {
348*2c75bda4Serichkeane     switch (DirectiveKind) {
349*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
350*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
351*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
352*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
353*2c75bda4Serichkeane     case OpenACCDirectiveKind::Routine:
354*2c75bda4Serichkeane       return true;
355*2c75bda4Serichkeane     default:
356*2c75bda4Serichkeane       return false;
357*2c75bda4Serichkeane     }
358*2c75bda4Serichkeane   case OpenACCClauseKind::Worker: {
359*2c75bda4Serichkeane     switch (DirectiveKind) {
360*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
361*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
362*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
363*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
364*2c75bda4Serichkeane     case OpenACCDirectiveKind::Routine:
365*2c75bda4Serichkeane       return true;
366*2c75bda4Serichkeane     default:
367*2c75bda4Serichkeane       return false;
368*2c75bda4Serichkeane     }
369*2c75bda4Serichkeane   }
370*2c75bda4Serichkeane   case OpenACCClauseKind::Vector: {
371*2c75bda4Serichkeane     switch (DirectiveKind) {
372*2c75bda4Serichkeane     case OpenACCDirectiveKind::Loop:
373*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
374*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
375*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
376*2c75bda4Serichkeane     case OpenACCDirectiveKind::Routine:
377*2c75bda4Serichkeane       return true;
378*2c75bda4Serichkeane     default:
379*2c75bda4Serichkeane       return false;
380*2c75bda4Serichkeane     }
381*2c75bda4Serichkeane   }
382*2c75bda4Serichkeane   case OpenACCClauseKind::Finalize: {
383*2c75bda4Serichkeane     switch (DirectiveKind) {
384*2c75bda4Serichkeane     case OpenACCDirectiveKind::ExitData:
385*2c75bda4Serichkeane       return true;
386*2c75bda4Serichkeane     default:
387*2c75bda4Serichkeane       return false;
388*2c75bda4Serichkeane     }
389*2c75bda4Serichkeane   }
390*2c75bda4Serichkeane   case OpenACCClauseKind::IfPresent: {
391*2c75bda4Serichkeane     switch (DirectiveKind) {
392*2c75bda4Serichkeane     case OpenACCDirectiveKind::HostData:
393*2c75bda4Serichkeane     case OpenACCDirectiveKind::Update:
394*2c75bda4Serichkeane       return true;
395*2c75bda4Serichkeane     default:
396*2c75bda4Serichkeane       return false;
397*2c75bda4Serichkeane     }
398*2c75bda4Serichkeane   }
399*2c75bda4Serichkeane   case OpenACCClauseKind::Delete: {
400*2c75bda4Serichkeane     switch (DirectiveKind) {
401*2c75bda4Serichkeane     case OpenACCDirectiveKind::ExitData:
402*2c75bda4Serichkeane       return true;
403*2c75bda4Serichkeane     default:
404*2c75bda4Serichkeane       return false;
405*2c75bda4Serichkeane     }
406*2c75bda4Serichkeane   }
407*2c75bda4Serichkeane 
408*2c75bda4Serichkeane   case OpenACCClauseKind::Detach: {
409*2c75bda4Serichkeane     switch (DirectiveKind) {
410*2c75bda4Serichkeane     case OpenACCDirectiveKind::ExitData:
411*2c75bda4Serichkeane       return true;
412*2c75bda4Serichkeane     default:
413*2c75bda4Serichkeane       return false;
414*2c75bda4Serichkeane     }
415*2c75bda4Serichkeane   }
416*2c75bda4Serichkeane 
417*2c75bda4Serichkeane   case OpenACCClauseKind::DeviceNum: {
418*2c75bda4Serichkeane     switch (DirectiveKind) {
419*2c75bda4Serichkeane     case OpenACCDirectiveKind::Init:
420*2c75bda4Serichkeane     case OpenACCDirectiveKind::Shutdown:
421*2c75bda4Serichkeane     case OpenACCDirectiveKind::Set:
422*2c75bda4Serichkeane       return true;
423*2c75bda4Serichkeane     default:
424*2c75bda4Serichkeane       return false;
425*2c75bda4Serichkeane     }
426*2c75bda4Serichkeane   }
427*2c75bda4Serichkeane 
428*2c75bda4Serichkeane   case OpenACCClauseKind::UseDevice: {
429*2c75bda4Serichkeane     switch (DirectiveKind) {
430*2c75bda4Serichkeane     case OpenACCDirectiveKind::HostData:
431*2c75bda4Serichkeane       return true;
432*2c75bda4Serichkeane     default:
433*2c75bda4Serichkeane       return false;
434*2c75bda4Serichkeane     }
435*2c75bda4Serichkeane   }
436*2c75bda4Serichkeane   case OpenACCClauseKind::DefaultAsync: {
437*2c75bda4Serichkeane     switch (DirectiveKind) {
438*2c75bda4Serichkeane     case OpenACCDirectiveKind::Set:
439*2c75bda4Serichkeane       return true;
440*2c75bda4Serichkeane     default:
441*2c75bda4Serichkeane       return false;
442*2c75bda4Serichkeane     }
443*2c75bda4Serichkeane   }
444*2c75bda4Serichkeane   case OpenACCClauseKind::Device: {
445*2c75bda4Serichkeane     switch (DirectiveKind) {
446*2c75bda4Serichkeane     case OpenACCDirectiveKind::Update:
447*2c75bda4Serichkeane       return true;
448*2c75bda4Serichkeane     default:
449*2c75bda4Serichkeane       return false;
450*2c75bda4Serichkeane     }
451*2c75bda4Serichkeane   }
452*2c75bda4Serichkeane   case OpenACCClauseKind::Host: {
453*2c75bda4Serichkeane     switch (DirectiveKind) {
454*2c75bda4Serichkeane     case OpenACCDirectiveKind::Update:
455*2c75bda4Serichkeane       return true;
456*2c75bda4Serichkeane     default:
457*2c75bda4Serichkeane       return false;
458*2c75bda4Serichkeane     }
459*2c75bda4Serichkeane   }
460*2c75bda4Serichkeane   }
461*2c75bda4Serichkeane 
462*2c75bda4Serichkeane   default:
463*2c75bda4Serichkeane     // Do nothing so we can go to the 'unimplemented' diagnostic instead.
464*2c75bda4Serichkeane     return true;
465*2c75bda4Serichkeane   }
466*2c75bda4Serichkeane   llvm_unreachable("Invalid clause kind");
467*2c75bda4Serichkeane }
468*2c75bda4Serichkeane 
469*2c75bda4Serichkeane bool checkAlreadyHasClauseOfKind(
470*2c75bda4Serichkeane     SemaOpenACC &S, ArrayRef<const OpenACCClause *> ExistingClauses,
471*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
472*2c75bda4Serichkeane   const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) {
473*2c75bda4Serichkeane     return C->getClauseKind() == Clause.getClauseKind();
474*2c75bda4Serichkeane   });
475*2c75bda4Serichkeane   if (Itr != ExistingClauses.end()) {
476*2c75bda4Serichkeane     S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)
477*2c75bda4Serichkeane         << Clause.getDirectiveKind() << Clause.getClauseKind();
478*2c75bda4Serichkeane     S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
479*2c75bda4Serichkeane     return true;
480*2c75bda4Serichkeane   }
481*2c75bda4Serichkeane   return false;
482*2c75bda4Serichkeane }
483*2c75bda4Serichkeane bool checkValidAfterDeviceType(
484*2c75bda4Serichkeane     SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
485*2c75bda4Serichkeane     const SemaOpenACC::OpenACCParsedClause &NewClause) {
486*2c75bda4Serichkeane   // This is implemented for everything but 'routine', so treat as 'fine' for
487*2c75bda4Serichkeane   // that.
488*2c75bda4Serichkeane   if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
489*2c75bda4Serichkeane     return false;
490*2c75bda4Serichkeane 
491*2c75bda4Serichkeane   // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are
492*2c75bda4Serichkeane   // default clauses.  Clauses that follow a device_type clause up to the end of
493*2c75bda4Serichkeane   // the directive or up to the next device_type clause are device-specific
494*2c75bda4Serichkeane   // clauses for the device types specified in the device_type argument.
495*2c75bda4Serichkeane   //
496*2c75bda4Serichkeane   // The above implies that despite what the individual text says, these are
497*2c75bda4Serichkeane   // valid.
498*2c75bda4Serichkeane   if (NewClause.getClauseKind() == OpenACCClauseKind::DType ||
499*2c75bda4Serichkeane       NewClause.getClauseKind() == OpenACCClauseKind::DeviceType)
500*2c75bda4Serichkeane     return false;
501*2c75bda4Serichkeane 
502*2c75bda4Serichkeane   // Implement check from OpenACC3.3: section 2.5.4:
503*2c75bda4Serichkeane   // Only the async, wait, num_gangs, num_workers, and vector_length clauses may
504*2c75bda4Serichkeane   // follow a device_type clause.
505*2c75bda4Serichkeane   if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) {
506*2c75bda4Serichkeane     switch (NewClause.getClauseKind()) {
507*2c75bda4Serichkeane     case OpenACCClauseKind::Async:
508*2c75bda4Serichkeane     case OpenACCClauseKind::Wait:
509*2c75bda4Serichkeane     case OpenACCClauseKind::NumGangs:
510*2c75bda4Serichkeane     case OpenACCClauseKind::NumWorkers:
511*2c75bda4Serichkeane     case OpenACCClauseKind::VectorLength:
512*2c75bda4Serichkeane       return false;
513*2c75bda4Serichkeane     default:
514*2c75bda4Serichkeane       break;
515*2c75bda4Serichkeane     }
516*2c75bda4Serichkeane   } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {
517*2c75bda4Serichkeane     // Implement check from OpenACC3.3: section 2.9:
518*2c75bda4Serichkeane     // Only the collapse, gang, worker, vector, seq, independent, auto, and tile
519*2c75bda4Serichkeane     // clauses may follow a device_type clause.
520*2c75bda4Serichkeane     switch (NewClause.getClauseKind()) {
521*2c75bda4Serichkeane     case OpenACCClauseKind::Collapse:
522*2c75bda4Serichkeane     case OpenACCClauseKind::Gang:
523*2c75bda4Serichkeane     case OpenACCClauseKind::Worker:
524*2c75bda4Serichkeane     case OpenACCClauseKind::Vector:
525*2c75bda4Serichkeane     case OpenACCClauseKind::Seq:
526*2c75bda4Serichkeane     case OpenACCClauseKind::Independent:
527*2c75bda4Serichkeane     case OpenACCClauseKind::Auto:
528*2c75bda4Serichkeane     case OpenACCClauseKind::Tile:
529*2c75bda4Serichkeane       return false;
530*2c75bda4Serichkeane     default:
531*2c75bda4Serichkeane       break;
532*2c75bda4Serichkeane     }
533*2c75bda4Serichkeane   } else if (isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind())) {
534*2c75bda4Serichkeane     // This seems like it should be the union of 2.9 and 2.5.4 from above.
535*2c75bda4Serichkeane     switch (NewClause.getClauseKind()) {
536*2c75bda4Serichkeane     case OpenACCClauseKind::Async:
537*2c75bda4Serichkeane     case OpenACCClauseKind::Wait:
538*2c75bda4Serichkeane     case OpenACCClauseKind::NumGangs:
539*2c75bda4Serichkeane     case OpenACCClauseKind::NumWorkers:
540*2c75bda4Serichkeane     case OpenACCClauseKind::VectorLength:
541*2c75bda4Serichkeane     case OpenACCClauseKind::Collapse:
542*2c75bda4Serichkeane     case OpenACCClauseKind::Gang:
543*2c75bda4Serichkeane     case OpenACCClauseKind::Worker:
544*2c75bda4Serichkeane     case OpenACCClauseKind::Vector:
545*2c75bda4Serichkeane     case OpenACCClauseKind::Seq:
546*2c75bda4Serichkeane     case OpenACCClauseKind::Independent:
547*2c75bda4Serichkeane     case OpenACCClauseKind::Auto:
548*2c75bda4Serichkeane     case OpenACCClauseKind::Tile:
549*2c75bda4Serichkeane       return false;
550*2c75bda4Serichkeane     default:
551*2c75bda4Serichkeane       break;
552*2c75bda4Serichkeane     }
553*2c75bda4Serichkeane   } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) {
554*2c75bda4Serichkeane     // OpenACC3.3 section 2.6.5: Only the async and wait clauses may follow a
555*2c75bda4Serichkeane     // device_type clause.
556*2c75bda4Serichkeane     switch (NewClause.getClauseKind()) {
557*2c75bda4Serichkeane     case OpenACCClauseKind::Async:
558*2c75bda4Serichkeane     case OpenACCClauseKind::Wait:
559*2c75bda4Serichkeane       return false;
560*2c75bda4Serichkeane     default:
561*2c75bda4Serichkeane       break;
562*2c75bda4Serichkeane     }
563*2c75bda4Serichkeane   } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set ||
564*2c75bda4Serichkeane              NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init ||
565*2c75bda4Serichkeane              NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) {
566*2c75bda4Serichkeane     // There are no restrictions on 'set', 'init', or 'shutdown'.
567*2c75bda4Serichkeane     return false;
568*2c75bda4Serichkeane   } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
569*2c75bda4Serichkeane     // OpenACC3.3 section 2.14.4: Only the async and wait clauses may follow a
570*2c75bda4Serichkeane     // device_type clause.
571*2c75bda4Serichkeane     switch (NewClause.getClauseKind()) {
572*2c75bda4Serichkeane     case OpenACCClauseKind::Async:
573*2c75bda4Serichkeane     case OpenACCClauseKind::Wait:
574*2c75bda4Serichkeane       return false;
575*2c75bda4Serichkeane     default:
576*2c75bda4Serichkeane       break;
577*2c75bda4Serichkeane     }
578*2c75bda4Serichkeane   }
579*2c75bda4Serichkeane   S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
580*2c75bda4Serichkeane       << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind()
581*2c75bda4Serichkeane       << NewClause.getDirectiveKind();
582*2c75bda4Serichkeane   S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here);
583*2c75bda4Serichkeane   return true;
584*2c75bda4Serichkeane }
585*2c75bda4Serichkeane 
586*2c75bda4Serichkeane // A temporary function that helps implement the 'not implemented' check at the
587*2c75bda4Serichkeane // top of each clause checking function. This should only be used in conjunction
588*2c75bda4Serichkeane // with the one being currently implemented/only updated after the entire
589*2c75bda4Serichkeane // construct has been implemented.
590*2c75bda4Serichkeane bool isDirectiveKindImplemented(OpenACCDirectiveKind DK) {
591*2c75bda4Serichkeane   return DK != OpenACCDirectiveKind::Declare &&
592*2c75bda4Serichkeane          DK != OpenACCDirectiveKind::Atomic &&
593*2c75bda4Serichkeane          DK != OpenACCDirectiveKind::Routine;
594*2c75bda4Serichkeane }
595*2c75bda4Serichkeane 
596*2c75bda4Serichkeane class SemaOpenACCClauseVisitor {
597*2c75bda4Serichkeane   SemaOpenACC &SemaRef;
598*2c75bda4Serichkeane   ASTContext &Ctx;
599*2c75bda4Serichkeane   ArrayRef<const OpenACCClause *> ExistingClauses;
600*2c75bda4Serichkeane   bool NotImplemented = false;
601*2c75bda4Serichkeane 
602*2c75bda4Serichkeane   OpenACCClause *isNotImplemented() {
603*2c75bda4Serichkeane     NotImplemented = true;
604*2c75bda4Serichkeane     return nullptr;
605*2c75bda4Serichkeane   }
606*2c75bda4Serichkeane 
607*2c75bda4Serichkeane   // OpenACC 3.3 2.9:
608*2c75bda4Serichkeane   // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
609*2c75bda4Serichkeane   // appears.
610*2c75bda4Serichkeane   bool DiagIfSeqClause(SemaOpenACC::OpenACCParsedClause &Clause) {
611*2c75bda4Serichkeane     const auto *Itr =
612*2c75bda4Serichkeane         llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
613*2c75bda4Serichkeane 
614*2c75bda4Serichkeane     if (Itr != ExistingClauses.end()) {
615*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
616*2c75bda4Serichkeane           << Clause.getClauseKind() << (*Itr)->getClauseKind()
617*2c75bda4Serichkeane           << Clause.getDirectiveKind();
618*2c75bda4Serichkeane       SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
619*2c75bda4Serichkeane 
620*2c75bda4Serichkeane       return true;
621*2c75bda4Serichkeane     }
622*2c75bda4Serichkeane     return false;
623*2c75bda4Serichkeane   }
624*2c75bda4Serichkeane 
625*2c75bda4Serichkeane public:
626*2c75bda4Serichkeane   SemaOpenACCClauseVisitor(SemaOpenACC &S,
627*2c75bda4Serichkeane                            ArrayRef<const OpenACCClause *> ExistingClauses)
628*2c75bda4Serichkeane       : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}
629*2c75bda4Serichkeane   // Once we've implemented everything, we shouldn't need this infrastructure.
630*2c75bda4Serichkeane   // But in the meantime, we use this to help decide whether the clause was
631*2c75bda4Serichkeane   // handled for this directive.
632*2c75bda4Serichkeane   bool diagNotImplemented() { return NotImplemented; }
633*2c75bda4Serichkeane 
634*2c75bda4Serichkeane   OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) {
635*2c75bda4Serichkeane     switch (Clause.getClauseKind()) {
636*2c75bda4Serichkeane #define VISIT_CLAUSE(CLAUSE_NAME)                                              \
637*2c75bda4Serichkeane   case OpenACCClauseKind::CLAUSE_NAME:                                         \
638*2c75bda4Serichkeane     return Visit##CLAUSE_NAME##Clause(Clause);
639*2c75bda4Serichkeane #define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED)                           \
640*2c75bda4Serichkeane   case OpenACCClauseKind::ALIAS:                                               \
641*2c75bda4Serichkeane   if (DEPRECATED)                                                              \
642*2c75bda4Serichkeane     SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)   \
643*2c75bda4Serichkeane         << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME;           \
644*2c75bda4Serichkeane   return Visit##CLAUSE_NAME##Clause(Clause);
645*2c75bda4Serichkeane #include "clang/Basic/OpenACCClauses.def"
646*2c75bda4Serichkeane     default:
647*2c75bda4Serichkeane       return isNotImplemented();
648*2c75bda4Serichkeane     }
649*2c75bda4Serichkeane     llvm_unreachable("Invalid clause kind");
650*2c75bda4Serichkeane   }
651*2c75bda4Serichkeane 
652*2c75bda4Serichkeane #define VISIT_CLAUSE(CLAUSE_NAME)                                              \
653*2c75bda4Serichkeane   OpenACCClause *Visit##CLAUSE_NAME##Clause(                                   \
654*2c75bda4Serichkeane       SemaOpenACC::OpenACCParsedClause &Clause);
655*2c75bda4Serichkeane #include "clang/Basic/OpenACCClauses.def"
656*2c75bda4Serichkeane };
657*2c75bda4Serichkeane 
658*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(
659*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
660*2c75bda4Serichkeane   // Don't add an invalid clause to the AST.
661*2c75bda4Serichkeane   if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid)
662*2c75bda4Serichkeane     return nullptr;
663*2c75bda4Serichkeane 
664*2c75bda4Serichkeane   // OpenACC 3.3, Section 2.5.4:
665*2c75bda4Serichkeane   // At most one 'default' clause may appear, and it must have a value of
666*2c75bda4Serichkeane   // either 'none' or 'present'.
667*2c75bda4Serichkeane   // Second half of the sentence is diagnosed during parsing.
668*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
669*2c75bda4Serichkeane     return nullptr;
670*2c75bda4Serichkeane 
671*2c75bda4Serichkeane   return OpenACCDefaultClause::Create(
672*2c75bda4Serichkeane       Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(),
673*2c75bda4Serichkeane       Clause.getLParenLoc(), Clause.getEndLoc());
674*2c75bda4Serichkeane }
675*2c75bda4Serichkeane 
676*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(
677*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
678*2c75bda4Serichkeane 
679*2c75bda4Serichkeane   // Duplicates here are not really sensible.  We could possible permit
680*2c75bda4Serichkeane   // multiples if they all had the same value, but there isn't really a good
681*2c75bda4Serichkeane   // reason to do so. Also, this simplifies the suppression of duplicates, in
682*2c75bda4Serichkeane   // that we know if we 'find' one after instantiation, that it is the same
683*2c75bda4Serichkeane   // clause, which simplifies instantiation/checking/etc.
684*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
685*2c75bda4Serichkeane     return nullptr;
686*2c75bda4Serichkeane 
687*2c75bda4Serichkeane   llvm::SmallVector<Expr *> NewSizeExprs;
688*2c75bda4Serichkeane 
689*2c75bda4Serichkeane   // Make sure these are all positive constant expressions or *.
690*2c75bda4Serichkeane   for (Expr *E : Clause.getIntExprs()) {
691*2c75bda4Serichkeane     ExprResult Res = SemaRef.CheckTileSizeExpr(E);
692*2c75bda4Serichkeane 
693*2c75bda4Serichkeane     if (!Res.isUsable())
694*2c75bda4Serichkeane       return nullptr;
695*2c75bda4Serichkeane 
696*2c75bda4Serichkeane     NewSizeExprs.push_back(Res.get());
697*2c75bda4Serichkeane   }
698*2c75bda4Serichkeane 
699*2c75bda4Serichkeane   return OpenACCTileClause::Create(Ctx, Clause.getBeginLoc(),
700*2c75bda4Serichkeane                                    Clause.getLParenLoc(), NewSizeExprs,
701*2c75bda4Serichkeane                                    Clause.getEndLoc());
702*2c75bda4Serichkeane }
703*2c75bda4Serichkeane 
704*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
705*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
706*2c75bda4Serichkeane   // There is no prose in the standard that says duplicates aren't allowed,
707*2c75bda4Serichkeane   // but this diagnostic is present in other compilers, as well as makes
708*2c75bda4Serichkeane   // sense. Prose DOES exist for 'data' and 'host_data', 'set', 'enter data' and
709*2c75bda4Serichkeane   // 'exit data' both don't, but other implmementations do this.  OpenACC issue
710*2c75bda4Serichkeane   // 519 filed for the latter two. Prose also exists for 'update'.
711*2c75bda4Serichkeane   // GCC allows this on init/shutdown, presumably for good reason, so we do too.
712*2c75bda4Serichkeane   if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init &&
713*2c75bda4Serichkeane       Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown &&
714*2c75bda4Serichkeane       checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
715*2c75bda4Serichkeane     return nullptr;
716*2c75bda4Serichkeane 
717*2c75bda4Serichkeane   // The parser has ensured that we have a proper condition expr, so there
718*2c75bda4Serichkeane   // isn't really much to do here.
719*2c75bda4Serichkeane 
720*2c75bda4Serichkeane   // If the 'if' clause is true, it makes the 'self' clause have no effect,
721*2c75bda4Serichkeane   // diagnose that here.  This only applies on compute/combined constructs.
722*2c75bda4Serichkeane   if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Update) {
723*2c75bda4Serichkeane     const auto *Itr =
724*2c75bda4Serichkeane         llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
725*2c75bda4Serichkeane     if (Itr != ExistingClauses.end()) {
726*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
727*2c75bda4Serichkeane       SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
728*2c75bda4Serichkeane     }
729*2c75bda4Serichkeane   }
730*2c75bda4Serichkeane 
731*2c75bda4Serichkeane   return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(),
732*2c75bda4Serichkeane                                  Clause.getLParenLoc(),
733*2c75bda4Serichkeane                                  Clause.getConditionExpr(), Clause.getEndLoc());
734*2c75bda4Serichkeane }
735*2c75bda4Serichkeane 
736*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
737*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
738*2c75bda4Serichkeane   // There is no prose in the standard that says duplicates aren't allowed,
739*2c75bda4Serichkeane   // but this diagnostic is present in other compilers, as well as makes
740*2c75bda4Serichkeane   // sense.
741*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
742*2c75bda4Serichkeane     return nullptr;
743*2c75bda4Serichkeane 
744*2c75bda4Serichkeane   // If the 'if' clause is true, it makes the 'self' clause have no effect,
745*2c75bda4Serichkeane   // diagnose that here.  This only applies on compute/combined constructs.
746*2c75bda4Serichkeane   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Update)
747*2c75bda4Serichkeane     return OpenACCSelfClause::Create(Ctx, Clause.getBeginLoc(),
748*2c75bda4Serichkeane                                      Clause.getLParenLoc(), Clause.getVarList(),
749*2c75bda4Serichkeane                                      Clause.getEndLoc());
750*2c75bda4Serichkeane 
751*2c75bda4Serichkeane   const auto *Itr =
752*2c75bda4Serichkeane       llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
753*2c75bda4Serichkeane   if (Itr != ExistingClauses.end()) {
754*2c75bda4Serichkeane     SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
755*2c75bda4Serichkeane     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
756*2c75bda4Serichkeane   }
757*2c75bda4Serichkeane   return OpenACCSelfClause::Create(
758*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
759*2c75bda4Serichkeane       Clause.getConditionExpr(), Clause.getEndLoc());
760*2c75bda4Serichkeane }
761*2c75bda4Serichkeane 
762*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
763*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
764*2c75bda4Serichkeane   // There is no prose in the standard that says duplicates aren't allowed,
765*2c75bda4Serichkeane   // but this diagnostic is present in other compilers, as well as makes
766*2c75bda4Serichkeane   // sense.
767*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
768*2c75bda4Serichkeane     return nullptr;
769*2c75bda4Serichkeane 
770*2c75bda4Serichkeane   // num_gangs requires at least 1 int expr in all forms.  Diagnose here, but
771*2c75bda4Serichkeane   // allow us to continue, an empty clause might be useful for future
772*2c75bda4Serichkeane   // diagnostics.
773*2c75bda4Serichkeane   if (Clause.getIntExprs().empty())
774*2c75bda4Serichkeane     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
775*2c75bda4Serichkeane         << /*NoArgs=*/0;
776*2c75bda4Serichkeane 
777*2c75bda4Serichkeane   unsigned MaxArgs =
778*2c75bda4Serichkeane       (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
779*2c75bda4Serichkeane        Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop)
780*2c75bda4Serichkeane           ? 3
781*2c75bda4Serichkeane           : 1;
782*2c75bda4Serichkeane   // The max number of args differs between parallel and other constructs.
783*2c75bda4Serichkeane   // Again, allow us to continue for the purposes of future diagnostics.
784*2c75bda4Serichkeane   if (Clause.getIntExprs().size() > MaxArgs)
785*2c75bda4Serichkeane     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
786*2c75bda4Serichkeane         << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs
787*2c75bda4Serichkeane         << Clause.getIntExprs().size();
788*2c75bda4Serichkeane 
789*2c75bda4Serichkeane   // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
790*2c75bda4Serichkeane   // directive that has a gang clause and is within a compute construct that has
791*2c75bda4Serichkeane   // a num_gangs clause with more than one explicit argument.
792*2c75bda4Serichkeane   if (Clause.getIntExprs().size() > 1 &&
793*2c75bda4Serichkeane       isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
794*2c75bda4Serichkeane     auto *GangClauseItr =
795*2c75bda4Serichkeane         llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
796*2c75bda4Serichkeane     auto *ReductionClauseItr =
797*2c75bda4Serichkeane         llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
798*2c75bda4Serichkeane 
799*2c75bda4Serichkeane     if (GangClauseItr != ExistingClauses.end() &&
800*2c75bda4Serichkeane         ReductionClauseItr != ExistingClauses.end()) {
801*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(),
802*2c75bda4Serichkeane                    diag::err_acc_gang_reduction_numgangs_conflict)
803*2c75bda4Serichkeane           << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
804*2c75bda4Serichkeane           << Clause.getDirectiveKind() << /*is on combined directive=*/1;
805*2c75bda4Serichkeane       SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
806*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
807*2c75bda4Serichkeane       SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
808*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
809*2c75bda4Serichkeane       return nullptr;
810*2c75bda4Serichkeane     }
811*2c75bda4Serichkeane   }
812*2c75bda4Serichkeane 
813*2c75bda4Serichkeane   // OpenACC 3.3 Section 2.5.4:
814*2c75bda4Serichkeane   // A reduction clause may not appear on a parallel construct with a
815*2c75bda4Serichkeane   // num_gangs clause that has more than one argument.
816*2c75bda4Serichkeane   if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
817*2c75bda4Serichkeane        Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) &&
818*2c75bda4Serichkeane       Clause.getIntExprs().size() > 1) {
819*2c75bda4Serichkeane     auto *Parallel =
820*2c75bda4Serichkeane         llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
821*2c75bda4Serichkeane 
822*2c75bda4Serichkeane     if (Parallel != ExistingClauses.end()) {
823*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(),
824*2c75bda4Serichkeane                    diag::err_acc_reduction_num_gangs_conflict)
825*2c75bda4Serichkeane           << /*>1 arg in first loc=*/1 << Clause.getClauseKind()
826*2c75bda4Serichkeane           << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction;
827*2c75bda4Serichkeane       SemaRef.Diag((*Parallel)->getBeginLoc(),
828*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
829*2c75bda4Serichkeane       return nullptr;
830*2c75bda4Serichkeane     }
831*2c75bda4Serichkeane   }
832*2c75bda4Serichkeane 
833*2c75bda4Serichkeane   // OpenACC 3.3 Section 2.9.2:
834*2c75bda4Serichkeane   // An argument with no keyword or with the 'num' keyword is allowed only when
835*2c75bda4Serichkeane   // the 'num_gangs' does not appear on the 'kernel' construct.
836*2c75bda4Serichkeane   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
837*2c75bda4Serichkeane     auto GangClauses = llvm::make_filter_range(
838*2c75bda4Serichkeane         ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
839*2c75bda4Serichkeane 
840*2c75bda4Serichkeane     for (auto *GC : GangClauses) {
841*2c75bda4Serichkeane       if (cast<OpenACCGangClause>(GC)->hasExprOfKind(OpenACCGangKind::Num)) {
842*2c75bda4Serichkeane         SemaRef.Diag(Clause.getBeginLoc(),
843*2c75bda4Serichkeane                      diag::err_acc_num_arg_conflict_reverse)
844*2c75bda4Serichkeane             << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang
845*2c75bda4Serichkeane             << /*Num argument*/ 1;
846*2c75bda4Serichkeane         SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here);
847*2c75bda4Serichkeane         return nullptr;
848*2c75bda4Serichkeane       }
849*2c75bda4Serichkeane     }
850*2c75bda4Serichkeane   }
851*2c75bda4Serichkeane 
852*2c75bda4Serichkeane   return OpenACCNumGangsClause::Create(
853*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(),
854*2c75bda4Serichkeane       Clause.getEndLoc());
855*2c75bda4Serichkeane }
856*2c75bda4Serichkeane 
857*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
858*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
859*2c75bda4Serichkeane   // There is no prose in the standard that says duplicates aren't allowed,
860*2c75bda4Serichkeane   // but this diagnostic is present in other compilers, as well as makes
861*2c75bda4Serichkeane   // sense.
862*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
863*2c75bda4Serichkeane     return nullptr;
864*2c75bda4Serichkeane 
865*2c75bda4Serichkeane   // OpenACC 3.3 Section 2.9.2:
866*2c75bda4Serichkeane   // An argument is allowed only when the 'num_workers' does not appear on the
867*2c75bda4Serichkeane   // kernels construct.
868*2c75bda4Serichkeane   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
869*2c75bda4Serichkeane     auto WorkerClauses = llvm::make_filter_range(
870*2c75bda4Serichkeane         ExistingClauses, llvm::IsaPred<OpenACCWorkerClause>);
871*2c75bda4Serichkeane 
872*2c75bda4Serichkeane     for (auto *WC : WorkerClauses) {
873*2c75bda4Serichkeane       if (cast<OpenACCWorkerClause>(WC)->hasIntExpr()) {
874*2c75bda4Serichkeane         SemaRef.Diag(Clause.getBeginLoc(),
875*2c75bda4Serichkeane                      diag::err_acc_num_arg_conflict_reverse)
876*2c75bda4Serichkeane             << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker
877*2c75bda4Serichkeane             << /*num argument*/ 0;
878*2c75bda4Serichkeane         SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here);
879*2c75bda4Serichkeane         return nullptr;
880*2c75bda4Serichkeane       }
881*2c75bda4Serichkeane     }
882*2c75bda4Serichkeane   }
883*2c75bda4Serichkeane 
884*2c75bda4Serichkeane   assert(Clause.getIntExprs().size() == 1 &&
885*2c75bda4Serichkeane          "Invalid number of expressions for NumWorkers");
886*2c75bda4Serichkeane   return OpenACCNumWorkersClause::Create(
887*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
888*2c75bda4Serichkeane       Clause.getEndLoc());
889*2c75bda4Serichkeane }
890*2c75bda4Serichkeane 
891*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
892*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
893*2c75bda4Serichkeane   // There is no prose in the standard that says duplicates aren't allowed,
894*2c75bda4Serichkeane   // but this diagnostic is present in other compilers, as well as makes
895*2c75bda4Serichkeane   // sense.
896*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
897*2c75bda4Serichkeane     return nullptr;
898*2c75bda4Serichkeane 
899*2c75bda4Serichkeane   // OpenACC 3.3 Section 2.9.4:
900*2c75bda4Serichkeane   // An argument is allowed only when the 'vector_length' does not appear on the
901*2c75bda4Serichkeane   // 'kernels' construct.
902*2c75bda4Serichkeane   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {
903*2c75bda4Serichkeane     auto VectorClauses = llvm::make_filter_range(
904*2c75bda4Serichkeane         ExistingClauses, llvm::IsaPred<OpenACCVectorClause>);
905*2c75bda4Serichkeane 
906*2c75bda4Serichkeane     for (auto *VC : VectorClauses) {
907*2c75bda4Serichkeane       if (cast<OpenACCVectorClause>(VC)->hasIntExpr()) {
908*2c75bda4Serichkeane         SemaRef.Diag(Clause.getBeginLoc(),
909*2c75bda4Serichkeane                      diag::err_acc_num_arg_conflict_reverse)
910*2c75bda4Serichkeane             << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector
911*2c75bda4Serichkeane             << /*num argument*/ 0;
912*2c75bda4Serichkeane         SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here);
913*2c75bda4Serichkeane         return nullptr;
914*2c75bda4Serichkeane       }
915*2c75bda4Serichkeane     }
916*2c75bda4Serichkeane   }
917*2c75bda4Serichkeane 
918*2c75bda4Serichkeane   assert(Clause.getIntExprs().size() == 1 &&
919*2c75bda4Serichkeane          "Invalid number of expressions for NumWorkers");
920*2c75bda4Serichkeane   return OpenACCVectorLengthClause::Create(
921*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
922*2c75bda4Serichkeane       Clause.getEndLoc());
923*2c75bda4Serichkeane }
924*2c75bda4Serichkeane 
925*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
926*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
927*2c75bda4Serichkeane   // There is no prose in the standard that says duplicates aren't allowed,
928*2c75bda4Serichkeane   // but this diagnostic is present in other compilers, as well as makes
929*2c75bda4Serichkeane   // sense.
930*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
931*2c75bda4Serichkeane     return nullptr;
932*2c75bda4Serichkeane 
933*2c75bda4Serichkeane   assert(Clause.getNumIntExprs() < 2 &&
934*2c75bda4Serichkeane          "Invalid number of expressions for Async");
935*2c75bda4Serichkeane   return OpenACCAsyncClause::Create(
936*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
937*2c75bda4Serichkeane       Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr,
938*2c75bda4Serichkeane       Clause.getEndLoc());
939*2c75bda4Serichkeane }
940*2c75bda4Serichkeane 
941*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause(
942*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
943*2c75bda4Serichkeane   // Restrictions only properly implemented on certain constructs, so skip/treat
944*2c75bda4Serichkeane   // as unimplemented in those cases.
945*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
946*2c75bda4Serichkeane     return isNotImplemented();
947*2c75bda4Serichkeane 
948*2c75bda4Serichkeane   // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
949*2c75bda4Serichkeane   // same directive.
950*2c75bda4Serichkeane   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
951*2c75bda4Serichkeane       checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
952*2c75bda4Serichkeane     return nullptr;
953*2c75bda4Serichkeane 
954*2c75bda4Serichkeane   assert(Clause.getNumIntExprs() == 1 &&
955*2c75bda4Serichkeane          "Invalid number of expressions for device_num");
956*2c75bda4Serichkeane   return OpenACCDeviceNumClause::Create(
957*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
958*2c75bda4Serichkeane       Clause.getEndLoc());
959*2c75bda4Serichkeane }
960*2c75bda4Serichkeane 
961*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause(
962*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
963*2c75bda4Serichkeane   // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
964*2c75bda4Serichkeane   // same directive.
965*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
966*2c75bda4Serichkeane     return nullptr;
967*2c75bda4Serichkeane 
968*2c75bda4Serichkeane   assert(Clause.getNumIntExprs() == 1 &&
969*2c75bda4Serichkeane          "Invalid number of expressions for default_async");
970*2c75bda4Serichkeane   return OpenACCDefaultAsyncClause::Create(
971*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
972*2c75bda4Serichkeane       Clause.getEndLoc());
973*2c75bda4Serichkeane }
974*2c75bda4Serichkeane 
975*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
976*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
977*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
978*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
979*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
980*2c75bda4Serichkeane 
981*2c75bda4Serichkeane   return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(),
982*2c75bda4Serichkeane                                       Clause.getLParenLoc(),
983*2c75bda4Serichkeane                                       Clause.getVarList(), Clause.getEndLoc());
984*2c75bda4Serichkeane }
985*2c75bda4Serichkeane 
986*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
987*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
988*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
989*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
990*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
991*2c75bda4Serichkeane 
992*2c75bda4Serichkeane   return OpenACCFirstPrivateClause::Create(
993*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
994*2c75bda4Serichkeane       Clause.getEndLoc());
995*2c75bda4Serichkeane }
996*2c75bda4Serichkeane 
997*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
998*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
999*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1000*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1001*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1002*2c75bda4Serichkeane 
1003*2c75bda4Serichkeane   return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(),
1004*2c75bda4Serichkeane                                        Clause.getLParenLoc(),
1005*2c75bda4Serichkeane                                        Clause.getVarList(), Clause.getEndLoc());
1006*2c75bda4Serichkeane }
1007*2c75bda4Serichkeane 
1008*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
1009*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1010*2c75bda4Serichkeane   // Restrictions only properly implemented on 'compute'/'combined'/'data'
1011*2c75bda4Serichkeane   // constructs, and 'compute'/'combined'/'data' constructs are the only
1012*2c75bda4Serichkeane   // construct that can do anything with this yet, so skip/treat as
1013*2c75bda4Serichkeane   // unimplemented in this case.
1014*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1015*2c75bda4Serichkeane     return isNotImplemented();
1016*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1017*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1018*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1019*2c75bda4Serichkeane 
1020*2c75bda4Serichkeane   return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(),
1021*2c75bda4Serichkeane                                       Clause.getLParenLoc(),
1022*2c75bda4Serichkeane                                       Clause.getVarList(), Clause.getEndLoc());
1023*2c75bda4Serichkeane }
1024*2c75bda4Serichkeane 
1025*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitHostClause(
1026*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1027*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1028*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1029*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1030*2c75bda4Serichkeane 
1031*2c75bda4Serichkeane   return OpenACCHostClause::Create(Ctx, Clause.getBeginLoc(),
1032*2c75bda4Serichkeane                                    Clause.getLParenLoc(), Clause.getVarList(),
1033*2c75bda4Serichkeane                                    Clause.getEndLoc());
1034*2c75bda4Serichkeane }
1035*2c75bda4Serichkeane 
1036*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceClause(
1037*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1038*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1039*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1040*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1041*2c75bda4Serichkeane 
1042*2c75bda4Serichkeane   return OpenACCDeviceClause::Create(Ctx, Clause.getBeginLoc(),
1043*2c75bda4Serichkeane                                      Clause.getLParenLoc(), Clause.getVarList(),
1044*2c75bda4Serichkeane                                      Clause.getEndLoc());
1045*2c75bda4Serichkeane }
1046*2c75bda4Serichkeane 
1047*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
1048*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1049*2c75bda4Serichkeane   // Restrictions only properly implemented on 'compute'/'combined'/'data'
1050*2c75bda4Serichkeane   // constructs, and 'compute'/'combined'/'data' constructs are the only
1051*2c75bda4Serichkeane   // construct that can do anything with this yet, so skip/treat as
1052*2c75bda4Serichkeane   // unimplemented in this case.
1053*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1054*2c75bda4Serichkeane     return isNotImplemented();
1055*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1056*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1057*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1058*2c75bda4Serichkeane 
1059*2c75bda4Serichkeane   return OpenACCCopyClause::Create(
1060*2c75bda4Serichkeane       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1061*2c75bda4Serichkeane       Clause.getVarList(), Clause.getEndLoc());
1062*2c75bda4Serichkeane }
1063*2c75bda4Serichkeane 
1064*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
1065*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1066*2c75bda4Serichkeane   // Restrictions only properly implemented on 'compute'/'combined'/'data'
1067*2c75bda4Serichkeane   // constructs, and 'compute'/'combined'/'data' constructs are the only
1068*2c75bda4Serichkeane   // construct that can do anything with this yet, so skip/treat as
1069*2c75bda4Serichkeane   // unimplemented in this case.
1070*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1071*2c75bda4Serichkeane     return isNotImplemented();
1072*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1073*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1074*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1075*2c75bda4Serichkeane 
1076*2c75bda4Serichkeane   return OpenACCCopyInClause::Create(
1077*2c75bda4Serichkeane       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1078*2c75bda4Serichkeane       Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc());
1079*2c75bda4Serichkeane }
1080*2c75bda4Serichkeane 
1081*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
1082*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1083*2c75bda4Serichkeane   // Restrictions only properly implemented on 'compute'/'combined'/'data'
1084*2c75bda4Serichkeane   // constructs, and 'compute'/'combined'/'data' constructs are the only
1085*2c75bda4Serichkeane   // construct that can do anything with this yet, so skip/treat as
1086*2c75bda4Serichkeane   // unimplemented in this case.
1087*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1088*2c75bda4Serichkeane     return isNotImplemented();
1089*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1090*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1091*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1092*2c75bda4Serichkeane 
1093*2c75bda4Serichkeane   return OpenACCCopyOutClause::Create(
1094*2c75bda4Serichkeane       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1095*2c75bda4Serichkeane       Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
1096*2c75bda4Serichkeane }
1097*2c75bda4Serichkeane 
1098*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
1099*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1100*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1101*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1102*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1103*2c75bda4Serichkeane 
1104*2c75bda4Serichkeane   return OpenACCCreateClause::Create(
1105*2c75bda4Serichkeane       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1106*2c75bda4Serichkeane       Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
1107*2c75bda4Serichkeane }
1108*2c75bda4Serichkeane 
1109*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
1110*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1111*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, but we
1112*2c75bda4Serichkeane   // still have to make sure it is a pointer type.
1113*2c75bda4Serichkeane   llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1114*2c75bda4Serichkeane   llvm::erase_if(VarList, [&](Expr *E) {
1115*2c75bda4Serichkeane     return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E);
1116*2c75bda4Serichkeane   });
1117*2c75bda4Serichkeane   Clause.setVarListDetails(VarList,
1118*2c75bda4Serichkeane                            /*IsReadOnly=*/false, /*IsZero=*/false);
1119*2c75bda4Serichkeane   return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(),
1120*2c75bda4Serichkeane                                      Clause.getLParenLoc(), Clause.getVarList(),
1121*2c75bda4Serichkeane                                      Clause.getEndLoc());
1122*2c75bda4Serichkeane }
1123*2c75bda4Serichkeane 
1124*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(
1125*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1126*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, but we
1127*2c75bda4Serichkeane   // still have to make sure it is a pointer type.
1128*2c75bda4Serichkeane   llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1129*2c75bda4Serichkeane   llvm::erase_if(VarList, [&](Expr *E) {
1130*2c75bda4Serichkeane     return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E);
1131*2c75bda4Serichkeane   });
1132*2c75bda4Serichkeane   Clause.setVarListDetails(VarList,
1133*2c75bda4Serichkeane                            /*IsReadOnly=*/false, /*IsZero=*/false);
1134*2c75bda4Serichkeane   return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(),
1135*2c75bda4Serichkeane                                      Clause.getLParenLoc(), Clause.getVarList(),
1136*2c75bda4Serichkeane                                      Clause.getEndLoc());
1137*2c75bda4Serichkeane }
1138*2c75bda4Serichkeane 
1139*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(
1140*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1141*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, so there
1142*2c75bda4Serichkeane   // really isn't anything to do here. GCC does some duplicate-finding, though
1143*2c75bda4Serichkeane   // it isn't apparent in the standard where this is justified.
1144*2c75bda4Serichkeane   return OpenACCDeleteClause::Create(Ctx, Clause.getBeginLoc(),
1145*2c75bda4Serichkeane                                      Clause.getLParenLoc(), Clause.getVarList(),
1146*2c75bda4Serichkeane                                      Clause.getEndLoc());
1147*2c75bda4Serichkeane }
1148*2c75bda4Serichkeane 
1149*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause(
1150*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1151*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable or array, so nothing
1152*2c75bda4Serichkeane   // left to do here.
1153*2c75bda4Serichkeane   return OpenACCUseDeviceClause::Create(
1154*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1155*2c75bda4Serichkeane       Clause.getEndLoc());
1156*2c75bda4Serichkeane }
1157*2c75bda4Serichkeane 
1158*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
1159*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1160*2c75bda4Serichkeane   // Restrictions only properly implemented on 'compute'/'combined'/'data'
1161*2c75bda4Serichkeane   // constructs, and 'compute'/'combined'/'data' constructs are the only
1162*2c75bda4Serichkeane   // construct that can do anything with this yet, so skip/treat as
1163*2c75bda4Serichkeane   // unimplemented in this case.
1164*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1165*2c75bda4Serichkeane     return isNotImplemented();
1166*2c75bda4Serichkeane 
1167*2c75bda4Serichkeane   // ActOnVar ensured that everything is a valid variable reference, but we
1168*2c75bda4Serichkeane   // still have to make sure it is a pointer type.
1169*2c75bda4Serichkeane   llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
1170*2c75bda4Serichkeane   llvm::erase_if(VarList, [&](Expr *E) {
1171*2c75bda4Serichkeane     return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E);
1172*2c75bda4Serichkeane   });
1173*2c75bda4Serichkeane   Clause.setVarListDetails(VarList,
1174*2c75bda4Serichkeane                            /*IsReadOnly=*/false, /*IsZero=*/false);
1175*2c75bda4Serichkeane 
1176*2c75bda4Serichkeane   return OpenACCDevicePtrClause::Create(
1177*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
1178*2c75bda4Serichkeane       Clause.getEndLoc());
1179*2c75bda4Serichkeane }
1180*2c75bda4Serichkeane 
1181*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
1182*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1183*2c75bda4Serichkeane   return OpenACCWaitClause::Create(
1184*2c75bda4Serichkeane       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(),
1185*2c75bda4Serichkeane       Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc());
1186*2c75bda4Serichkeane }
1187*2c75bda4Serichkeane 
1188*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
1189*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1190*2c75bda4Serichkeane   // Restrictions implemented properly on everything except 'routine'.
1191*2c75bda4Serichkeane   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
1192*2c75bda4Serichkeane     return isNotImplemented();
1193*2c75bda4Serichkeane 
1194*2c75bda4Serichkeane   // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the
1195*2c75bda4Serichkeane   // same directive.
1196*2c75bda4Serichkeane   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&
1197*2c75bda4Serichkeane       checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1198*2c75bda4Serichkeane     return nullptr;
1199*2c75bda4Serichkeane 
1200*2c75bda4Serichkeane   // TODO OpenACC: Once we get enough of the CodeGen implemented that we have
1201*2c75bda4Serichkeane   // a source for the list of valid architectures, we need to warn on unknown
1202*2c75bda4Serichkeane   // identifiers here.
1203*2c75bda4Serichkeane 
1204*2c75bda4Serichkeane   return OpenACCDeviceTypeClause::Create(
1205*2c75bda4Serichkeane       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
1206*2c75bda4Serichkeane       Clause.getDeviceTypeArchitectures(), Clause.getEndLoc());
1207*2c75bda4Serichkeane }
1208*2c75bda4Serichkeane 
1209*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(
1210*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1211*2c75bda4Serichkeane   // OpenACC 3.3 2.9:
1212*2c75bda4Serichkeane   // Only one of the seq, independent, and auto clauses may appear.
1213*2c75bda4Serichkeane   const auto *Itr =
1214*2c75bda4Serichkeane       llvm::find_if(ExistingClauses,
1215*2c75bda4Serichkeane                     llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
1216*2c75bda4Serichkeane   if (Itr != ExistingClauses.end()) {
1217*2c75bda4Serichkeane     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1218*2c75bda4Serichkeane         << Clause.getClauseKind() << Clause.getDirectiveKind();
1219*2c75bda4Serichkeane     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1220*2c75bda4Serichkeane     return nullptr;
1221*2c75bda4Serichkeane   }
1222*2c75bda4Serichkeane 
1223*2c75bda4Serichkeane   return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(),
1224*2c75bda4Serichkeane                                    Clause.getEndLoc());
1225*2c75bda4Serichkeane }
1226*2c75bda4Serichkeane 
1227*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
1228*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1229*2c75bda4Serichkeane   // OpenACC 3.3 2.9:
1230*2c75bda4Serichkeane   // Only one of the seq, independent, and auto clauses may appear.
1231*2c75bda4Serichkeane   const auto *Itr = llvm::find_if(
1232*2c75bda4Serichkeane       ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
1233*2c75bda4Serichkeane   if (Itr != ExistingClauses.end()) {
1234*2c75bda4Serichkeane     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1235*2c75bda4Serichkeane         << Clause.getClauseKind() << Clause.getDirectiveKind();
1236*2c75bda4Serichkeane     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1237*2c75bda4Serichkeane     return nullptr;
1238*2c75bda4Serichkeane   }
1239*2c75bda4Serichkeane 
1240*2c75bda4Serichkeane   return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(),
1241*2c75bda4Serichkeane                                           Clause.getEndLoc());
1242*2c75bda4Serichkeane }
1243*2c75bda4Serichkeane 
1244*2c75bda4Serichkeane ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) {
1245*2c75bda4Serichkeane   if (isa<OpenACCAsteriskSizeExpr>(E))
1246*2c75bda4Serichkeane     return E;
1247*2c75bda4Serichkeane   return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1248*2c75bda4Serichkeane                         E->getBeginLoc(), E);
1249*2c75bda4Serichkeane }
1250*2c75bda4Serichkeane 
1251*2c75bda4Serichkeane bool IsOrphanLoop(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) {
1252*2c75bda4Serichkeane   return DK == OpenACCDirectiveKind::Loop &&
1253*2c75bda4Serichkeane          AssocKind == OpenACCDirectiveKind::Invalid;
1254*2c75bda4Serichkeane }
1255*2c75bda4Serichkeane 
1256*2c75bda4Serichkeane bool HasAssocKind(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) {
1257*2c75bda4Serichkeane   return DK == OpenACCDirectiveKind::Loop &&
1258*2c75bda4Serichkeane          AssocKind != OpenACCDirectiveKind::Invalid;
1259*2c75bda4Serichkeane }
1260*2c75bda4Serichkeane 
1261*2c75bda4Serichkeane ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK,
1262*2c75bda4Serichkeane                              OpenACCClauseKind CK, OpenACCDirectiveKind DK,
1263*2c75bda4Serichkeane                              OpenACCDirectiveKind AssocKind) {
1264*2c75bda4Serichkeane   S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1265*2c75bda4Serichkeane       << GK << CK << IsOrphanLoop(DK, AssocKind) << DK
1266*2c75bda4Serichkeane       << HasAssocKind(DK, AssocKind) << AssocKind;
1267*2c75bda4Serichkeane   return ExprError();
1268*2c75bda4Serichkeane }
1269*2c75bda4Serichkeane ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind,
1270*2c75bda4Serichkeane                              OpenACCClauseKind CK, OpenACCDirectiveKind DK,
1271*2c75bda4Serichkeane                              OpenACCDirectiveKind AssocKind) {
1272*2c75bda4Serichkeane   S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
1273*2c75bda4Serichkeane       << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK
1274*2c75bda4Serichkeane       << HasAssocKind(DK, AssocKind) << AssocKind;
1275*2c75bda4Serichkeane   return ExprError();
1276*2c75bda4Serichkeane }
1277*2c75bda4Serichkeane 
1278*2c75bda4Serichkeane ExprResult CheckGangParallelExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
1279*2c75bda4Serichkeane                                  OpenACCDirectiveKind AssocKind,
1280*2c75bda4Serichkeane                                  OpenACCGangKind GK, Expr *E) {
1281*2c75bda4Serichkeane   switch (GK) {
1282*2c75bda4Serichkeane   case OpenACCGangKind::Static:
1283*2c75bda4Serichkeane     return CheckGangStaticExpr(S, E);
1284*2c75bda4Serichkeane   case OpenACCGangKind::Num:
1285*2c75bda4Serichkeane     // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel
1286*2c75bda4Serichkeane     // construct, or an orphaned loop construct, the gang clause behaves as
1287*2c75bda4Serichkeane     // follows. ... The num argument is not allowed.
1288*2c75bda4Serichkeane     return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1289*2c75bda4Serichkeane   case OpenACCGangKind::Dim: {
1290*2c75bda4Serichkeane     // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel
1291*2c75bda4Serichkeane     // construct, or an orphaned loop construct, the gang clause behaves as
1292*2c75bda4Serichkeane     // follows. ... The dim argument must be a constant positive integer value
1293*2c75bda4Serichkeane     // 1, 2, or 3.
1294*2c75bda4Serichkeane     if (!E)
1295*2c75bda4Serichkeane       return ExprError();
1296*2c75bda4Serichkeane     ExprResult Res =
1297*2c75bda4Serichkeane         S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,
1298*2c75bda4Serichkeane                        E->getBeginLoc(), E);
1299*2c75bda4Serichkeane 
1300*2c75bda4Serichkeane     if (!Res.isUsable())
1301*2c75bda4Serichkeane       return Res;
1302*2c75bda4Serichkeane 
1303*2c75bda4Serichkeane     if (Res.get()->isInstantiationDependent())
1304*2c75bda4Serichkeane       return Res;
1305*2c75bda4Serichkeane 
1306*2c75bda4Serichkeane     std::optional<llvm::APSInt> ICE =
1307*2c75bda4Serichkeane         Res.get()->getIntegerConstantExpr(S.getASTContext());
1308*2c75bda4Serichkeane 
1309*2c75bda4Serichkeane     if (!ICE || *ICE <= 0 || ICE > 3) {
1310*2c75bda4Serichkeane       S.Diag(Res.get()->getBeginLoc(), diag::err_acc_gang_dim_value)
1311*2c75bda4Serichkeane           << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
1312*2c75bda4Serichkeane       return ExprError();
1313*2c75bda4Serichkeane     }
1314*2c75bda4Serichkeane 
1315*2c75bda4Serichkeane     return ExprResult{
1316*2c75bda4Serichkeane         ConstantExpr::Create(S.getASTContext(), Res.get(), APValue{*ICE})};
1317*2c75bda4Serichkeane   }
1318*2c75bda4Serichkeane   }
1319*2c75bda4Serichkeane   llvm_unreachable("Unknown gang kind in gang parallel check");
1320*2c75bda4Serichkeane }
1321*2c75bda4Serichkeane 
1322*2c75bda4Serichkeane ExprResult CheckGangKernelsExpr(SemaOpenACC &S,
1323*2c75bda4Serichkeane                                 ArrayRef<const OpenACCClause *> ExistingClauses,
1324*2c75bda4Serichkeane                                 OpenACCDirectiveKind DK,
1325*2c75bda4Serichkeane                                 OpenACCDirectiveKind AssocKind,
1326*2c75bda4Serichkeane                                 OpenACCGangKind GK, Expr *E) {
1327*2c75bda4Serichkeane   switch (GK) {
1328*2c75bda4Serichkeane   // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1329*2c75bda4Serichkeane   // construct, the gang clause behaves as follows. ... The dim argument is
1330*2c75bda4Serichkeane   // not allowed.
1331*2c75bda4Serichkeane   case OpenACCGangKind::Dim:
1332*2c75bda4Serichkeane     return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1333*2c75bda4Serichkeane   case OpenACCGangKind::Num: {
1334*2c75bda4Serichkeane     // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1335*2c75bda4Serichkeane     // construct, the gang clause behaves as follows. ... An argument with no
1336*2c75bda4Serichkeane     // keyword or with num keyword is only allowed when num_gangs does not
1337*2c75bda4Serichkeane     // appear on the kernels construct. ... The region of a loop with the gang
1338*2c75bda4Serichkeane     // clause may not contain another loop with a gang clause unless within a
1339*2c75bda4Serichkeane     // nested compute region.
1340*2c75bda4Serichkeane 
1341*2c75bda4Serichkeane     // If this is a 'combined' construct, search the list of existing clauses.
1342*2c75bda4Serichkeane     // Else we need to search the containing 'kernel'.
1343*2c75bda4Serichkeane     auto Collection = isOpenACCCombinedDirectiveKind(DK)
1344*2c75bda4Serichkeane                           ? ExistingClauses
1345*2c75bda4Serichkeane                           : S.getActiveComputeConstructInfo().Clauses;
1346*2c75bda4Serichkeane 
1347*2c75bda4Serichkeane     const auto *Itr =
1348*2c75bda4Serichkeane         llvm::find_if(Collection, llvm::IsaPred<OpenACCNumGangsClause>);
1349*2c75bda4Serichkeane 
1350*2c75bda4Serichkeane     if (Itr != Collection.end()) {
1351*2c75bda4Serichkeane       S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict)
1352*2c75bda4Serichkeane           << "num" << OpenACCClauseKind::Gang << DK
1353*2c75bda4Serichkeane           << HasAssocKind(DK, AssocKind) << AssocKind
1354*2c75bda4Serichkeane           << OpenACCClauseKind::NumGangs;
1355*2c75bda4Serichkeane 
1356*2c75bda4Serichkeane       S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1357*2c75bda4Serichkeane       return ExprError();
1358*2c75bda4Serichkeane     }
1359*2c75bda4Serichkeane     return ExprResult{E};
1360*2c75bda4Serichkeane   }
1361*2c75bda4Serichkeane   case OpenACCGangKind::Static:
1362*2c75bda4Serichkeane     return CheckGangStaticExpr(S, E);
1363*2c75bda4Serichkeane   }
1364*2c75bda4Serichkeane   llvm_unreachable("Unknown gang kind in gang kernels check");
1365*2c75bda4Serichkeane }
1366*2c75bda4Serichkeane 
1367*2c75bda4Serichkeane ExprResult CheckGangSerialExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
1368*2c75bda4Serichkeane                                OpenACCDirectiveKind AssocKind,
1369*2c75bda4Serichkeane                                OpenACCGangKind GK, Expr *E) {
1370*2c75bda4Serichkeane   switch (GK) {
1371*2c75bda4Serichkeane   // 'dim' and 'num' don't really make sense on serial, and GCC rejects them
1372*2c75bda4Serichkeane   // too, so we disallow them too.
1373*2c75bda4Serichkeane   case OpenACCGangKind::Dim:
1374*2c75bda4Serichkeane   case OpenACCGangKind::Num:
1375*2c75bda4Serichkeane     return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);
1376*2c75bda4Serichkeane   case OpenACCGangKind::Static:
1377*2c75bda4Serichkeane     return CheckGangStaticExpr(S, E);
1378*2c75bda4Serichkeane   }
1379*2c75bda4Serichkeane   llvm_unreachable("Unknown gang kind in gang serial check");
1380*2c75bda4Serichkeane }
1381*2c75bda4Serichkeane 
1382*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(
1383*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1384*2c75bda4Serichkeane   if (DiagIfSeqClause(Clause))
1385*2c75bda4Serichkeane     return nullptr;
1386*2c75bda4Serichkeane 
1387*2c75bda4Serichkeane   // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1388*2c75bda4Serichkeane   // it is the only construct that can do anything with this, so skip/treat as
1389*2c75bda4Serichkeane   // unimplemented for the routine constructs.
1390*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1391*2c75bda4Serichkeane     return isNotImplemented();
1392*2c75bda4Serichkeane 
1393*2c75bda4Serichkeane   Expr *IntExpr =
1394*2c75bda4Serichkeane       Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
1395*2c75bda4Serichkeane   if (IntExpr) {
1396*2c75bda4Serichkeane     if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1397*2c75bda4Serichkeane       switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1398*2c75bda4Serichkeane       case OpenACCDirectiveKind::Invalid:
1399*2c75bda4Serichkeane       case OpenACCDirectiveKind::Parallel:
1400*2c75bda4Serichkeane         // No restriction on when 'parallel' can contain an argument.
1401*2c75bda4Serichkeane         break;
1402*2c75bda4Serichkeane       case OpenACCDirectiveKind::Serial:
1403*2c75bda4Serichkeane         // GCC disallows this, and there is no real good reason for us to permit
1404*2c75bda4Serichkeane         // it, so disallow until we come up with a use case that makes sense.
1405*2c75bda4Serichkeane         DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1406*2c75bda4Serichkeane                           Clause.getDirectiveKind(),
1407*2c75bda4Serichkeane                           SemaRef.getActiveComputeConstructInfo().Kind);
1408*2c75bda4Serichkeane         IntExpr = nullptr;
1409*2c75bda4Serichkeane         break;
1410*2c75bda4Serichkeane       case OpenACCDirectiveKind::Kernels: {
1411*2c75bda4Serichkeane         const auto *Itr =
1412*2c75bda4Serichkeane             llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1413*2c75bda4Serichkeane                           llvm::IsaPred<OpenACCVectorLengthClause>);
1414*2c75bda4Serichkeane         if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1415*2c75bda4Serichkeane           SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1416*2c75bda4Serichkeane               << "length" << OpenACCClauseKind::Vector
1417*2c75bda4Serichkeane               << Clause.getDirectiveKind()
1418*2c75bda4Serichkeane               << HasAssocKind(Clause.getDirectiveKind(),
1419*2c75bda4Serichkeane                               SemaRef.getActiveComputeConstructInfo().Kind)
1420*2c75bda4Serichkeane               << SemaRef.getActiveComputeConstructInfo().Kind
1421*2c75bda4Serichkeane               << OpenACCClauseKind::VectorLength;
1422*2c75bda4Serichkeane           SemaRef.Diag((*Itr)->getBeginLoc(),
1423*2c75bda4Serichkeane                        diag::note_acc_previous_clause_here);
1424*2c75bda4Serichkeane 
1425*2c75bda4Serichkeane           IntExpr = nullptr;
1426*2c75bda4Serichkeane         }
1427*2c75bda4Serichkeane         break;
1428*2c75bda4Serichkeane       }
1429*2c75bda4Serichkeane       default:
1430*2c75bda4Serichkeane         llvm_unreachable("Non compute construct in active compute construct");
1431*2c75bda4Serichkeane       }
1432*2c75bda4Serichkeane     } else {
1433*2c75bda4Serichkeane       if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1434*2c75bda4Serichkeane         DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,
1435*2c75bda4Serichkeane                           Clause.getDirectiveKind(),
1436*2c75bda4Serichkeane                           SemaRef.getActiveComputeConstructInfo().Kind);
1437*2c75bda4Serichkeane         IntExpr = nullptr;
1438*2c75bda4Serichkeane       } else if (Clause.getDirectiveKind() ==
1439*2c75bda4Serichkeane                  OpenACCDirectiveKind::KernelsLoop) {
1440*2c75bda4Serichkeane         const auto *Itr = llvm::find_if(
1441*2c75bda4Serichkeane             ExistingClauses, llvm::IsaPred<OpenACCVectorLengthClause>);
1442*2c75bda4Serichkeane         if (Itr != ExistingClauses.end()) {
1443*2c75bda4Serichkeane           SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1444*2c75bda4Serichkeane               << "length" << OpenACCClauseKind::Vector
1445*2c75bda4Serichkeane               << Clause.getDirectiveKind()
1446*2c75bda4Serichkeane               << HasAssocKind(Clause.getDirectiveKind(),
1447*2c75bda4Serichkeane                               SemaRef.getActiveComputeConstructInfo().Kind)
1448*2c75bda4Serichkeane               << SemaRef.getActiveComputeConstructInfo().Kind
1449*2c75bda4Serichkeane               << OpenACCClauseKind::VectorLength;
1450*2c75bda4Serichkeane           SemaRef.Diag((*Itr)->getBeginLoc(),
1451*2c75bda4Serichkeane                        diag::note_acc_previous_clause_here);
1452*2c75bda4Serichkeane 
1453*2c75bda4Serichkeane           IntExpr = nullptr;
1454*2c75bda4Serichkeane         }
1455*2c75bda4Serichkeane       }
1456*2c75bda4Serichkeane     }
1457*2c75bda4Serichkeane   }
1458*2c75bda4Serichkeane 
1459*2c75bda4Serichkeane   if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1460*2c75bda4Serichkeane     // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1461*2c75bda4Serichkeane     // contain a loop with a gang, worker, or vector clause unless within a
1462*2c75bda4Serichkeane     // nested compute region.
1463*2c75bda4Serichkeane     if (SemaRef.LoopVectorClauseLoc.isValid()) {
1464*2c75bda4Serichkeane       // This handles the 'inner loop' diagnostic, but we cannot set that we're
1465*2c75bda4Serichkeane       // on one of these until we get to the end of the construct.
1466*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1467*2c75bda4Serichkeane           << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1468*2c75bda4Serichkeane           << /*skip kernels construct info*/ 0;
1469*2c75bda4Serichkeane       SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1470*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
1471*2c75bda4Serichkeane       return nullptr;
1472*2c75bda4Serichkeane     }
1473*2c75bda4Serichkeane   }
1474*2c75bda4Serichkeane 
1475*2c75bda4Serichkeane   return OpenACCVectorClause::Create(Ctx, Clause.getBeginLoc(),
1476*2c75bda4Serichkeane                                      Clause.getLParenLoc(), IntExpr,
1477*2c75bda4Serichkeane                                      Clause.getEndLoc());
1478*2c75bda4Serichkeane }
1479*2c75bda4Serichkeane 
1480*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
1481*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1482*2c75bda4Serichkeane   if (DiagIfSeqClause(Clause))
1483*2c75bda4Serichkeane     return nullptr;
1484*2c75bda4Serichkeane 
1485*2c75bda4Serichkeane   // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1486*2c75bda4Serichkeane   // it is the only construct that can do anything with this, so skip/treat as
1487*2c75bda4Serichkeane   // unimplemented for the routine constructs.
1488*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1489*2c75bda4Serichkeane     return isNotImplemented();
1490*2c75bda4Serichkeane 
1491*2c75bda4Serichkeane   Expr *IntExpr =
1492*2c75bda4Serichkeane       Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;
1493*2c75bda4Serichkeane 
1494*2c75bda4Serichkeane   if (IntExpr) {
1495*2c75bda4Serichkeane     if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1496*2c75bda4Serichkeane       switch (SemaRef.getActiveComputeConstructInfo().Kind) {
1497*2c75bda4Serichkeane       case OpenACCDirectiveKind::Invalid:
1498*2c75bda4Serichkeane       case OpenACCDirectiveKind::ParallelLoop:
1499*2c75bda4Serichkeane       case OpenACCDirectiveKind::SerialLoop:
1500*2c75bda4Serichkeane       case OpenACCDirectiveKind::Parallel:
1501*2c75bda4Serichkeane       case OpenACCDirectiveKind::Serial:
1502*2c75bda4Serichkeane         DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1503*2c75bda4Serichkeane                           OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1504*2c75bda4Serichkeane                           SemaRef.getActiveComputeConstructInfo().Kind);
1505*2c75bda4Serichkeane         IntExpr = nullptr;
1506*2c75bda4Serichkeane         break;
1507*2c75bda4Serichkeane       case OpenACCDirectiveKind::KernelsLoop:
1508*2c75bda4Serichkeane       case OpenACCDirectiveKind::Kernels: {
1509*2c75bda4Serichkeane         const auto *Itr =
1510*2c75bda4Serichkeane             llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
1511*2c75bda4Serichkeane                           llvm::IsaPred<OpenACCNumWorkersClause>);
1512*2c75bda4Serichkeane         if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
1513*2c75bda4Serichkeane           SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1514*2c75bda4Serichkeane               << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1515*2c75bda4Serichkeane               << HasAssocKind(Clause.getDirectiveKind(),
1516*2c75bda4Serichkeane                               SemaRef.getActiveComputeConstructInfo().Kind)
1517*2c75bda4Serichkeane               << SemaRef.getActiveComputeConstructInfo().Kind
1518*2c75bda4Serichkeane               << OpenACCClauseKind::NumWorkers;
1519*2c75bda4Serichkeane           SemaRef.Diag((*Itr)->getBeginLoc(),
1520*2c75bda4Serichkeane                        diag::note_acc_previous_clause_here);
1521*2c75bda4Serichkeane 
1522*2c75bda4Serichkeane           IntExpr = nullptr;
1523*2c75bda4Serichkeane         }
1524*2c75bda4Serichkeane         break;
1525*2c75bda4Serichkeane       }
1526*2c75bda4Serichkeane       default:
1527*2c75bda4Serichkeane         llvm_unreachable("Non compute construct in active compute construct");
1528*2c75bda4Serichkeane       }
1529*2c75bda4Serichkeane     } else {
1530*2c75bda4Serichkeane       if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop ||
1531*2c75bda4Serichkeane           Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {
1532*2c75bda4Serichkeane         DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,
1533*2c75bda4Serichkeane                           OpenACCClauseKind::Worker, Clause.getDirectiveKind(),
1534*2c75bda4Serichkeane                           SemaRef.getActiveComputeConstructInfo().Kind);
1535*2c75bda4Serichkeane         IntExpr = nullptr;
1536*2c75bda4Serichkeane       } else {
1537*2c75bda4Serichkeane         assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop &&
1538*2c75bda4Serichkeane                "Unknown combined directive kind?");
1539*2c75bda4Serichkeane         const auto *Itr = llvm::find_if(ExistingClauses,
1540*2c75bda4Serichkeane                                         llvm::IsaPred<OpenACCNumWorkersClause>);
1541*2c75bda4Serichkeane         if (Itr != ExistingClauses.end()) {
1542*2c75bda4Serichkeane           SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
1543*2c75bda4Serichkeane               << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()
1544*2c75bda4Serichkeane               << HasAssocKind(Clause.getDirectiveKind(),
1545*2c75bda4Serichkeane                               SemaRef.getActiveComputeConstructInfo().Kind)
1546*2c75bda4Serichkeane               << SemaRef.getActiveComputeConstructInfo().Kind
1547*2c75bda4Serichkeane               << OpenACCClauseKind::NumWorkers;
1548*2c75bda4Serichkeane           SemaRef.Diag((*Itr)->getBeginLoc(),
1549*2c75bda4Serichkeane                        diag::note_acc_previous_clause_here);
1550*2c75bda4Serichkeane 
1551*2c75bda4Serichkeane           IntExpr = nullptr;
1552*2c75bda4Serichkeane         }
1553*2c75bda4Serichkeane       }
1554*2c75bda4Serichkeane     }
1555*2c75bda4Serichkeane   }
1556*2c75bda4Serichkeane 
1557*2c75bda4Serichkeane   if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1558*2c75bda4Serichkeane     // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1559*2c75bda4Serichkeane     // contain a loop with a gang or worker clause unless within a nested
1560*2c75bda4Serichkeane     // compute region.
1561*2c75bda4Serichkeane     if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1562*2c75bda4Serichkeane       // This handles the 'inner loop' diagnostic, but we cannot set that we're
1563*2c75bda4Serichkeane       // on one of these until we get to the end of the construct.
1564*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1565*2c75bda4Serichkeane           << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
1566*2c75bda4Serichkeane           << /*skip kernels construct info*/ 0;
1567*2c75bda4Serichkeane       SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1568*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
1569*2c75bda4Serichkeane       return nullptr;
1570*2c75bda4Serichkeane     }
1571*2c75bda4Serichkeane 
1572*2c75bda4Serichkeane     // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1573*2c75bda4Serichkeane     // contain a loop with a gang, worker, or vector clause unless within a
1574*2c75bda4Serichkeane     // nested compute region.
1575*2c75bda4Serichkeane     if (SemaRef.LoopVectorClauseLoc.isValid()) {
1576*2c75bda4Serichkeane       // This handles the 'inner loop' diagnostic, but we cannot set that we're
1577*2c75bda4Serichkeane       // on one of these until we get to the end of the construct.
1578*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1579*2c75bda4Serichkeane           << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector
1580*2c75bda4Serichkeane           << /*skip kernels construct info*/ 0;
1581*2c75bda4Serichkeane       SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1582*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
1583*2c75bda4Serichkeane       return nullptr;
1584*2c75bda4Serichkeane     }
1585*2c75bda4Serichkeane   }
1586*2c75bda4Serichkeane 
1587*2c75bda4Serichkeane   return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(),
1588*2c75bda4Serichkeane                                      Clause.getLParenLoc(), IntExpr,
1589*2c75bda4Serichkeane                                      Clause.getEndLoc());
1590*2c75bda4Serichkeane }
1591*2c75bda4Serichkeane 
1592*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
1593*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1594*2c75bda4Serichkeane   if (DiagIfSeqClause(Clause))
1595*2c75bda4Serichkeane     return nullptr;
1596*2c75bda4Serichkeane 
1597*2c75bda4Serichkeane   // Restrictions only properly implemented on 'loop' constructs, and it is
1598*2c75bda4Serichkeane   // the only construct that can do anything with this, so skip/treat as
1599*2c75bda4Serichkeane   // unimplemented for the combined constructs.
1600*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1601*2c75bda4Serichkeane     return isNotImplemented();
1602*2c75bda4Serichkeane 
1603*2c75bda4Serichkeane   // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
1604*2c75bda4Serichkeane   // directive that has a gang clause and is within a compute construct that has
1605*2c75bda4Serichkeane   // a num_gangs clause with more than one explicit argument.
1606*2c75bda4Serichkeane   if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1607*2c75bda4Serichkeane        SemaRef.getActiveComputeConstructInfo().Kind !=
1608*2c75bda4Serichkeane            OpenACCDirectiveKind::Invalid) ||
1609*2c75bda4Serichkeane       isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1610*2c75bda4Serichkeane     // num_gangs clause on the active compute construct.
1611*2c75bda4Serichkeane     auto ActiveComputeConstructContainer =
1612*2c75bda4Serichkeane         isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())
1613*2c75bda4Serichkeane             ? ExistingClauses
1614*2c75bda4Serichkeane             : SemaRef.getActiveComputeConstructInfo().Clauses;
1615*2c75bda4Serichkeane     auto *NumGangsClauseItr = llvm::find_if(
1616*2c75bda4Serichkeane         ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>);
1617*2c75bda4Serichkeane 
1618*2c75bda4Serichkeane     if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1619*2c75bda4Serichkeane         cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() >
1620*2c75bda4Serichkeane             1) {
1621*2c75bda4Serichkeane       auto *ReductionClauseItr =
1622*2c75bda4Serichkeane           llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
1623*2c75bda4Serichkeane 
1624*2c75bda4Serichkeane       if (ReductionClauseItr != ExistingClauses.end()) {
1625*2c75bda4Serichkeane         SemaRef.Diag(Clause.getBeginLoc(),
1626*2c75bda4Serichkeane                      diag::err_acc_gang_reduction_numgangs_conflict)
1627*2c75bda4Serichkeane             << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction
1628*2c75bda4Serichkeane             << Clause.getDirectiveKind()
1629*2c75bda4Serichkeane             << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind());
1630*2c75bda4Serichkeane         SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),
1631*2c75bda4Serichkeane                      diag::note_acc_previous_clause_here);
1632*2c75bda4Serichkeane         SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1633*2c75bda4Serichkeane                      diag::note_acc_previous_clause_here);
1634*2c75bda4Serichkeane         return nullptr;
1635*2c75bda4Serichkeane       }
1636*2c75bda4Serichkeane     }
1637*2c75bda4Serichkeane   }
1638*2c75bda4Serichkeane 
1639*2c75bda4Serichkeane   llvm::SmallVector<OpenACCGangKind> GangKinds;
1640*2c75bda4Serichkeane   llvm::SmallVector<Expr *> IntExprs;
1641*2c75bda4Serichkeane 
1642*2c75bda4Serichkeane   // Store the existing locations, so we can do duplicate checking.  Index is
1643*2c75bda4Serichkeane   // the int-value of the OpenACCGangKind enum.
1644*2c75bda4Serichkeane   SourceLocation ExistingElemLoc[3];
1645*2c75bda4Serichkeane 
1646*2c75bda4Serichkeane   for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) {
1647*2c75bda4Serichkeane     OpenACCGangKind GK = Clause.getGangKinds()[I];
1648*2c75bda4Serichkeane     ExprResult ER =
1649*2c75bda4Serichkeane         SemaRef.CheckGangExpr(ExistingClauses, Clause.getDirectiveKind(), GK,
1650*2c75bda4Serichkeane                               Clause.getIntExprs()[I]);
1651*2c75bda4Serichkeane 
1652*2c75bda4Serichkeane     if (!ER.isUsable())
1653*2c75bda4Serichkeane       continue;
1654*2c75bda4Serichkeane 
1655*2c75bda4Serichkeane     // OpenACC 3.3 2.9: 'gang-arg-list' may have at most one num, one dim, and
1656*2c75bda4Serichkeane     // one static argument.
1657*2c75bda4Serichkeane     if (ExistingElemLoc[static_cast<unsigned>(GK)].isValid()) {
1658*2c75bda4Serichkeane       SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_gang_multiple_elt)
1659*2c75bda4Serichkeane           << static_cast<unsigned>(GK);
1660*2c75bda4Serichkeane       SemaRef.Diag(ExistingElemLoc[static_cast<unsigned>(GK)],
1661*2c75bda4Serichkeane                    diag::note_acc_previous_expr_here);
1662*2c75bda4Serichkeane       continue;
1663*2c75bda4Serichkeane     }
1664*2c75bda4Serichkeane 
1665*2c75bda4Serichkeane     ExistingElemLoc[static_cast<unsigned>(GK)] = ER.get()->getBeginLoc();
1666*2c75bda4Serichkeane     GangKinds.push_back(GK);
1667*2c75bda4Serichkeane     IntExprs.push_back(ER.get());
1668*2c75bda4Serichkeane   }
1669*2c75bda4Serichkeane 
1670*2c75bda4Serichkeane   if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1671*2c75bda4Serichkeane     // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
1672*2c75bda4Serichkeane     // construct, the gang clause behaves as follows. ... The region of a loop
1673*2c75bda4Serichkeane     // with a gang clause may not contain another loop with a gang clause unless
1674*2c75bda4Serichkeane     // within a nested compute region.
1675*2c75bda4Serichkeane     if (SemaRef.LoopGangClauseOnKernel.Loc.isValid()) {
1676*2c75bda4Serichkeane       // This handles the 'inner loop' diagnostic, but we cannot set that we're
1677*2c75bda4Serichkeane       // on one of these until we get to the end of the construct.
1678*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1679*2c75bda4Serichkeane           << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang
1680*2c75bda4Serichkeane           << /*kernels construct info*/ 1
1681*2c75bda4Serichkeane           << SemaRef.LoopGangClauseOnKernel.DirKind;
1682*2c75bda4Serichkeane       SemaRef.Diag(SemaRef.LoopGangClauseOnKernel.Loc,
1683*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
1684*2c75bda4Serichkeane       return nullptr;
1685*2c75bda4Serichkeane     }
1686*2c75bda4Serichkeane 
1687*2c75bda4Serichkeane     // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
1688*2c75bda4Serichkeane     // contain a loop with a gang or worker clause unless within a nested
1689*2c75bda4Serichkeane     // compute region.
1690*2c75bda4Serichkeane     if (SemaRef.LoopWorkerClauseLoc.isValid()) {
1691*2c75bda4Serichkeane       // This handles the 'inner loop' diagnostic, but we cannot set that we're
1692*2c75bda4Serichkeane       // on one of these until we get to the end of the construct.
1693*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1694*2c75bda4Serichkeane           << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker
1695*2c75bda4Serichkeane           << /*!kernels construct info*/ 0;
1696*2c75bda4Serichkeane       SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
1697*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
1698*2c75bda4Serichkeane       return nullptr;
1699*2c75bda4Serichkeane     }
1700*2c75bda4Serichkeane 
1701*2c75bda4Serichkeane     // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1702*2c75bda4Serichkeane     // contain a loop with a gang, worker, or vector clause unless within a
1703*2c75bda4Serichkeane     // nested compute region.
1704*2c75bda4Serichkeane     if (SemaRef.LoopVectorClauseLoc.isValid()) {
1705*2c75bda4Serichkeane       // This handles the 'inner loop' diagnostic, but we cannot set that we're
1706*2c75bda4Serichkeane       // on one of these until we get to the end of the construct.
1707*2c75bda4Serichkeane       SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
1708*2c75bda4Serichkeane           << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector
1709*2c75bda4Serichkeane           << /*!kernels construct info*/ 0;
1710*2c75bda4Serichkeane       SemaRef.Diag(SemaRef.LoopVectorClauseLoc,
1711*2c75bda4Serichkeane                    diag::note_acc_previous_clause_here);
1712*2c75bda4Serichkeane       return nullptr;
1713*2c75bda4Serichkeane     }
1714*2c75bda4Serichkeane   }
1715*2c75bda4Serichkeane 
1716*2c75bda4Serichkeane   return SemaRef.CheckGangClause(Clause.getDirectiveKind(), ExistingClauses,
1717*2c75bda4Serichkeane                                  Clause.getBeginLoc(), Clause.getLParenLoc(),
1718*2c75bda4Serichkeane                                  GangKinds, IntExprs, Clause.getEndLoc());
1719*2c75bda4Serichkeane }
1720*2c75bda4Serichkeane 
1721*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(
1722*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1723*2c75bda4Serichkeane   // There isn't anything to do here, this is only valid on one construct, and
1724*2c75bda4Serichkeane   // has no associated rules.
1725*2c75bda4Serichkeane   return OpenACCFinalizeClause::Create(Ctx, Clause.getBeginLoc(),
1726*2c75bda4Serichkeane                                        Clause.getEndLoc());
1727*2c75bda4Serichkeane }
1728*2c75bda4Serichkeane 
1729*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
1730*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1731*2c75bda4Serichkeane   // There isn't anything to do here, this is only valid on one construct, and
1732*2c75bda4Serichkeane   // has no associated rules.
1733*2c75bda4Serichkeane   return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(),
1734*2c75bda4Serichkeane                                         Clause.getEndLoc());
1735*2c75bda4Serichkeane }
1736*2c75bda4Serichkeane 
1737*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
1738*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1739*2c75bda4Serichkeane   // Restrictions only properly implemented on 'loop' constructs and combined ,
1740*2c75bda4Serichkeane   // and it is the only construct that can do anything with this, so skip/treat
1741*2c75bda4Serichkeane   // as unimplemented for the routine constructs.
1742*2c75bda4Serichkeane   if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1743*2c75bda4Serichkeane     return isNotImplemented();
1744*2c75bda4Serichkeane 
1745*2c75bda4Serichkeane   // OpenACC 3.3 2.9:
1746*2c75bda4Serichkeane   // Only one of the seq, independent, and auto clauses may appear.
1747*2c75bda4Serichkeane   const auto *Itr =
1748*2c75bda4Serichkeane       llvm::find_if(ExistingClauses,
1749*2c75bda4Serichkeane                     llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
1750*2c75bda4Serichkeane   if (Itr != ExistingClauses.end()) {
1751*2c75bda4Serichkeane     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
1752*2c75bda4Serichkeane         << Clause.getClauseKind() << Clause.getDirectiveKind();
1753*2c75bda4Serichkeane     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1754*2c75bda4Serichkeane     return nullptr;
1755*2c75bda4Serichkeane   }
1756*2c75bda4Serichkeane 
1757*2c75bda4Serichkeane   // OpenACC 3.3 2.9:
1758*2c75bda4Serichkeane   // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
1759*2c75bda4Serichkeane   // appears.
1760*2c75bda4Serichkeane   Itr = llvm::find_if(ExistingClauses,
1761*2c75bda4Serichkeane                       llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
1762*2c75bda4Serichkeane                                     OpenACCVectorClause>);
1763*2c75bda4Serichkeane 
1764*2c75bda4Serichkeane   if (Itr != ExistingClauses.end()) {
1765*2c75bda4Serichkeane     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
1766*2c75bda4Serichkeane         << Clause.getClauseKind() << (*Itr)->getClauseKind()
1767*2c75bda4Serichkeane         << Clause.getDirectiveKind();
1768*2c75bda4Serichkeane     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1769*2c75bda4Serichkeane     return nullptr;
1770*2c75bda4Serichkeane   }
1771*2c75bda4Serichkeane 
1772*2c75bda4Serichkeane   return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(),
1773*2c75bda4Serichkeane                                   Clause.getEndLoc());
1774*2c75bda4Serichkeane }
1775*2c75bda4Serichkeane 
1776*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
1777*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1778*2c75bda4Serichkeane   // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
1779*2c75bda4Serichkeane   // directive that has a gang clause and is within a compute construct that has
1780*2c75bda4Serichkeane   // a num_gangs clause with more than one explicit argument.
1781*2c75bda4Serichkeane   if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&
1782*2c75bda4Serichkeane        SemaRef.getActiveComputeConstructInfo().Kind !=
1783*2c75bda4Serichkeane            OpenACCDirectiveKind::Invalid) ||
1784*2c75bda4Serichkeane       isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) {
1785*2c75bda4Serichkeane     // num_gangs clause on the active compute construct.
1786*2c75bda4Serichkeane     auto ActiveComputeConstructContainer =
1787*2c75bda4Serichkeane         isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())
1788*2c75bda4Serichkeane             ? ExistingClauses
1789*2c75bda4Serichkeane             : SemaRef.getActiveComputeConstructInfo().Clauses;
1790*2c75bda4Serichkeane     auto *NumGangsClauseItr = llvm::find_if(
1791*2c75bda4Serichkeane         ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>);
1792*2c75bda4Serichkeane 
1793*2c75bda4Serichkeane     if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&
1794*2c75bda4Serichkeane         cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() >
1795*2c75bda4Serichkeane             1) {
1796*2c75bda4Serichkeane       auto *GangClauseItr =
1797*2c75bda4Serichkeane           llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
1798*2c75bda4Serichkeane 
1799*2c75bda4Serichkeane       if (GangClauseItr != ExistingClauses.end()) {
1800*2c75bda4Serichkeane         SemaRef.Diag(Clause.getBeginLoc(),
1801*2c75bda4Serichkeane                      diag::err_acc_gang_reduction_numgangs_conflict)
1802*2c75bda4Serichkeane             << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang
1803*2c75bda4Serichkeane             << Clause.getDirectiveKind()
1804*2c75bda4Serichkeane             << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind());
1805*2c75bda4Serichkeane         SemaRef.Diag((*GangClauseItr)->getBeginLoc(),
1806*2c75bda4Serichkeane                      diag::note_acc_previous_clause_here);
1807*2c75bda4Serichkeane         SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),
1808*2c75bda4Serichkeane                      diag::note_acc_previous_clause_here);
1809*2c75bda4Serichkeane         return nullptr;
1810*2c75bda4Serichkeane       }
1811*2c75bda4Serichkeane     }
1812*2c75bda4Serichkeane   }
1813*2c75bda4Serichkeane 
1814*2c75bda4Serichkeane   // OpenACC3.3 Section 2.9.11: If a variable is involved in a reduction that
1815*2c75bda4Serichkeane   // spans multiple nested loops where two or more of those loops have
1816*2c75bda4Serichkeane   // associated loop directives, a reduction clause containing that variable
1817*2c75bda4Serichkeane   // must appear on each of those loop directives.
1818*2c75bda4Serichkeane   //
1819*2c75bda4Serichkeane   // This can't really be implemented in the CFE, as this requires a level of
1820*2c75bda4Serichkeane   // rechability/useage analysis that we're not really wanting to get into.
1821*2c75bda4Serichkeane   // Additionally, I'm alerted that this restriction is one that the middle-end
1822*2c75bda4Serichkeane   // can just 'figure out' as an extension and isn't really necessary.
1823*2c75bda4Serichkeane   //
1824*2c75bda4Serichkeane   // OpenACC3.3 Section 2.9.11: Every 'var' in a reduction clause appearing on
1825*2c75bda4Serichkeane   // an orphaned loop construct must be private.
1826*2c75bda4Serichkeane   //
1827*2c75bda4Serichkeane   // This again is something we cannot really diagnose, as it requires we see
1828*2c75bda4Serichkeane   // all the uses/scopes of all variables referenced.  The middle end/MLIR might
1829*2c75bda4Serichkeane   // be able to diagnose this.
1830*2c75bda4Serichkeane 
1831*2c75bda4Serichkeane   // OpenACC 3.3 Section 2.5.4:
1832*2c75bda4Serichkeane   // A reduction clause may not appear on a parallel construct with a
1833*2c75bda4Serichkeane   // num_gangs clause that has more than one argument.
1834*2c75bda4Serichkeane   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
1835*2c75bda4Serichkeane       Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) {
1836*2c75bda4Serichkeane     auto NumGangsClauses = llvm::make_filter_range(
1837*2c75bda4Serichkeane         ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>);
1838*2c75bda4Serichkeane 
1839*2c75bda4Serichkeane     for (auto *NGC : NumGangsClauses) {
1840*2c75bda4Serichkeane       unsigned NumExprs =
1841*2c75bda4Serichkeane           cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size();
1842*2c75bda4Serichkeane 
1843*2c75bda4Serichkeane       if (NumExprs > 1) {
1844*2c75bda4Serichkeane         SemaRef.Diag(Clause.getBeginLoc(),
1845*2c75bda4Serichkeane                      diag::err_acc_reduction_num_gangs_conflict)
1846*2c75bda4Serichkeane             << /*>1 arg in first loc=*/0 << Clause.getClauseKind()
1847*2c75bda4Serichkeane             << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs;
1848*2c75bda4Serichkeane         SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here);
1849*2c75bda4Serichkeane         return nullptr;
1850*2c75bda4Serichkeane       }
1851*2c75bda4Serichkeane     }
1852*2c75bda4Serichkeane   }
1853*2c75bda4Serichkeane 
1854*2c75bda4Serichkeane   SmallVector<Expr *> ValidVars;
1855*2c75bda4Serichkeane 
1856*2c75bda4Serichkeane   for (Expr *Var : Clause.getVarList()) {
1857*2c75bda4Serichkeane     ExprResult Res = SemaRef.CheckReductionVar(Clause.getDirectiveKind(),
1858*2c75bda4Serichkeane                                                Clause.getReductionOp(), Var);
1859*2c75bda4Serichkeane 
1860*2c75bda4Serichkeane     if (Res.isUsable())
1861*2c75bda4Serichkeane       ValidVars.push_back(Res.get());
1862*2c75bda4Serichkeane   }
1863*2c75bda4Serichkeane 
1864*2c75bda4Serichkeane   return SemaRef.CheckReductionClause(
1865*2c75bda4Serichkeane       ExistingClauses, Clause.getDirectiveKind(), Clause.getBeginLoc(),
1866*2c75bda4Serichkeane       Clause.getLParenLoc(), Clause.getReductionOp(), ValidVars,
1867*2c75bda4Serichkeane       Clause.getEndLoc());
1868*2c75bda4Serichkeane }
1869*2c75bda4Serichkeane 
1870*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(
1871*2c75bda4Serichkeane     SemaOpenACC::OpenACCParsedClause &Clause) {
1872*2c75bda4Serichkeane   // Duplicates here are not really sensible.  We could possible permit
1873*2c75bda4Serichkeane   // multiples if they all had the same value, but there isn't really a good
1874*2c75bda4Serichkeane   // reason to do so. Also, this simplifies the suppression of duplicates, in
1875*2c75bda4Serichkeane   // that we know if we 'find' one after instantiation, that it is the same
1876*2c75bda4Serichkeane   // clause, which simplifies instantiation/checking/etc.
1877*2c75bda4Serichkeane   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
1878*2c75bda4Serichkeane     return nullptr;
1879*2c75bda4Serichkeane 
1880*2c75bda4Serichkeane   ExprResult LoopCount = SemaRef.CheckCollapseLoopCount(Clause.getLoopCount());
1881*2c75bda4Serichkeane 
1882*2c75bda4Serichkeane   if (!LoopCount.isUsable())
1883*2c75bda4Serichkeane     return nullptr;
1884*2c75bda4Serichkeane 
1885*2c75bda4Serichkeane   return OpenACCCollapseClause::Create(Ctx, Clause.getBeginLoc(),
1886*2c75bda4Serichkeane                                        Clause.getLParenLoc(), Clause.isForce(),
1887*2c75bda4Serichkeane                                        LoopCount.get(), Clause.getEndLoc());
1888*2c75bda4Serichkeane }
1889*2c75bda4Serichkeane 
1890*2c75bda4Serichkeane // Return true if the two vars refer to the same variable, for the purposes of
1891*2c75bda4Serichkeane // equality checking.
1892*2c75bda4Serichkeane bool areVarsEqual(Expr *VarExpr1, Expr *VarExpr2) {
1893*2c75bda4Serichkeane   if (VarExpr1->isInstantiationDependent() ||
1894*2c75bda4Serichkeane       VarExpr2->isInstantiationDependent())
1895*2c75bda4Serichkeane     return false;
1896*2c75bda4Serichkeane 
1897*2c75bda4Serichkeane   VarExpr1 = VarExpr1->IgnoreParenCasts();
1898*2c75bda4Serichkeane   VarExpr2 = VarExpr2->IgnoreParenCasts();
1899*2c75bda4Serichkeane 
1900*2c75bda4Serichkeane   // Legal expressions can be: Scalar variable reference, sub-array, array
1901*2c75bda4Serichkeane   // element, or composite variable member.
1902*2c75bda4Serichkeane 
1903*2c75bda4Serichkeane   // Sub-array.
1904*2c75bda4Serichkeane   if (isa<ArraySectionExpr>(VarExpr1)) {
1905*2c75bda4Serichkeane     auto *Expr2AS = dyn_cast<ArraySectionExpr>(VarExpr2);
1906*2c75bda4Serichkeane     if (!Expr2AS)
1907*2c75bda4Serichkeane       return false;
1908*2c75bda4Serichkeane 
1909*2c75bda4Serichkeane     auto *Expr1AS = cast<ArraySectionExpr>(VarExpr1);
1910*2c75bda4Serichkeane 
1911*2c75bda4Serichkeane     if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
1912*2c75bda4Serichkeane       return false;
1913*2c75bda4Serichkeane     // We could possibly check to see if the ranges aren't overlapping, but it
1914*2c75bda4Serichkeane     // isn't clear that the rules allow this.
1915*2c75bda4Serichkeane     return true;
1916*2c75bda4Serichkeane   }
1917*2c75bda4Serichkeane 
1918*2c75bda4Serichkeane   // Array-element.
1919*2c75bda4Serichkeane   if (isa<ArraySubscriptExpr>(VarExpr1)) {
1920*2c75bda4Serichkeane     auto *Expr2AS = dyn_cast<ArraySubscriptExpr>(VarExpr2);
1921*2c75bda4Serichkeane     if (!Expr2AS)
1922*2c75bda4Serichkeane       return false;
1923*2c75bda4Serichkeane 
1924*2c75bda4Serichkeane     auto *Expr1AS = cast<ArraySubscriptExpr>(VarExpr1);
1925*2c75bda4Serichkeane 
1926*2c75bda4Serichkeane     if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))
1927*2c75bda4Serichkeane       return false;
1928*2c75bda4Serichkeane 
1929*2c75bda4Serichkeane     // We could possibly check to see if the elements referenced aren't the
1930*2c75bda4Serichkeane     // same, but it isn't clear by reading of the standard that this is allowed
1931*2c75bda4Serichkeane     // (and that the 'var' refered to isn't the array).
1932*2c75bda4Serichkeane     return true;
1933*2c75bda4Serichkeane   }
1934*2c75bda4Serichkeane 
1935*2c75bda4Serichkeane   // Scalar variable reference, or composite variable.
1936*2c75bda4Serichkeane   if (isa<DeclRefExpr>(VarExpr1)) {
1937*2c75bda4Serichkeane     auto *Expr2DRE = dyn_cast<DeclRefExpr>(VarExpr2);
1938*2c75bda4Serichkeane     if (!Expr2DRE)
1939*2c75bda4Serichkeane       return false;
1940*2c75bda4Serichkeane 
1941*2c75bda4Serichkeane     auto *Expr1DRE = cast<DeclRefExpr>(VarExpr1);
1942*2c75bda4Serichkeane 
1943*2c75bda4Serichkeane     return Expr1DRE->getDecl()->getMostRecentDecl() ==
1944*2c75bda4Serichkeane            Expr2DRE->getDecl()->getMostRecentDecl();
1945*2c75bda4Serichkeane   }
1946*2c75bda4Serichkeane 
1947*2c75bda4Serichkeane   llvm_unreachable("Unknown variable type encountered");
1948*2c75bda4Serichkeane }
1949*2c75bda4Serichkeane } // namespace
1950*2c75bda4Serichkeane 
1951*2c75bda4Serichkeane OpenACCClause *
1952*2c75bda4Serichkeane SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
1953*2c75bda4Serichkeane                          OpenACCParsedClause &Clause) {
1954*2c75bda4Serichkeane   if (Clause.getClauseKind() == OpenACCClauseKind::Invalid)
1955*2c75bda4Serichkeane     return nullptr;
1956*2c75bda4Serichkeane 
1957*2c75bda4Serichkeane   // Diagnose that we don't support this clause on this directive.
1958*2c75bda4Serichkeane   if (!doesClauseApplyToDirective(Clause.getDirectiveKind(),
1959*2c75bda4Serichkeane                                   Clause.getClauseKind())) {
1960*2c75bda4Serichkeane     Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)
1961*2c75bda4Serichkeane         << Clause.getDirectiveKind() << Clause.getClauseKind();
1962*2c75bda4Serichkeane     return nullptr;
1963*2c75bda4Serichkeane   }
1964*2c75bda4Serichkeane 
1965*2c75bda4Serichkeane   if (const auto *DevTypeClause =
1966*2c75bda4Serichkeane           llvm::find_if(ExistingClauses,
1967*2c75bda4Serichkeane                         [&](const OpenACCClause *C) {
1968*2c75bda4Serichkeane                           return isa<OpenACCDeviceTypeClause>(C);
1969*2c75bda4Serichkeane                         });
1970*2c75bda4Serichkeane       DevTypeClause != ExistingClauses.end()) {
1971*2c75bda4Serichkeane     if (checkValidAfterDeviceType(
1972*2c75bda4Serichkeane             *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause))
1973*2c75bda4Serichkeane       return nullptr;
1974*2c75bda4Serichkeane   }
1975*2c75bda4Serichkeane 
1976*2c75bda4Serichkeane   SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};
1977*2c75bda4Serichkeane   OpenACCClause *Result = Visitor.Visit(Clause);
1978*2c75bda4Serichkeane   assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) &&
1979*2c75bda4Serichkeane          "Created wrong clause?");
1980*2c75bda4Serichkeane 
1981*2c75bda4Serichkeane   if (Visitor.diagNotImplemented())
1982*2c75bda4Serichkeane     Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)
1983*2c75bda4Serichkeane         << Clause.getClauseKind();
1984*2c75bda4Serichkeane 
1985*2c75bda4Serichkeane   return Result;
1986*2c75bda4Serichkeane 
1987*2c75bda4Serichkeane }
1988*2c75bda4Serichkeane 
1989*2c75bda4Serichkeane /// OpenACC 3.3 section 2.5.15:
1990*2c75bda4Serichkeane /// At a mininmum, the supported data types include ... the numerical data types
1991*2c75bda4Serichkeane /// in C, C++, and Fortran.
1992*2c75bda4Serichkeane ///
1993*2c75bda4Serichkeane /// If the reduction var is a composite variable, each
1994*2c75bda4Serichkeane /// member of the composite variable must be a supported datatype for the
1995*2c75bda4Serichkeane /// reduction operation.
1996*2c75bda4Serichkeane ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
1997*2c75bda4Serichkeane                                           OpenACCReductionOperator ReductionOp,
1998*2c75bda4Serichkeane                                           Expr *VarExpr) {
1999*2c75bda4Serichkeane   VarExpr = VarExpr->IgnoreParenCasts();
2000*2c75bda4Serichkeane 
2001*2c75bda4Serichkeane   auto TypeIsValid = [](QualType Ty) {
2002*2c75bda4Serichkeane     return Ty->isDependentType() || Ty->isScalarType();
2003*2c75bda4Serichkeane   };
2004*2c75bda4Serichkeane 
2005*2c75bda4Serichkeane   if (isa<ArraySectionExpr>(VarExpr)) {
2006*2c75bda4Serichkeane     Expr *ASExpr = VarExpr;
2007*2c75bda4Serichkeane     QualType BaseTy = ArraySectionExpr::getBaseOriginalType(ASExpr);
2008*2c75bda4Serichkeane     QualType EltTy = getASTContext().getBaseElementType(BaseTy);
2009*2c75bda4Serichkeane 
2010*2c75bda4Serichkeane     if (!TypeIsValid(EltTy)) {
2011*2c75bda4Serichkeane       Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2012*2c75bda4Serichkeane           << EltTy << /*Sub array base type*/ 1;
2013*2c75bda4Serichkeane       return ExprError();
2014*2c75bda4Serichkeane     }
2015*2c75bda4Serichkeane   } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) {
2016*2c75bda4Serichkeane     if (!RD->isStruct() && !RD->isClass()) {
2017*2c75bda4Serichkeane       Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2018*2c75bda4Serichkeane           << /*not class or struct*/ 0 << VarExpr->getType();
2019*2c75bda4Serichkeane       return ExprError();
2020*2c75bda4Serichkeane     }
2021*2c75bda4Serichkeane 
2022*2c75bda4Serichkeane     if (!RD->isCompleteDefinition()) {
2023*2c75bda4Serichkeane       Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2024*2c75bda4Serichkeane           << /*incomplete*/ 1 << VarExpr->getType();
2025*2c75bda4Serichkeane       return ExprError();
2026*2c75bda4Serichkeane     }
2027*2c75bda4Serichkeane     if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
2028*2c75bda4Serichkeane         CXXRD && !CXXRD->isAggregate()) {
2029*2c75bda4Serichkeane       Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
2030*2c75bda4Serichkeane           << /*aggregate*/ 2 << VarExpr->getType();
2031*2c75bda4Serichkeane       return ExprError();
2032*2c75bda4Serichkeane     }
2033*2c75bda4Serichkeane 
2034*2c75bda4Serichkeane     for (FieldDecl *FD : RD->fields()) {
2035*2c75bda4Serichkeane       if (!TypeIsValid(FD->getType())) {
2036*2c75bda4Serichkeane         Diag(VarExpr->getExprLoc(),
2037*2c75bda4Serichkeane              diag::err_acc_reduction_composite_member_type);
2038*2c75bda4Serichkeane         Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc);
2039*2c75bda4Serichkeane         return ExprError();
2040*2c75bda4Serichkeane       }
2041*2c75bda4Serichkeane     }
2042*2c75bda4Serichkeane   } else if (!TypeIsValid(VarExpr->getType())) {
2043*2c75bda4Serichkeane     Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
2044*2c75bda4Serichkeane         << VarExpr->getType() << /*Sub array base type*/ 0;
2045*2c75bda4Serichkeane     return ExprError();
2046*2c75bda4Serichkeane   }
2047*2c75bda4Serichkeane 
2048*2c75bda4Serichkeane   // OpenACC3.3: 2.9.11: Reduction clauses on nested constructs for the same
2049*2c75bda4Serichkeane   // reduction 'var' must have the same reduction operator.
2050*2c75bda4Serichkeane   if (!VarExpr->isInstantiationDependent()) {
2051*2c75bda4Serichkeane 
2052*2c75bda4Serichkeane     for (const OpenACCReductionClause *RClause : ActiveReductionClauses) {
2053*2c75bda4Serichkeane       if (RClause->getReductionOp() == ReductionOp)
2054*2c75bda4Serichkeane         break;
2055*2c75bda4Serichkeane 
2056*2c75bda4Serichkeane       for (Expr *OldVarExpr : RClause->getVarList()) {
2057*2c75bda4Serichkeane         if (OldVarExpr->isInstantiationDependent())
2058*2c75bda4Serichkeane           continue;
2059*2c75bda4Serichkeane 
2060*2c75bda4Serichkeane         if (areVarsEqual(VarExpr, OldVarExpr)) {
2061*2c75bda4Serichkeane           Diag(VarExpr->getExprLoc(), diag::err_reduction_op_mismatch)
2062*2c75bda4Serichkeane               << ReductionOp << RClause->getReductionOp();
2063*2c75bda4Serichkeane           Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here);
2064*2c75bda4Serichkeane           return ExprError();
2065*2c75bda4Serichkeane         }
2066*2c75bda4Serichkeane       }
2067*2c75bda4Serichkeane     }
2068*2c75bda4Serichkeane   }
2069*2c75bda4Serichkeane 
2070*2c75bda4Serichkeane   return VarExpr;
2071*2c75bda4Serichkeane }
2072*2c75bda4Serichkeane 
2073*2c75bda4Serichkeane ExprResult SemaOpenACC::CheckTileSizeExpr(Expr *SizeExpr) {
2074*2c75bda4Serichkeane   if (!SizeExpr)
2075*2c75bda4Serichkeane     return ExprError();
2076*2c75bda4Serichkeane 
2077*2c75bda4Serichkeane   assert((SizeExpr->isInstantiationDependent() ||
2078*2c75bda4Serichkeane           SizeExpr->getType()->isIntegerType()) &&
2079*2c75bda4Serichkeane          "size argument non integer?");
2080*2c75bda4Serichkeane 
2081*2c75bda4Serichkeane   // If dependent, or an asterisk, the expression is fine.
2082*2c75bda4Serichkeane   if (SizeExpr->isInstantiationDependent() ||
2083*2c75bda4Serichkeane       isa<OpenACCAsteriskSizeExpr>(SizeExpr))
2084*2c75bda4Serichkeane     return ExprResult{SizeExpr};
2085*2c75bda4Serichkeane 
2086*2c75bda4Serichkeane   std::optional<llvm::APSInt> ICE =
2087*2c75bda4Serichkeane       SizeExpr->getIntegerConstantExpr(getASTContext());
2088*2c75bda4Serichkeane 
2089*2c75bda4Serichkeane   // OpenACC 3.3 2.9.8
2090*2c75bda4Serichkeane   // where each tile size is a constant positive integer expression or asterisk.
2091*2c75bda4Serichkeane   if (!ICE || *ICE <= 0) {
2092*2c75bda4Serichkeane     Diag(SizeExpr->getBeginLoc(), diag::err_acc_size_expr_value)
2093*2c75bda4Serichkeane         << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2094*2c75bda4Serichkeane     return ExprError();
2095*2c75bda4Serichkeane   }
2096*2c75bda4Serichkeane 
2097*2c75bda4Serichkeane   return ExprResult{
2098*2c75bda4Serichkeane       ConstantExpr::Create(getASTContext(), SizeExpr, APValue{*ICE})};
2099*2c75bda4Serichkeane }
2100*2c75bda4Serichkeane 
2101*2c75bda4Serichkeane ExprResult SemaOpenACC::CheckCollapseLoopCount(Expr *LoopCount) {
2102*2c75bda4Serichkeane   if (!LoopCount)
2103*2c75bda4Serichkeane     return ExprError();
2104*2c75bda4Serichkeane 
2105*2c75bda4Serichkeane   assert((LoopCount->isInstantiationDependent() ||
2106*2c75bda4Serichkeane           LoopCount->getType()->isIntegerType()) &&
2107*2c75bda4Serichkeane          "Loop argument non integer?");
2108*2c75bda4Serichkeane 
2109*2c75bda4Serichkeane   // If this is dependent, there really isn't anything we can check.
2110*2c75bda4Serichkeane   if (LoopCount->isInstantiationDependent())
2111*2c75bda4Serichkeane     return ExprResult{LoopCount};
2112*2c75bda4Serichkeane 
2113*2c75bda4Serichkeane   std::optional<llvm::APSInt> ICE =
2114*2c75bda4Serichkeane       LoopCount->getIntegerConstantExpr(getASTContext());
2115*2c75bda4Serichkeane 
2116*2c75bda4Serichkeane   // OpenACC 3.3: 2.9.1
2117*2c75bda4Serichkeane   // The argument to the collapse clause must be a constant positive integer
2118*2c75bda4Serichkeane   // expression.
2119*2c75bda4Serichkeane   if (!ICE || *ICE <= 0) {
2120*2c75bda4Serichkeane     Diag(LoopCount->getBeginLoc(), diag::err_acc_collapse_loop_count)
2121*2c75bda4Serichkeane         << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();
2122*2c75bda4Serichkeane     return ExprError();
2123*2c75bda4Serichkeane   }
2124*2c75bda4Serichkeane 
2125*2c75bda4Serichkeane   return ExprResult{
2126*2c75bda4Serichkeane       ConstantExpr::Create(getASTContext(), LoopCount, APValue{*ICE})};
2127*2c75bda4Serichkeane }
2128*2c75bda4Serichkeane 
2129*2c75bda4Serichkeane ExprResult
2130*2c75bda4Serichkeane SemaOpenACC::CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses,
2131*2c75bda4Serichkeane                            OpenACCDirectiveKind DK, OpenACCGangKind GK,
2132*2c75bda4Serichkeane                            Expr *E) {
2133*2c75bda4Serichkeane   // There are two cases for the enforcement here: the 'current' directive is a
2134*2c75bda4Serichkeane   // 'loop', where we need to check the active compute construct kind, or the
2135*2c75bda4Serichkeane   // current directive is a 'combined' construct, where we have to check the
2136*2c75bda4Serichkeane   // current one.
2137*2c75bda4Serichkeane   switch (DK) {
2138*2c75bda4Serichkeane   case OpenACCDirectiveKind::ParallelLoop:
2139*2c75bda4Serichkeane     return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2140*2c75bda4Serichkeane                                  E);
2141*2c75bda4Serichkeane   case OpenACCDirectiveKind::SerialLoop:
2142*2c75bda4Serichkeane     return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2143*2c75bda4Serichkeane                                E);
2144*2c75bda4Serichkeane   case OpenACCDirectiveKind::KernelsLoop:
2145*2c75bda4Serichkeane     return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2146*2c75bda4Serichkeane                                 ActiveComputeConstructInfo.Kind, GK, E);
2147*2c75bda4Serichkeane   case OpenACCDirectiveKind::Loop:
2148*2c75bda4Serichkeane     switch (ActiveComputeConstructInfo.Kind) {
2149*2c75bda4Serichkeane     case OpenACCDirectiveKind::Invalid:
2150*2c75bda4Serichkeane     case OpenACCDirectiveKind::Parallel:
2151*2c75bda4Serichkeane     case OpenACCDirectiveKind::ParallelLoop:
2152*2c75bda4Serichkeane       return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind,
2153*2c75bda4Serichkeane                                    GK, E);
2154*2c75bda4Serichkeane     case OpenACCDirectiveKind::SerialLoop:
2155*2c75bda4Serichkeane     case OpenACCDirectiveKind::Serial:
2156*2c75bda4Serichkeane       return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,
2157*2c75bda4Serichkeane                                  E);
2158*2c75bda4Serichkeane     case OpenACCDirectiveKind::KernelsLoop:
2159*2c75bda4Serichkeane     case OpenACCDirectiveKind::Kernels:
2160*2c75bda4Serichkeane       return CheckGangKernelsExpr(*this, ExistingClauses, DK,
2161*2c75bda4Serichkeane                                   ActiveComputeConstructInfo.Kind, GK, E);
2162*2c75bda4Serichkeane     default:
2163*2c75bda4Serichkeane       llvm_unreachable("Non compute construct in active compute construct?");
2164*2c75bda4Serichkeane     }
2165*2c75bda4Serichkeane   default:
2166*2c75bda4Serichkeane     // TODO: OpenACC: when we implement this on 'routine', we'll have to
2167*2c75bda4Serichkeane     // implement its checking here.
2168*2c75bda4Serichkeane     llvm_unreachable("Invalid directive kind for a Gang clause");
2169*2c75bda4Serichkeane   }
2170*2c75bda4Serichkeane   llvm_unreachable("Compute construct directive not handled?");
2171*2c75bda4Serichkeane }
2172*2c75bda4Serichkeane 
2173*2c75bda4Serichkeane OpenACCClause *
2174*2c75bda4Serichkeane SemaOpenACC::CheckGangClause(OpenACCDirectiveKind DirKind,
2175*2c75bda4Serichkeane                              ArrayRef<const OpenACCClause *> ExistingClauses,
2176*2c75bda4Serichkeane                              SourceLocation BeginLoc, SourceLocation LParenLoc,
2177*2c75bda4Serichkeane                              ArrayRef<OpenACCGangKind> GangKinds,
2178*2c75bda4Serichkeane                              ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) {
2179*2c75bda4Serichkeane   // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive
2180*2c75bda4Serichkeane   // that has a gang clause with a dim: argument whose value is greater than 1.
2181*2c75bda4Serichkeane 
2182*2c75bda4Serichkeane   const auto *ReductionItr =
2183*2c75bda4Serichkeane       llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
2184*2c75bda4Serichkeane 
2185*2c75bda4Serichkeane   if (ReductionItr != ExistingClauses.end()) {
2186*2c75bda4Serichkeane     const auto GangZip = llvm::zip_equal(GangKinds, IntExprs);
2187*2c75bda4Serichkeane     const auto GangItr = llvm::find_if(GangZip, [](const auto &Tuple) {
2188*2c75bda4Serichkeane       return std::get<0>(Tuple) == OpenACCGangKind::Dim;
2189*2c75bda4Serichkeane     });
2190*2c75bda4Serichkeane 
2191*2c75bda4Serichkeane     if (GangItr != GangZip.end()) {
2192*2c75bda4Serichkeane       const Expr *DimExpr = std::get<1>(*GangItr);
2193*2c75bda4Serichkeane 
2194*2c75bda4Serichkeane       assert(
2195*2c75bda4Serichkeane           (DimExpr->isInstantiationDependent() || isa<ConstantExpr>(DimExpr)) &&
2196*2c75bda4Serichkeane           "Improperly formed gang argument");
2197*2c75bda4Serichkeane       if (const auto *DimVal = dyn_cast<ConstantExpr>(DimExpr);
2198*2c75bda4Serichkeane           DimVal && DimVal->getResultAsAPSInt() > 1) {
2199*2c75bda4Serichkeane         Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict)
2200*2c75bda4Serichkeane             << /*gang/reduction=*/0 << DirKind;
2201*2c75bda4Serichkeane         Diag((*ReductionItr)->getBeginLoc(),
2202*2c75bda4Serichkeane              diag::note_acc_previous_clause_here);
2203*2c75bda4Serichkeane         return nullptr;
2204*2c75bda4Serichkeane       }
2205*2c75bda4Serichkeane     }
2206*2c75bda4Serichkeane   }
2207*2c75bda4Serichkeane 
2208*2c75bda4Serichkeane   return OpenACCGangClause::Create(getASTContext(), BeginLoc, LParenLoc,
2209*2c75bda4Serichkeane                                    GangKinds, IntExprs, EndLoc);
2210*2c75bda4Serichkeane }
2211*2c75bda4Serichkeane 
2212*2c75bda4Serichkeane OpenACCClause *SemaOpenACC::CheckReductionClause(
2213*2c75bda4Serichkeane     ArrayRef<const OpenACCClause *> ExistingClauses,
2214*2c75bda4Serichkeane     OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc,
2215*2c75bda4Serichkeane     SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp,
2216*2c75bda4Serichkeane     ArrayRef<Expr *> Vars, SourceLocation EndLoc) {
2217*2c75bda4Serichkeane   if (DirectiveKind == OpenACCDirectiveKind::Loop ||
2218*2c75bda4Serichkeane       isOpenACCCombinedDirectiveKind(DirectiveKind)) {
2219*2c75bda4Serichkeane     // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive
2220*2c75bda4Serichkeane     // that has a gang clause with a dim: argument whose value is greater
2221*2c75bda4Serichkeane     // than 1.
2222*2c75bda4Serichkeane     const auto GangClauses = llvm::make_filter_range(
2223*2c75bda4Serichkeane         ExistingClauses, llvm::IsaPred<OpenACCGangClause>);
2224*2c75bda4Serichkeane 
2225*2c75bda4Serichkeane     for (auto *GC : GangClauses) {
2226*2c75bda4Serichkeane       const auto *GangClause = cast<OpenACCGangClause>(GC);
2227*2c75bda4Serichkeane       for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) {
2228*2c75bda4Serichkeane         std::pair<OpenACCGangKind, const Expr *> EPair = GangClause->getExpr(I);
2229*2c75bda4Serichkeane         if (EPair.first != OpenACCGangKind::Dim)
2230*2c75bda4Serichkeane           continue;
2231*2c75bda4Serichkeane 
2232*2c75bda4Serichkeane         if (const auto *DimVal = dyn_cast<ConstantExpr>(EPair.second);
2233*2c75bda4Serichkeane             DimVal && DimVal->getResultAsAPSInt() > 1) {
2234*2c75bda4Serichkeane           Diag(BeginLoc, diag::err_acc_gang_reduction_conflict)
2235*2c75bda4Serichkeane               << /*reduction/gang=*/1 << DirectiveKind;
2236*2c75bda4Serichkeane           Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here);
2237*2c75bda4Serichkeane           return nullptr;
2238*2c75bda4Serichkeane         }
2239*2c75bda4Serichkeane       }
2240*2c75bda4Serichkeane     }
2241*2c75bda4Serichkeane   }
2242*2c75bda4Serichkeane 
2243*2c75bda4Serichkeane   auto *Ret = OpenACCReductionClause::Create(
2244*2c75bda4Serichkeane       getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc);
2245*2c75bda4Serichkeane   return Ret;
2246*2c75bda4Serichkeane }
2247