xref: /llvm-project/clang/lib/Sema/SemaOpenACC.cpp (revision 2c75bda42605b620f8450e44a7b6f2db3adc21cb)
1 //===--- SemaOpenACC.cpp - Semantic Analysis for OpenACC constructs -------===//
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 constructs, and things
10 /// that are not clause specific.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/StmtOpenACC.h"
15 #include "clang/Basic/DiagnosticSema.h"
16 #include "clang/Basic/OpenACCKinds.h"
17 #include "clang/Sema/Sema.h"
18 #include "clang/Sema/SemaOpenACC.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/Support/Casting.h"
21 
22 using namespace clang;
23 
24 namespace {
25 bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K,
26                                     SourceLocation StartLoc, bool IsStmt) {
27   switch (K) {
28   default:
29   case OpenACCDirectiveKind::Invalid:
30     // Nothing to do here, both invalid and unimplemented don't really need to
31     // do anything.
32     break;
33   case OpenACCDirectiveKind::ParallelLoop:
34   case OpenACCDirectiveKind::SerialLoop:
35   case OpenACCDirectiveKind::KernelsLoop:
36   case OpenACCDirectiveKind::Parallel:
37   case OpenACCDirectiveKind::Serial:
38   case OpenACCDirectiveKind::Kernels:
39   case OpenACCDirectiveKind::Loop:
40   case OpenACCDirectiveKind::Data:
41   case OpenACCDirectiveKind::EnterData:
42   case OpenACCDirectiveKind::ExitData:
43   case OpenACCDirectiveKind::HostData:
44   case OpenACCDirectiveKind::Wait:
45     if (!IsStmt)
46       return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
47     break;
48   }
49   return false;
50 }
51 
52 void CollectActiveReductionClauses(
53     llvm::SmallVector<OpenACCReductionClause *> &ActiveClauses,
54     ArrayRef<OpenACCClause *> CurClauses) {
55   for (auto *CurClause : CurClauses) {
56     if (auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
57         RedClause && !RedClause->getVarList().empty())
58       ActiveClauses.push_back(RedClause);
59   }
60 }
61 
62 // Depth needs to be preserved for all associated statements that aren't
63 // supposed to modify the compute/combined/loop construct information.
64 bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) {
65   switch (DK) {
66   case OpenACCDirectiveKind::Parallel:
67   case OpenACCDirectiveKind::ParallelLoop:
68   case OpenACCDirectiveKind::Serial:
69   case OpenACCDirectiveKind::SerialLoop:
70   case OpenACCDirectiveKind::Kernels:
71   case OpenACCDirectiveKind::KernelsLoop:
72   case OpenACCDirectiveKind::Loop:
73     return false;
74   case OpenACCDirectiveKind::Data:
75   case OpenACCDirectiveKind::HostData:
76     return true;
77   case OpenACCDirectiveKind::EnterData:
78   case OpenACCDirectiveKind::ExitData:
79   case OpenACCDirectiveKind::Wait:
80   case OpenACCDirectiveKind::Init:
81   case OpenACCDirectiveKind::Shutdown:
82   case OpenACCDirectiveKind::Set:
83   case OpenACCDirectiveKind::Update:
84     llvm_unreachable("Doesn't have an associated stmt");
85   default:
86   case OpenACCDirectiveKind::Invalid:
87     llvm_unreachable("Unhandled directive kind?");
88   }
89   llvm_unreachable("Unhandled directive kind?");
90 }
91 
92 } // namespace
93 
94 SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {}
95 
96 SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
97     SemaOpenACC &S, OpenACCDirectiveKind DK, SourceLocation DirLoc,
98     ArrayRef<const OpenACCClause *> UnInstClauses,
99     ArrayRef<OpenACCClause *> Clauses)
100     : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
101       DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),
102       OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
103       OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
104       OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),
105       ActiveReductionClauses(S.ActiveReductionClauses),
106       LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
107 
108   // Compute constructs end up taking their 'loop'.
109   if (DirKind == OpenACCDirectiveKind::Parallel ||
110       DirKind == OpenACCDirectiveKind::Serial ||
111       DirKind == OpenACCDirectiveKind::Kernels) {
112     CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
113     SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
114     SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
115 
116     // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
117     // construct, the gang clause behaves as follows. ... The region of a loop
118     // with a gang clause may not contain another loop with a gang clause unless
119     // within a nested compute region.
120     //
121     // Implement the 'unless within a nested compute region' part.
122     SemaRef.LoopGangClauseOnKernel = {};
123     SemaRef.LoopWorkerClauseLoc = {};
124     SemaRef.LoopVectorClauseLoc = {};
125     SemaRef.LoopWithoutSeqInfo = {};
126   } else if (DirKind == OpenACCDirectiveKind::ParallelLoop ||
127              DirKind == OpenACCDirectiveKind::SerialLoop ||
128              DirKind == OpenACCDirectiveKind::KernelsLoop) {
129     SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
130     SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
131 
132     CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
133     SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
134     SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
135 
136     SemaRef.LoopGangClauseOnKernel = {};
137     SemaRef.LoopWorkerClauseLoc = {};
138     SemaRef.LoopVectorClauseLoc = {};
139 
140     // Set the active 'loop' location if there isn't a 'seq' on it, so we can
141     // diagnose the for loops.
142     SemaRef.LoopWithoutSeqInfo = {};
143     if (Clauses.end() ==
144         llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
145       SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
146 
147     // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
148     // construct, the gang clause behaves as follows. ... The region of a loop
149     // with a gang clause may not contain another loop with a gang clause unless
150     // within a nested compute region.
151     //
152     // We don't bother doing this when this is a template instantiation, as
153     // there is no reason to do these checks: the existance of a
154     // gang/kernels/etc cannot be dependent.
155     if (DirKind == OpenACCDirectiveKind::KernelsLoop && UnInstClauses.empty()) {
156       // This handles the 'outer loop' part of this.
157       auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
158       if (Itr != Clauses.end())
159         SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), DirKind};
160     }
161 
162     if (UnInstClauses.empty()) {
163       auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
164       if (Itr != Clauses.end())
165         SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
166 
167       auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
168       if (Itr2 != Clauses.end())
169         SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
170     }
171   } else if (DirKind == OpenACCDirectiveKind::Loop) {
172     CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
173     SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
174     SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
175 
176     // Set the active 'loop' location if there isn't a 'seq' on it, so we can
177     // diagnose the for loops.
178     SemaRef.LoopWithoutSeqInfo = {};
179     if (Clauses.end() ==
180         llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
181       SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
182 
183     // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
184     // construct, the gang clause behaves as follows. ... The region of a loop
185     // with a gang clause may not contain another loop with a gang clause unless
186     // within a nested compute region.
187     //
188     // We don't bother doing this when this is a template instantiation, as
189     // there is no reason to do these checks: the existance of a
190     // gang/kernels/etc cannot be dependent.
191     if (SemaRef.getActiveComputeConstructInfo().Kind ==
192             OpenACCDirectiveKind::Kernels &&
193         UnInstClauses.empty()) {
194       // This handles the 'outer loop' part of this.
195       auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
196       if (Itr != Clauses.end())
197         SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(),
198                                           OpenACCDirectiveKind::Kernels};
199     }
200 
201     if (UnInstClauses.empty()) {
202       auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
203       if (Itr != Clauses.end())
204         SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
205 
206       auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
207       if (Itr2 != Clauses.end())
208         SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
209     }
210   }
211 }
212 
213 void SemaOpenACC::AssociatedStmtRAII::SetCollapseInfoBeforeAssociatedStmt(
214     ArrayRef<const OpenACCClause *> UnInstClauses,
215     ArrayRef<OpenACCClause *> Clauses) {
216 
217   // Reset this checking for loops that aren't covered in a RAII object.
218   SemaRef.LoopInfo.CurLevelHasLoopAlready = false;
219   SemaRef.CollapseInfo.CollapseDepthSatisfied = true;
220   SemaRef.TileInfo.TileDepthSatisfied = true;
221 
222   // We make sure to take an optional list of uninstantiated clauses, so that
223   // we can check to make sure we don't 'double diagnose' in the event that
224   // the value of 'N' was not dependent in a template. We also ensure during
225   // Sema that there is only 1 collapse on each construct, so we can count on
226   // the fact that if both find a 'collapse', that they are the same one.
227   auto *CollapseClauseItr =
228       llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
229   auto *UnInstCollapseClauseItr =
230       llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
231 
232   if (Clauses.end() == CollapseClauseItr)
233     return;
234 
235   OpenACCCollapseClause *CollapseClause =
236       cast<OpenACCCollapseClause>(*CollapseClauseItr);
237 
238   SemaRef.CollapseInfo.ActiveCollapse = CollapseClause;
239   Expr *LoopCount = CollapseClause->getLoopCount();
240 
241   // If the loop count is still instantiation dependent, setting the depth
242   // counter isn't necessary, so return here.
243   if (!LoopCount || LoopCount->isInstantiationDependent())
244     return;
245 
246   // Suppress diagnostics if we've done a 'transform' where the previous version
247   // wasn't dependent, meaning we already diagnosed it.
248   if (UnInstCollapseClauseItr != UnInstClauses.end() &&
249       !cast<OpenACCCollapseClause>(*UnInstCollapseClauseItr)
250            ->getLoopCount()
251            ->isInstantiationDependent())
252     return;
253 
254   SemaRef.CollapseInfo.CollapseDepthSatisfied = false;
255   SemaRef.CollapseInfo.CurCollapseCount =
256       cast<ConstantExpr>(LoopCount)->getResultAsAPSInt();
257   SemaRef.CollapseInfo.DirectiveKind = DirKind;
258 }
259 
260 void SemaOpenACC::AssociatedStmtRAII::SetTileInfoBeforeAssociatedStmt(
261     ArrayRef<const OpenACCClause *> UnInstClauses,
262     ArrayRef<OpenACCClause *> Clauses) {
263   // We don't diagnose if this is during instantiation, since the only thing we
264   // care about is the number of arguments, which we can figure out without
265   // instantiation, so we don't want to double-diagnose.
266   if (UnInstClauses.size() > 0)
267     return;
268   auto *TileClauseItr =
269       llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
270 
271   if (Clauses.end() == TileClauseItr)
272     return;
273 
274   OpenACCTileClause *TileClause = cast<OpenACCTileClause>(*TileClauseItr);
275   SemaRef.TileInfo.ActiveTile = TileClause;
276   SemaRef.TileInfo.TileDepthSatisfied = false;
277   SemaRef.TileInfo.CurTileCount = TileClause->getSizeExprs().size();
278   SemaRef.TileInfo.DirectiveKind = DirKind;
279 }
280 
281 SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() {
282   if (DirKind == OpenACCDirectiveKind::Parallel ||
283       DirKind == OpenACCDirectiveKind::Serial ||
284       DirKind == OpenACCDirectiveKind::Kernels ||
285       DirKind == OpenACCDirectiveKind::Loop ||
286       DirKind == OpenACCDirectiveKind::ParallelLoop ||
287       DirKind == OpenACCDirectiveKind::SerialLoop ||
288       DirKind == OpenACCDirectiveKind::KernelsLoop) {
289     SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
290     SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
291     SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
292     SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
293     SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
294     SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
295   } else if (DirKind == OpenACCDirectiveKind::Data ||
296              DirKind == OpenACCDirectiveKind::HostData) {
297     // Intentionally doesn't reset the Loop, Compute Construct, or reduction
298     // effects.
299   }
300 }
301 
302 void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
303                                  SourceLocation DirLoc) {
304   // Start an evaluation context to parse the clause arguments on.
305   SemaRef.PushExpressionEvaluationContext(
306       Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
307 
308   switch (K) {
309   case OpenACCDirectiveKind::Invalid:
310     // Nothing to do here, an invalid kind has nothing we can check here.  We
311     // want to continue parsing clauses as far as we can, so we will just
312     // ensure that we can still work and don't check any construct-specific
313     // rules anywhere.
314     break;
315   case OpenACCDirectiveKind::Parallel:
316   case OpenACCDirectiveKind::Serial:
317   case OpenACCDirectiveKind::Kernels:
318   case OpenACCDirectiveKind::ParallelLoop:
319   case OpenACCDirectiveKind::SerialLoop:
320   case OpenACCDirectiveKind::KernelsLoop:
321   case OpenACCDirectiveKind::Loop:
322   case OpenACCDirectiveKind::Data:
323   case OpenACCDirectiveKind::EnterData:
324   case OpenACCDirectiveKind::ExitData:
325   case OpenACCDirectiveKind::HostData:
326   case OpenACCDirectiveKind::Init:
327   case OpenACCDirectiveKind::Shutdown:
328   case OpenACCDirectiveKind::Set:
329   case OpenACCDirectiveKind::Update:
330     // Nothing to do here, there is no real legalization that needs to happen
331     // here as these constructs do not take any arguments.
332     break;
333   case OpenACCDirectiveKind::Wait:
334     // Nothing really to do here, the arguments to the 'wait' should have
335     // already been handled by the time we get here.
336     break;
337   default:
338     Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;
339     break;
340   }
341 }
342 
343 ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK,
344                                      OpenACCClauseKind CK, SourceLocation Loc,
345                                      Expr *IntExpr) {
346 
347   assert(((DK != OpenACCDirectiveKind::Invalid &&
348            CK == OpenACCClauseKind::Invalid) ||
349           (DK == OpenACCDirectiveKind::Invalid &&
350            CK != OpenACCClauseKind::Invalid) ||
351           (DK == OpenACCDirectiveKind::Invalid &&
352            CK == OpenACCClauseKind::Invalid)) &&
353          "Only one of directive or clause kind should be provided");
354 
355   class IntExprConverter : public Sema::ICEConvertDiagnoser {
356     OpenACCDirectiveKind DirectiveKind;
357     OpenACCClauseKind ClauseKind;
358     Expr *IntExpr;
359 
360     // gets the index into the diagnostics so we can use this for clauses,
361     // directives, and sub array.s
362     unsigned getDiagKind() const {
363       if (ClauseKind != OpenACCClauseKind::Invalid)
364         return 0;
365       if (DirectiveKind != OpenACCDirectiveKind::Invalid)
366         return 1;
367       return 2;
368     }
369 
370   public:
371     IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
372                      Expr *IntExpr)
373         : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false,
374                               /*Suppress=*/false,
375                               /*SuppressConversion=*/true),
376           DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
377 
378     bool match(QualType T) override {
379       // OpenACC spec just calls this 'integer expression' as having an
380       // 'integer type', so fall back on C99's 'integer type'.
381       return T->isIntegerType();
382     }
383     SemaBase::SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
384                                                    QualType T) override {
385       return S.Diag(Loc, diag::err_acc_int_expr_requires_integer)
386              << getDiagKind() << ClauseKind << DirectiveKind << T;
387     }
388 
389     SemaBase::SemaDiagnosticBuilder
390     diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override {
391       return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
392              << T << IntExpr->getSourceRange();
393     }
394 
395     SemaBase::SemaDiagnosticBuilder
396     diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T,
397                          QualType ConvTy) override {
398       return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
399              << T << ConvTy;
400     }
401 
402     SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S,
403                                                      CXXConversionDecl *Conv,
404                                                      QualType ConvTy) override {
405       return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
406              << ConvTy->isEnumeralType() << ConvTy;
407     }
408 
409     SemaBase::SemaDiagnosticBuilder
410     diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override {
411       return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T;
412     }
413 
414     SemaBase::SemaDiagnosticBuilder
415     noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
416       return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
417              << ConvTy->isEnumeralType() << ConvTy;
418     }
419 
420     SemaBase::SemaDiagnosticBuilder
421     diagnoseConversion(Sema &S, SourceLocation Loc, QualType T,
422                        QualType ConvTy) override {
423       llvm_unreachable("conversion functions are permitted");
424     }
425   } IntExprDiagnoser(DK, CK, IntExpr);
426 
427   if (!IntExpr)
428     return ExprError();
429 
430   ExprResult IntExprResult = SemaRef.PerformContextualImplicitConversion(
431       Loc, IntExpr, IntExprDiagnoser);
432   if (IntExprResult.isInvalid())
433     return ExprError();
434 
435   IntExpr = IntExprResult.get();
436   if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType())
437     return ExprError();
438 
439   // TODO OpenACC: Do we want to perform usual unary conversions here? When
440   // doing codegen we might find that is necessary, but skip it for now.
441   return IntExpr;
442 }
443 
444 bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind,
445                                         Expr *VarExpr) {
446   // We already know that VarExpr is a proper reference to a variable, so we
447   // should be able to just take the type of the expression to get the type of
448   // the referenced variable.
449 
450   // We've already seen an error, don't diagnose anything else.
451   if (!VarExpr || VarExpr->containsErrors())
452     return false;
453 
454   if (isa<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()) ||
455       VarExpr->hasPlaceholderType(BuiltinType::ArraySection)) {
456     Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << /*OpenACC=*/0;
457     Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var);
458     return true;
459   }
460 
461   QualType Ty = VarExpr->getType();
462   Ty = Ty.getNonReferenceType().getUnqualifiedType();
463 
464   // Nothing we can do if this is a dependent type.
465   if (Ty->isDependentType())
466     return false;
467 
468   if (!Ty->isPointerType())
469     return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type)
470            << ClauseKind << Ty;
471   return false;
472 }
473 
474 ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) {
475   Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
476 
477   // 'use_device' doesn't allow array subscript or array sections.
478   // OpenACC3.3 2.8:
479   // A 'var' in a 'use_device' clause must be the name of a variable or array.
480   if (CK == OpenACCClauseKind::UseDevice &&
481       isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
482     Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
483     return ExprError();
484   }
485 
486   // Sub-arrays/subscript-exprs are fine as long as the base is a
487   // VarExpr/MemberExpr. So strip all of those off.
488   while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
489     if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
490       CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts();
491     else
492       CurVarExpr =
493           cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts();
494   }
495 
496   // References to a VarDecl are fine.
497   if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
498     if (isa<VarDecl, NonTypeTemplateParmDecl>(
499             DRE->getFoundDecl()->getCanonicalDecl()))
500       return VarExpr;
501   }
502 
503   // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a
504   // reduction clause must be a scalar variable name, an aggregate variable
505   // name, an array element, or a subarray.
506   // If CK is a 'use_device', this also isn't valid, as it isn' the name of a
507   // variable or array.
508   // A MemberExpr that references a Field is valid for other clauses.
509   if (CK != OpenACCClauseKind::Reduction &&
510       CK != OpenACCClauseKind::UseDevice) {
511     if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
512       if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
513         return VarExpr;
514     }
515   }
516 
517   // Referring to 'this' is ok for the most part, but for 'use_device' doesn't
518   // fall into 'variable or array name'
519   if (CK != OpenACCClauseKind::UseDevice && isa<CXXThisExpr>(CurVarExpr))
520     return VarExpr;
521 
522   // Nothing really we can do here, as these are dependent.  So just return they
523   // are valid.
524   if (isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
525       (CK != OpenACCClauseKind::Reduction &&
526        isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
527     return VarExpr;
528 
529   // There isn't really anything we can do in the case of a recovery expr, so
530   // skip the diagnostic rather than produce a confusing diagnostic.
531   if (isa<RecoveryExpr>(CurVarExpr))
532     return ExprError();
533 
534   if (CK == OpenACCClauseKind::UseDevice)
535     Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);
536   else
537     Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)
538         << (CK != OpenACCClauseKind::Reduction);
539   return ExprError();
540 }
541 
542 ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
543                                               Expr *LowerBound,
544                                               SourceLocation ColonLoc,
545                                               Expr *Length,
546                                               SourceLocation RBLoc) {
547   ASTContext &Context = getASTContext();
548 
549   // Handle placeholders.
550   if (Base->hasPlaceholderType() &&
551       !Base->hasPlaceholderType(BuiltinType::ArraySection)) {
552     ExprResult Result = SemaRef.CheckPlaceholderExpr(Base);
553     if (Result.isInvalid())
554       return ExprError();
555     Base = Result.get();
556   }
557   if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) {
558     ExprResult Result = SemaRef.CheckPlaceholderExpr(LowerBound);
559     if (Result.isInvalid())
560       return ExprError();
561     Result = SemaRef.DefaultLvalueConversion(Result.get());
562     if (Result.isInvalid())
563       return ExprError();
564     LowerBound = Result.get();
565   }
566   if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
567     ExprResult Result = SemaRef.CheckPlaceholderExpr(Length);
568     if (Result.isInvalid())
569       return ExprError();
570     Result = SemaRef.DefaultLvalueConversion(Result.get());
571     if (Result.isInvalid())
572       return ExprError();
573     Length = Result.get();
574   }
575 
576   // Check the 'base' value, it must be an array or pointer type, and not to/of
577   // a function type.
578   QualType OriginalBaseTy = ArraySectionExpr::getBaseOriginalType(Base);
579   QualType ResultTy;
580   if (!Base->isTypeDependent()) {
581     if (OriginalBaseTy->isAnyPointerType()) {
582       ResultTy = OriginalBaseTy->getPointeeType();
583     } else if (OriginalBaseTy->isArrayType()) {
584       ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType();
585     } else {
586       return ExprError(
587           Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
588           << Base->getSourceRange());
589     }
590 
591     if (ResultTy->isFunctionType()) {
592       Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type)
593           << ResultTy << Base->getSourceRange();
594       return ExprError();
595     }
596 
597     if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy,
598                                     diag::err_acc_subarray_incomplete_type,
599                                     Base))
600       return ExprError();
601 
602     if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) {
603       ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base);
604       if (Result.isInvalid())
605         return ExprError();
606       Base = Result.get();
607     }
608   }
609 
610   auto GetRecovery = [&](Expr *E, QualType Ty) {
611     ExprResult Recovery =
612         SemaRef.CreateRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), E, Ty);
613     return Recovery.isUsable() ? Recovery.get() : nullptr;
614   };
615 
616   // Ensure both of the expressions are int-exprs.
617   if (LowerBound && !LowerBound->isTypeDependent()) {
618     ExprResult LBRes =
619         ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid,
620                      LowerBound->getExprLoc(), LowerBound);
621 
622     if (LBRes.isUsable())
623       LBRes = SemaRef.DefaultLvalueConversion(LBRes.get());
624     LowerBound =
625         LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);
626   }
627 
628   if (Length && !Length->isTypeDependent()) {
629     ExprResult LenRes =
630         ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid,
631                      Length->getExprLoc(), Length);
632 
633     if (LenRes.isUsable())
634       LenRes = SemaRef.DefaultLvalueConversion(LenRes.get());
635     Length =
636         LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);
637   }
638 
639   // Length is required if the base type is not an array of known bounds.
640   if (!Length && (OriginalBaseTy.isNull() ||
641                   (!OriginalBaseTy->isDependentType() &&
642                    !OriginalBaseTy->isConstantArrayType() &&
643                    !OriginalBaseTy->isDependentSizedArrayType()))) {
644     bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();
645     Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
646     // Fill in a dummy 'length' so that when we instantiate this we don't
647     // double-diagnose here.
648     ExprResult Recovery = SemaRef.CreateRecoveryExpr(
649         ColonLoc, SourceLocation(), ArrayRef<Expr *>(), Context.IntTy);
650     Length = Recovery.isUsable() ? Recovery.get() : nullptr;
651   }
652 
653   // Check the values of each of the arguments, they cannot be negative(we
654   // assume), and if the array bound is known, must be within range. As we do
655   // so, do our best to continue with evaluation, we can set the
656   // value/expression to nullptr/nullopt if they are invalid, and treat them as
657   // not present for the rest of evaluation.
658 
659   // We don't have to check for dependence, because the dependent size is
660   // represented as a different AST node.
661   std::optional<llvm::APSInt> BaseSize;
662   if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) {
663     const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
664     BaseSize = ArrayTy->getSize();
665   }
666 
667   auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> {
668     if (!E || E->isInstantiationDependent())
669       return std::nullopt;
670 
671     Expr::EvalResult Res;
672     if (!E->EvaluateAsInt(Res, Context))
673       return std::nullopt;
674     return Res.Val.getInt();
675   };
676 
677   std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
678   std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
679 
680   // Check lower bound for negative or out of range.
681   if (LowerBoundValue.has_value()) {
682     if (LowerBoundValue->isNegative()) {
683       Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative)
684           << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10);
685       LowerBoundValue.reset();
686       LowerBound = GetRecovery(LowerBound, LowerBound->getType());
687     } else if (BaseSize.has_value() &&
688                llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
689       // Lower bound (start index) must be less than the size of the array.
690       Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range)
691           << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10)
692           << toString(*BaseSize, /*Radix=*/10);
693       LowerBoundValue.reset();
694       LowerBound = GetRecovery(LowerBound, LowerBound->getType());
695     }
696   }
697 
698   // Check length for negative or out of range.
699   if (LengthValue.has_value()) {
700     if (LengthValue->isNegative()) {
701       Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
702           << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10);
703       LengthValue.reset();
704       Length = GetRecovery(Length, Length->getType());
705     } else if (BaseSize.has_value() &&
706                llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
707       // Length must be lessthan or EQUAL to the size of the array.
708       Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
709           << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10)
710           << toString(*BaseSize, /*Radix=*/10);
711       LengthValue.reset();
712       Length = GetRecovery(Length, Length->getType());
713     }
714   }
715 
716   // Adding two APSInts requires matching sign, so extract that here.
717   auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
718     if (LHS.isSigned() == RHS.isSigned())
719       return LHS + RHS;
720 
721     unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
722     return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), /*Signed=*/true);
723   };
724 
725   // If we know all 3 values, we can diagnose that the total value would be out
726   // of range.
727   if (BaseSize.has_value() && LowerBoundValue.has_value() &&
728       LengthValue.has_value() &&
729       llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
730                                   *BaseSize) > 0) {
731     Diag(Base->getExprLoc(),
732          diag::err_acc_subarray_base_plus_length_out_of_range)
733         << toString(*LowerBoundValue, /*Radix=*/10)
734         << toString(*LengthValue, /*Radix=*/10)
735         << toString(*BaseSize, /*Radix=*/10);
736 
737     LowerBoundValue.reset();
738     LowerBound = GetRecovery(LowerBound, LowerBound->getType());
739     LengthValue.reset();
740     Length = GetRecovery(Length, Length->getType());
741   }
742 
743   // If any part of the expression is dependent, return a dependent sub-array.
744   QualType ArrayExprTy = Context.ArraySectionTy;
745   if (Base->isTypeDependent() ||
746       (LowerBound && LowerBound->isInstantiationDependent()) ||
747       (Length && Length->isInstantiationDependent()))
748     ArrayExprTy = Context.DependentTy;
749 
750   return new (Context)
751       ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue,
752                        OK_Ordinary, ColonLoc, RBLoc);
753 }
754 
755 void SemaOpenACC::ActOnWhileStmt(SourceLocation WhileLoc) {
756   if (!getLangOpts().OpenACC)
757     return;
758 
759   if (!LoopInfo.TopLevelLoopSeen)
760     return;
761 
762   if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
763     Diag(WhileLoc, diag::err_acc_invalid_in_loop)
764         << /*while loop*/ 1 << CollapseInfo.DirectiveKind
765         << OpenACCClauseKind::Collapse;
766     assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
767     Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
768          diag::note_acc_active_clause_here)
769         << OpenACCClauseKind::Collapse;
770 
771     // Remove the value so that we don't get cascading errors in the body. The
772     // caller RAII object will restore this.
773     CollapseInfo.CurCollapseCount = std::nullopt;
774   }
775 
776   if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
777     Diag(WhileLoc, diag::err_acc_invalid_in_loop)
778         << /*while loop*/ 1 << TileInfo.DirectiveKind
779         << OpenACCClauseKind::Tile;
780     assert(TileInfo.ActiveTile && "tile count without object?");
781     Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
782         << OpenACCClauseKind::Tile;
783 
784     // Remove the value so that we don't get cascading errors in the body. The
785     // caller RAII object will restore this.
786     TileInfo.CurTileCount = std::nullopt;
787   }
788 }
789 
790 void SemaOpenACC::ActOnDoStmt(SourceLocation DoLoc) {
791   if (!getLangOpts().OpenACC)
792     return;
793 
794   if (!LoopInfo.TopLevelLoopSeen)
795     return;
796 
797   if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
798     Diag(DoLoc, diag::err_acc_invalid_in_loop)
799         << /*do loop*/ 2 << CollapseInfo.DirectiveKind
800         << OpenACCClauseKind::Collapse;
801     assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
802     Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
803          diag::note_acc_active_clause_here)
804         << OpenACCClauseKind::Collapse;
805 
806     // Remove the value so that we don't get cascading errors in the body. The
807     // caller RAII object will restore this.
808     CollapseInfo.CurCollapseCount = std::nullopt;
809   }
810 
811   if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
812     Diag(DoLoc, diag::err_acc_invalid_in_loop)
813         << /*do loop*/ 2 << TileInfo.DirectiveKind << OpenACCClauseKind::Tile;
814     assert(TileInfo.ActiveTile && "tile count without object?");
815     Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
816         << OpenACCClauseKind::Tile;
817 
818     // Remove the value so that we don't get cascading errors in the body. The
819     // caller RAII object will restore this.
820     TileInfo.CurTileCount = std::nullopt;
821   }
822 }
823 
824 void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc,
825                                      ForStmtBeginChecker &C) {
826   assert(getLangOpts().OpenACC && "Check enabled when not OpenACC?");
827 
828   // Enable the while/do-while checking.
829   LoopInfo.TopLevelLoopSeen = true;
830 
831   if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
832     C.check();
833 
834     // OpenACC 3.3 2.9.1:
835     // Each associated loop, except the innermost, must contain exactly one loop
836     // or loop nest.
837     // This checks for more than 1 loop at the current level, the
838     // 'depth'-satisifed checking manages the 'not zero' case.
839     if (LoopInfo.CurLevelHasLoopAlready) {
840       Diag(ForLoc, diag::err_acc_clause_multiple_loops)
841           << CollapseInfo.DirectiveKind << OpenACCClauseKind::Collapse;
842       assert(CollapseInfo.ActiveCollapse && "No collapse object?");
843       Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
844            diag::note_acc_active_clause_here)
845           << OpenACCClauseKind::Collapse;
846     } else {
847       --(*CollapseInfo.CurCollapseCount);
848 
849       // Once we've hit zero here, we know we have deep enough 'for' loops to
850       // get to the bottom.
851       if (*CollapseInfo.CurCollapseCount == 0)
852         CollapseInfo.CollapseDepthSatisfied = true;
853     }
854   }
855 
856   if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
857     C.check();
858 
859     if (LoopInfo.CurLevelHasLoopAlready) {
860       Diag(ForLoc, diag::err_acc_clause_multiple_loops)
861           << TileInfo.DirectiveKind << OpenACCClauseKind::Tile;
862       assert(TileInfo.ActiveTile && "No tile object?");
863       Diag(TileInfo.ActiveTile->getBeginLoc(),
864            diag::note_acc_active_clause_here)
865           << OpenACCClauseKind::Tile;
866     } else {
867       --(*TileInfo.CurTileCount);
868       // Once we've hit zero here, we know we have deep enough 'for' loops to
869       // get to the bottom.
870       if (*TileInfo.CurTileCount == 0)
871         TileInfo.TileDepthSatisfied = true;
872     }
873   }
874 
875   // Set this to 'false' for the body of this loop, so that the next level
876   // checks independently.
877   LoopInfo.CurLevelHasLoopAlready = false;
878 }
879 
880 namespace {
881 bool isValidLoopVariableType(QualType LoopVarTy) {
882   // Just skip if it is dependent, it could be any of the below.
883   if (LoopVarTy->isDependentType())
884     return true;
885 
886   // The loop variable must be of integer,
887   if (LoopVarTy->isIntegerType())
888     return true;
889 
890   // C/C++ pointer,
891   if (LoopVarTy->isPointerType())
892     return true;
893 
894   // or C++ random-access iterator type.
895   if (const auto *RD = LoopVarTy->getAsCXXRecordDecl()) {
896     // Note: Only do CXXRecordDecl because RecordDecl can't be a random access
897     // iterator type!
898 
899     // We could either do a lot of work to see if this matches
900     // random-access-iterator, but it seems that just checking that the
901     // 'iterator_category' typedef is more than sufficient. If programmers are
902     // willing to lie about this, we can let them.
903 
904     for (const auto *TD :
905          llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
906       const auto *TDND = cast<TypedefNameDecl>(TD)->getCanonicalDecl();
907 
908       if (TDND->getName() != "iterator_category")
909         continue;
910 
911       // If there is no type for this decl, return false.
912       if (TDND->getUnderlyingType().isNull())
913         return false;
914 
915       const CXXRecordDecl *ItrCategoryDecl =
916           TDND->getUnderlyingType()->getAsCXXRecordDecl();
917 
918       // If the category isn't a record decl, it isn't the tag type.
919       if (!ItrCategoryDecl)
920         return false;
921 
922       auto IsRandomAccessIteratorTag = [](const CXXRecordDecl *RD) {
923         if (RD->getName() != "random_access_iterator_tag")
924           return false;
925         // Checks just for std::random_access_iterator_tag.
926         return RD->getEnclosingNamespaceContext()->isStdNamespace();
927       };
928 
929       if (IsRandomAccessIteratorTag(ItrCategoryDecl))
930         return true;
931 
932       // We can also support types inherited from the
933       // random_access_iterator_tag.
934       for (CXXBaseSpecifier BS : ItrCategoryDecl->bases()) {
935 
936         if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
937           return true;
938       }
939 
940       return false;
941     }
942   }
943 
944   return false;
945 }
946 
947 } // namespace
948 
949 void SemaOpenACC::ForStmtBeginChecker::check() {
950   if (SemaRef.LoopWithoutSeqInfo.Kind == OpenACCDirectiveKind::Invalid)
951     return;
952 
953   if (AlreadyChecked)
954     return;
955   AlreadyChecked = true;
956 
957   // OpenACC3.3 2.1:
958   // A loop associated with a loop construct that does not have a seq clause
959   // must be written to meet all the following conditions:
960   // - The loop variable must be of integer, C/C++ pointer, or C++ random-access
961   // iterator type.
962   // - The loop variable must monotonically increase or decrease in the
963   // direction of its termination condition.
964   // - The loop trip count must be computable in constant time when entering the
965   // loop construct.
966   //
967   // For a C++ range-based for loop, the loop variable
968   // identified by the above conditions is the internal iterator, such as a
969   // pointer, that the compiler generates to iterate the range.  it is not the
970   // variable declared by the for loop.
971 
972   if (IsRangeFor) {
973     // If the range-for is being instantiated and didn't change, don't
974     // re-diagnose.
975     if (!RangeFor.has_value())
976       return;
977     // For a range-for, we can assume everything is 'corect' other than the type
978     // of the iterator, so check that.
979     const DeclStmt *RangeStmt = (*RangeFor)->getBeginStmt();
980 
981     // In some dependent contexts, the autogenerated range statement doesn't get
982     // included until instantiation, so skip for now.
983     if (!RangeStmt)
984       return;
985 
986     const ValueDecl *InitVar = cast<ValueDecl>(RangeStmt->getSingleDecl());
987     QualType VarType = InitVar->getType().getNonReferenceType();
988     if (!isValidLoopVariableType(VarType)) {
989       SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type)
990           << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
991       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
992                    diag::note_acc_construct_here)
993           << SemaRef.LoopWithoutSeqInfo.Kind;
994     }
995     return;
996   }
997 
998   // Else we are in normal 'ForStmt', so we can diagnose everything.
999   // We only have to check cond/inc if they have changed, but 'init' needs to
1000   // just suppress its diagnostics if it hasn't changed.
1001   const ValueDecl *InitVar = checkInit();
1002   if (Cond.has_value())
1003     checkCond();
1004   if (Inc.has_value())
1005     checkInc(InitVar);
1006 }
1007 const ValueDecl *SemaOpenACC::ForStmtBeginChecker::checkInit() {
1008   if (!Init) {
1009     if (InitChanged) {
1010       SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
1011           << SemaRef.LoopWithoutSeqInfo.Kind;
1012       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1013                    diag::note_acc_construct_here)
1014           << SemaRef.LoopWithoutSeqInfo.Kind;
1015     }
1016     return nullptr;
1017   }
1018 
1019   auto DiagLoopVar = [&]() {
1020     if (InitChanged) {
1021       SemaRef.Diag(Init->getBeginLoc(), diag::err_acc_loop_variable)
1022           << SemaRef.LoopWithoutSeqInfo.Kind;
1023       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1024                    diag::note_acc_construct_here)
1025           << SemaRef.LoopWithoutSeqInfo.Kind;
1026     }
1027     return nullptr;
1028   };
1029 
1030   if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
1031     Init = ExprTemp->getSubExpr();
1032   if (const auto *E = dyn_cast<Expr>(Init))
1033     Init = E->IgnoreParenImpCasts();
1034 
1035   const ValueDecl *InitVar = nullptr;
1036 
1037   if (const auto *BO = dyn_cast<BinaryOperator>(Init)) {
1038     // Allow assignment operator here.
1039 
1040     if (!BO->isAssignmentOp())
1041       return DiagLoopVar();
1042 
1043     const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
1044 
1045     if (const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1046       InitVar = DRE->getDecl();
1047   } else if (const auto *DS = dyn_cast<DeclStmt>(Init)) {
1048     // Allow T t = <whatever>
1049     if (!DS->isSingleDecl())
1050       return DiagLoopVar();
1051 
1052     InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1053 
1054     // Ensure we have an initializer, unless this is a record/dependent type.
1055 
1056     if (InitVar) {
1057       if (!isa<VarDecl>(InitVar))
1058         return DiagLoopVar();
1059 
1060       if (!InitVar->getType()->isRecordType() &&
1061           !InitVar->getType()->isDependentType() &&
1062           !cast<VarDecl>(InitVar)->hasInit())
1063         return DiagLoopVar();
1064     }
1065   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(Init)) {
1066     // Allow assignment operator call.
1067     if (CE->getOperator() != OO_Equal)
1068       return DiagLoopVar();
1069 
1070     const Expr *LHS = CE->getArg(0)->IgnoreParenImpCasts();
1071 
1072     if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1073       InitVar = DRE->getDecl();
1074     } else if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
1075       if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1076         InitVar = ME->getMemberDecl();
1077     }
1078   }
1079 
1080   if (!InitVar)
1081     return DiagLoopVar();
1082 
1083   InitVar = cast<ValueDecl>(InitVar->getCanonicalDecl());
1084   QualType VarType = InitVar->getType().getNonReferenceType();
1085 
1086   // Since we have one, all we need to do is ensure it is the right type.
1087   if (!isValidLoopVariableType(VarType)) {
1088     if (InitChanged) {
1089       SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type)
1090           << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1091       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1092                    diag::note_acc_construct_here)
1093           << SemaRef.LoopWithoutSeqInfo.Kind;
1094     }
1095     return nullptr;
1096   }
1097 
1098   return InitVar;
1099 }
1100 void SemaOpenACC::ForStmtBeginChecker::checkCond() {
1101   if (!*Cond) {
1102     SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1103         << SemaRef.LoopWithoutSeqInfo.Kind;
1104     SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
1105         << SemaRef.LoopWithoutSeqInfo.Kind;
1106   }
1107   // Nothing else to do here.  we could probably do some additional work to look
1108   // into the termination condition, but that error-prone.  For now, we don't
1109   // implement anything other than 'there is a termination condition', and if
1110   // codegen/MLIR comes up with some necessary restrictions, we can implement
1111   // them here.
1112 }
1113 
1114 void SemaOpenACC::ForStmtBeginChecker::checkInc(const ValueDecl *Init) {
1115 
1116   if (!*Inc) {
1117     SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1118         << SemaRef.LoopWithoutSeqInfo.Kind;
1119     SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
1120         << SemaRef.LoopWithoutSeqInfo.Kind;
1121     return;
1122   }
1123   auto DiagIncVar = [this] {
1124     SemaRef.Diag((*Inc)->getBeginLoc(), diag::err_acc_loop_not_monotonic)
1125         << SemaRef.LoopWithoutSeqInfo.Kind;
1126     SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)
1127         << SemaRef.LoopWithoutSeqInfo.Kind;
1128     return;
1129   };
1130 
1131   if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(*Inc))
1132     Inc = ExprTemp->getSubExpr();
1133   if (const auto *E = dyn_cast<Expr>(*Inc))
1134     Inc = E->IgnoreParenImpCasts();
1135 
1136   auto getDeclFromExpr = [](const Expr *E) -> const ValueDecl * {
1137     E = E->IgnoreParenImpCasts();
1138     if (const auto *FE = dyn_cast<FullExpr>(E))
1139       E = FE->getSubExpr();
1140 
1141     E = E->IgnoreParenImpCasts();
1142 
1143     if (!E)
1144       return nullptr;
1145     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
1146       return dyn_cast<ValueDecl>(DRE->getDecl());
1147 
1148     if (const auto *ME = dyn_cast<MemberExpr>(E))
1149       if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1150         return ME->getMemberDecl();
1151 
1152     return nullptr;
1153   };
1154 
1155   const ValueDecl *IncVar = nullptr;
1156 
1157   // Here we enforce the monotonically increase/decrease:
1158   if (const auto *UO = dyn_cast<UnaryOperator>(*Inc)) {
1159     // Allow increment/decrement ops.
1160     if (!UO->isIncrementDecrementOp())
1161       return DiagIncVar();
1162     IncVar = getDeclFromExpr(UO->getSubExpr());
1163   } else if (const auto *BO = dyn_cast<BinaryOperator>(*Inc)) {
1164     switch (BO->getOpcode()) {
1165     default:
1166       return DiagIncVar();
1167     case BO_AddAssign:
1168     case BO_SubAssign:
1169     case BO_MulAssign:
1170     case BO_DivAssign:
1171     case BO_Assign:
1172       // += -= *= /= should all be fine here, this should be all of the
1173       // 'monotonical' compound-assign ops.
1174       // Assignment we just give up on, we could do better, and ensure that it
1175       // is a binary/operator expr doing more work, but that seems like a lot
1176       // of work for an error prone check.
1177       break;
1178     }
1179     IncVar = getDeclFromExpr(BO->getLHS());
1180   } else if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(*Inc)) {
1181     switch (CE->getOperator()) {
1182     default:
1183       return DiagIncVar();
1184     case OO_PlusPlus:
1185     case OO_MinusMinus:
1186     case OO_PlusEqual:
1187     case OO_MinusEqual:
1188     case OO_StarEqual:
1189     case OO_SlashEqual:
1190     case OO_Equal:
1191       // += -= *= /= should all be fine here, this should be all of the
1192       // 'monotonical' compound-assign ops.
1193       // Assignment we just give up on, we could do better, and ensure that it
1194       // is a binary/operator expr doing more work, but that seems like a lot
1195       // of work for an error prone check.
1196       break;
1197     }
1198 
1199     IncVar = getDeclFromExpr(CE->getArg(0));
1200 
1201   } else if (const auto *ME = dyn_cast<CXXMemberCallExpr>(*Inc)) {
1202     IncVar = getDeclFromExpr(ME->getImplicitObjectArgument());
1203     // We can't really do much for member expressions, other than hope they are
1204     // doing the right thing, so give up here.
1205   }
1206 
1207   if (!IncVar)
1208     return DiagIncVar();
1209 
1210   // InitVar shouldn't be null unless there was an error, so don't diagnose if
1211   // that is the case. Else we should ensure that it refers to the  loop
1212   // value.
1213   if (Init && IncVar->getCanonicalDecl() != Init->getCanonicalDecl())
1214     return DiagIncVar();
1215 
1216   return;
1217 }
1218 
1219 void SemaOpenACC::ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst,
1220                                     const Stmt *First, const Stmt *OldSecond,
1221                                     const Stmt *Second, const Stmt *OldThird,
1222                                     const Stmt *Third) {
1223   if (!getLangOpts().OpenACC)
1224     return;
1225 
1226   std::optional<const Stmt *> S;
1227   if (OldSecond == Second)
1228     S = std::nullopt;
1229   else
1230     S = Second;
1231   std::optional<const Stmt *> T;
1232   if (OldThird == Third)
1233     S = std::nullopt;
1234   else
1235     S = Third;
1236 
1237   bool InitChanged = false;
1238   if (OldFirst != First) {
1239     InitChanged = true;
1240 
1241     // VarDecls are always rebuild because they are dependent, so we can do a
1242     // little work to suppress some of the double checking based on whether the
1243     // type is instantiation dependent.
1244     QualType OldVDTy;
1245     QualType NewVDTy;
1246     if (const auto *DS = dyn_cast<DeclStmt>(OldFirst))
1247       if (const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1248               DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
1249         OldVDTy = VD->getType();
1250     if (const auto *DS = dyn_cast<DeclStmt>(First))
1251       if (const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1252               DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
1253         NewVDTy = VD->getType();
1254 
1255     if (!OldVDTy.isNull() && !NewVDTy.isNull())
1256       InitChanged = OldVDTy->isInstantiationDependentType() !=
1257                     NewVDTy->isInstantiationDependentType();
1258   }
1259 
1260   ForStmtBeginChecker FSBC{*this, ForLoc, First, InitChanged, S, T};
1261   if (!LoopInfo.TopLevelLoopSeen) {
1262     FSBC.check();
1263   }
1264 
1265   ForStmtBeginHelper(ForLoc, FSBC);
1266 }
1267 
1268 void SemaOpenACC::ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First,
1269                                     const Stmt *Second, const Stmt *Third) {
1270   if (!getLangOpts().OpenACC)
1271     return;
1272 
1273   ForStmtBeginChecker FSBC{*this,  ForLoc, First, /*InitChanged=*/true,
1274                            Second, Third};
1275   if (!LoopInfo.TopLevelLoopSeen) {
1276     FSBC.check();
1277   }
1278 
1279   ForStmtBeginHelper(ForLoc, FSBC);
1280 }
1281 
1282 void SemaOpenACC::ActOnRangeForStmtBegin(SourceLocation ForLoc,
1283                                          const Stmt *OldRangeFor,
1284                                          const Stmt *RangeFor) {
1285   if (!getLangOpts().OpenACC)
1286     return;
1287 
1288   std::optional<const CXXForRangeStmt *> RF;
1289 
1290   if (OldRangeFor == RangeFor)
1291     RF = std::nullopt;
1292   else
1293     RF = cast<CXXForRangeStmt>(RangeFor);
1294 
1295   ForStmtBeginChecker FSBC{*this, ForLoc, RF};
1296   if (!LoopInfo.TopLevelLoopSeen) {
1297     FSBC.check();
1298   }
1299   ForStmtBeginHelper(ForLoc, FSBC);
1300 }
1301 
1302 void SemaOpenACC::ActOnRangeForStmtBegin(SourceLocation ForLoc,
1303                                          const Stmt *RangeFor) {
1304   if (!getLangOpts().OpenACC)
1305     return;
1306 
1307   ForStmtBeginChecker FSBC{*this, ForLoc, cast<CXXForRangeStmt>(RangeFor)};
1308   if (!LoopInfo.TopLevelLoopSeen) {
1309     FSBC.check();
1310   }
1311   ForStmtBeginHelper(ForLoc, FSBC);
1312 }
1313 
1314 namespace {
1315 SourceLocation FindInterveningCodeInLoop(const Stmt *CurStmt) {
1316   // We should diagnose on anything except `CompoundStmt`, `NullStmt`,
1317   // `ForStmt`, `CXXForRangeStmt`, since those are legal, and `WhileStmt` and
1318   // `DoStmt`, as those are caught as a violation elsewhere.
1319   // For `CompoundStmt` we need to search inside of it.
1320   if (!CurStmt ||
1321       isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(
1322           CurStmt))
1323     return SourceLocation{};
1324 
1325   // Any other construct is an error anyway, so it has already been diagnosed.
1326   if (isa<OpenACCConstructStmt>(CurStmt))
1327     return SourceLocation{};
1328 
1329   // Search inside the compound statement, this allows for arbitrary nesting
1330   // of compound statements, as long as there isn't any code inside.
1331   if (const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1332     for (const auto *ChildStmt : CS->children()) {
1333       SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1334       if (ChildStmtLoc.isValid())
1335         return ChildStmtLoc;
1336     }
1337     // Empty/not invalid compound statements are legal.
1338     return SourceLocation{};
1339   }
1340   return CurStmt->getBeginLoc();
1341 }
1342 } // namespace
1343 
1344 void SemaOpenACC::ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body) {
1345   if (!getLangOpts().OpenACC)
1346     return;
1347 
1348   // Set this to 'true' so if we find another one at this level we can diagnose.
1349   LoopInfo.CurLevelHasLoopAlready = true;
1350 
1351   if (!Body.isUsable())
1352     return;
1353 
1354   bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1355                           *CollapseInfo.CurCollapseCount > 0 &&
1356                           !CollapseInfo.ActiveCollapse->hasForce();
1357   bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1358 
1359   if (IsActiveCollapse || IsActiveTile) {
1360     SourceLocation OtherStmtLoc = FindInterveningCodeInLoop(Body.get());
1361 
1362     if (OtherStmtLoc.isValid() && IsActiveCollapse) {
1363       Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1364           << OpenACCClauseKind::Collapse << CollapseInfo.DirectiveKind;
1365       Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1366            diag::note_acc_active_clause_here)
1367           << OpenACCClauseKind::Collapse;
1368     }
1369 
1370     if (OtherStmtLoc.isValid() && IsActiveTile) {
1371       Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1372           << OpenACCClauseKind::Tile << TileInfo.DirectiveKind;
1373       Diag(TileInfo.ActiveTile->getBeginLoc(),
1374            diag::note_acc_active_clause_here)
1375           << OpenACCClauseKind::Tile;
1376     }
1377   }
1378 }
1379 
1380 namespace {
1381 // Get a list of clause Kinds for diagnosing a list, joined by a commas and an
1382 // 'or'.
1383 std::string GetListOfClauses(llvm::ArrayRef<OpenACCClauseKind> Clauses) {
1384   assert(!Clauses.empty() && "empty clause list not supported");
1385 
1386   std::string Output;
1387   llvm::raw_string_ostream OS{Output};
1388 
1389   if (Clauses.size() == 1) {
1390     OS << '\'' << Clauses[0] << '\'';
1391     return Output;
1392   }
1393 
1394   llvm::ArrayRef<OpenACCClauseKind> AllButLast{Clauses.begin(),
1395                                                Clauses.end() - 1};
1396 
1397   llvm::interleave(
1398       AllButLast, [&](OpenACCClauseKind K) { OS << '\'' << K << '\''; },
1399       [&] { OS << ", "; });
1400 
1401   OS << " or \'" << Clauses.back() << '\'';
1402   return Output;
1403 }
1404 } // namespace
1405 
1406 bool SemaOpenACC::ActOnStartStmtDirective(
1407     OpenACCDirectiveKind K, SourceLocation StartLoc,
1408     ArrayRef<const OpenACCClause *> Clauses) {
1409   SemaRef.DiscardCleanupsInEvaluationContext();
1410   SemaRef.PopExpressionEvaluationContext();
1411 
1412   // OpenACC 3.3 2.9.1:
1413   // Intervening code must not contain other OpenACC directives or calls to API
1414   // routines.
1415   //
1416   // ALL constructs are ill-formed if there is an active 'collapse'
1417   if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1418     Diag(StartLoc, diag::err_acc_invalid_in_loop)
1419         << /*OpenACC Construct*/ 0 << CollapseInfo.DirectiveKind
1420         << OpenACCClauseKind::Collapse << K;
1421     assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
1422     Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1423          diag::note_acc_active_clause_here)
1424         << OpenACCClauseKind::Collapse;
1425   }
1426   if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1427     Diag(StartLoc, diag::err_acc_invalid_in_loop)
1428         << /*OpenACC Construct*/ 0 << TileInfo.DirectiveKind
1429         << OpenACCClauseKind::Tile << K;
1430     assert(TileInfo.ActiveTile && "Tile count without object?");
1431     Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1432         << OpenACCClauseKind::Tile;
1433   }
1434 
1435   // OpenACC3.3 2.6.5: At least one copy, copyin, copyout, create, no_create,
1436   // present, deviceptr, attach, or default clause must appear on a 'data'
1437   // construct.
1438   if (K == OpenACCDirectiveKind::Data &&
1439       llvm::find_if(Clauses,
1440                     llvm::IsaPred<OpenACCCopyClause, OpenACCCopyInClause,
1441                                   OpenACCCopyOutClause, OpenACCCreateClause,
1442                                   OpenACCNoCreateClause, OpenACCPresentClause,
1443                                   OpenACCDevicePtrClause, OpenACCAttachClause,
1444                                   OpenACCDefaultClause>) == Clauses.end())
1445     return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1446            << K
1447            << GetListOfClauses(
1448                   {OpenACCClauseKind::Copy, OpenACCClauseKind::CopyIn,
1449                    OpenACCClauseKind::CopyOut, OpenACCClauseKind::Create,
1450                    OpenACCClauseKind::NoCreate, OpenACCClauseKind::Present,
1451                    OpenACCClauseKind::DevicePtr, OpenACCClauseKind::Attach,
1452                    OpenACCClauseKind::Default});
1453 
1454   // OpenACC3.3 2.6.6: At least one copyin, create, or attach clause must appear
1455   // on an enter data directive.
1456   if (K == OpenACCDirectiveKind::EnterData &&
1457       llvm::find_if(Clauses,
1458                     llvm::IsaPred<OpenACCCopyInClause, OpenACCCreateClause,
1459                                   OpenACCAttachClause>) == Clauses.end())
1460     return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1461            << K
1462            << GetListOfClauses({
1463                   OpenACCClauseKind::CopyIn,
1464                   OpenACCClauseKind::Create,
1465                   OpenACCClauseKind::Attach,
1466               });
1467   // OpenACC3.3 2.6.6: At least one copyout, delete, or detach clause must
1468   // appear on an exit data directive.
1469   if (K == OpenACCDirectiveKind::ExitData &&
1470       llvm::find_if(Clauses,
1471                     llvm::IsaPred<OpenACCCopyOutClause, OpenACCDeleteClause,
1472                                   OpenACCDetachClause>) == Clauses.end())
1473     return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1474            << K
1475            << GetListOfClauses({
1476                   OpenACCClauseKind::CopyOut,
1477                   OpenACCClauseKind::Delete,
1478                   OpenACCClauseKind::Detach,
1479               });
1480 
1481   // OpenACC3.3 2.8: At least 'one use_device' clause must appear.
1482   if (K == OpenACCDirectiveKind::HostData &&
1483       llvm::find_if(Clauses, llvm::IsaPred<OpenACCUseDeviceClause>) ==
1484           Clauses.end())
1485     return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1486            << K << GetListOfClauses({OpenACCClauseKind::UseDevice});
1487 
1488   // OpenACC3.3 2.14.3: At least one default_async, device_num, or device_type
1489   // clause must appear.
1490   if (K == OpenACCDirectiveKind::Set &&
1491       llvm::find_if(
1492           Clauses,
1493           llvm::IsaPred<OpenACCDefaultAsyncClause, OpenACCDeviceNumClause,
1494                         OpenACCDeviceTypeClause, OpenACCIfClause>) ==
1495           Clauses.end())
1496     return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1497            << K
1498            << GetListOfClauses({OpenACCClauseKind::DefaultAsync,
1499                                 OpenACCClauseKind::DeviceNum,
1500                                 OpenACCClauseKind::DeviceType,
1501                                 OpenACCClauseKind::If});
1502 
1503   // OpenACC3.3 2.14.4: At least one self, host, or device clause must appear on
1504   // an update directive.
1505   if (K == OpenACCDirectiveKind::Update &&
1506       llvm::find_if(Clauses, llvm::IsaPred<OpenACCSelfClause, OpenACCHostClause,
1507                                            OpenACCDeviceClause>) ==
1508           Clauses.end())
1509     return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1510            << K
1511            << GetListOfClauses({OpenACCClauseKind::Self,
1512                                 OpenACCClauseKind::Host,
1513                                 OpenACCClauseKind::Device});
1514 
1515   return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
1516 }
1517 
1518 StmtResult SemaOpenACC::ActOnEndStmtDirective(
1519     OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc,
1520     SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
1521     SourceLocation RParenLoc, SourceLocation EndLoc,
1522     ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt) {
1523   switch (K) {
1524   default:
1525     return StmtEmpty();
1526   case OpenACCDirectiveKind::Invalid:
1527     return StmtError();
1528   case OpenACCDirectiveKind::Parallel:
1529   case OpenACCDirectiveKind::Serial:
1530   case OpenACCDirectiveKind::Kernels: {
1531     return OpenACCComputeConstruct::Create(
1532         getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
1533         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1534   }
1535   case OpenACCDirectiveKind::ParallelLoop:
1536   case OpenACCDirectiveKind::SerialLoop:
1537   case OpenACCDirectiveKind::KernelsLoop: {
1538     return OpenACCCombinedConstruct::Create(
1539         getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
1540         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1541   }
1542   case OpenACCDirectiveKind::Loop: {
1543     return OpenACCLoopConstruct::Create(
1544         getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
1545         EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1546   }
1547   case OpenACCDirectiveKind::Data: {
1548     return OpenACCDataConstruct::Create(
1549         getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
1550         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1551   }
1552   case OpenACCDirectiveKind::EnterData: {
1553     return OpenACCEnterDataConstruct::Create(getASTContext(), StartLoc, DirLoc,
1554                                              EndLoc, Clauses);
1555   }
1556   case OpenACCDirectiveKind::ExitData: {
1557     return OpenACCExitDataConstruct::Create(getASTContext(), StartLoc, DirLoc,
1558                                             EndLoc, Clauses);
1559   }
1560   case OpenACCDirectiveKind::HostData: {
1561     return OpenACCHostDataConstruct::Create(
1562         getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
1563         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1564   }
1565   case OpenACCDirectiveKind::Wait: {
1566     return OpenACCWaitConstruct::Create(
1567         getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
1568         Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
1569   }
1570   case OpenACCDirectiveKind::Init: {
1571     return OpenACCInitConstruct::Create(getASTContext(), StartLoc, DirLoc,
1572                                         EndLoc, Clauses);
1573   }
1574   case OpenACCDirectiveKind::Shutdown: {
1575     return OpenACCShutdownConstruct::Create(getASTContext(), StartLoc, DirLoc,
1576                                             EndLoc, Clauses);
1577   }
1578   case OpenACCDirectiveKind::Set: {
1579     return OpenACCSetConstruct::Create(getASTContext(), StartLoc, DirLoc,
1580                                        EndLoc, Clauses);
1581   }
1582   case OpenACCDirectiveKind::Update: {
1583     return OpenACCUpdateConstruct::Create(getASTContext(), StartLoc, DirLoc,
1584                                           EndLoc, Clauses);
1585   }
1586   }
1587   llvm_unreachable("Unhandled case in directive handling?");
1588 }
1589 
1590 StmtResult SemaOpenACC::ActOnAssociatedStmt(
1591     SourceLocation DirectiveLoc, OpenACCDirectiveKind K,
1592     ArrayRef<const OpenACCClause *> Clauses, StmtResult AssocStmt) {
1593   switch (K) {
1594   default:
1595     llvm_unreachable("Unimplemented associated statement application");
1596   case OpenACCDirectiveKind::EnterData:
1597   case OpenACCDirectiveKind::ExitData:
1598   case OpenACCDirectiveKind::Wait:
1599   case OpenACCDirectiveKind::Init:
1600   case OpenACCDirectiveKind::Shutdown:
1601   case OpenACCDirectiveKind::Set:
1602     llvm_unreachable(
1603         "these don't have associated statements, so shouldn't get here");
1604   case OpenACCDirectiveKind::Parallel:
1605   case OpenACCDirectiveKind::Serial:
1606   case OpenACCDirectiveKind::Kernels:
1607   case OpenACCDirectiveKind::Data:
1608   case OpenACCDirectiveKind::HostData:
1609     // There really isn't any checking here that could happen. As long as we
1610     // have a statement to associate, this should be fine.
1611     // OpenACC 3.3 Section 6:
1612     // Structured Block: in C or C++, an executable statement, possibly
1613     // compound, with a single entry at the top and a single exit at the
1614     // bottom.
1615     // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and
1616     // an interpretation of it is to allow this and treat the initializer as
1617     // the 'structured block'.
1618     return AssocStmt;
1619   case OpenACCDirectiveKind::Loop:
1620   case OpenACCDirectiveKind::ParallelLoop:
1621   case OpenACCDirectiveKind::SerialLoop:
1622   case OpenACCDirectiveKind::KernelsLoop:
1623     if (!AssocStmt.isUsable())
1624       return StmtError();
1625 
1626     if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) {
1627       Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop)
1628           << K;
1629       Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
1630       return StmtError();
1631     }
1632 
1633     if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
1634       if (!CollapseInfo.CollapseDepthSatisfied) {
1635         Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
1636             << OpenACCClauseKind::Collapse;
1637         assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
1638         Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1639              diag::note_acc_active_clause_here)
1640             << OpenACCClauseKind::Collapse;
1641       }
1642 
1643       if (!TileInfo.TileDepthSatisfied) {
1644         Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
1645             << OpenACCClauseKind::Tile;
1646         assert(TileInfo.ActiveTile && "Collapse count without object?");
1647         Diag(TileInfo.ActiveTile->getBeginLoc(),
1648              diag::note_acc_active_clause_here)
1649             << OpenACCClauseKind::Tile;
1650       }
1651       return StmtError();
1652     }
1653 
1654     return AssocStmt.get();
1655   }
1656   llvm_unreachable("Invalid associated statement application");
1657 }
1658 
1659 bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K,
1660                                           SourceLocation StartLoc) {
1661   // OpenCC3.3 2.1 (line 889)
1662   // A program must not depend on the order of evaluation of expressions in
1663   // clause arguments or on any side effects of the evaluations.
1664   SemaRef.DiscardCleanupsInEvaluationContext();
1665   SemaRef.PopExpressionEvaluationContext();
1666   return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
1667 }
1668 
1669 DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; }
1670 
1671 ExprResult
1672 SemaOpenACC::BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
1673   return OpenACCAsteriskSizeExpr::Create(getASTContext(), AsteriskLoc);
1674 }
1675 
1676 ExprResult
1677 SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
1678   return BuildOpenACCAsteriskSizeExpr(AsteriskLoc);
1679 }
1680