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