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