xref: /freebsd/contrib/llvm-project/clang/lib/Sema/SemaOpenACC.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/Sema/SemaOpenACC.h"
15 #include "clang/AST/DeclOpenACC.h"
16 #include "clang/AST/StmtOpenACC.h"
17 #include "clang/Basic/DiagnosticSema.h"
18 #include "clang/Basic/OpenACCKinds.h"
19 #include "clang/Basic/SourceManager.h"
20 #include "clang/Sema/Scope.h"
21 #include "clang/Sema/Sema.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/Support/Casting.h"
24 
25 using namespace clang;
26 
27 namespace {
diagnoseConstructAppertainment(SemaOpenACC & S,OpenACCDirectiveKind K,SourceLocation StartLoc,bool IsStmt)28 bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K,
29                                     SourceLocation StartLoc, bool IsStmt) {
30   switch (K) {
31   default:
32   case OpenACCDirectiveKind::Invalid:
33     // Nothing to do here, both invalid and unimplemented don't really need to
34     // do anything.
35     break;
36   case OpenACCDirectiveKind::Parallel:
37   case OpenACCDirectiveKind::ParallelLoop:
38   case OpenACCDirectiveKind::Serial:
39   case OpenACCDirectiveKind::SerialLoop:
40   case OpenACCDirectiveKind::Kernels:
41   case OpenACCDirectiveKind::KernelsLoop:
42   case OpenACCDirectiveKind::Loop:
43   case OpenACCDirectiveKind::Data:
44   case OpenACCDirectiveKind::EnterData:
45   case OpenACCDirectiveKind::ExitData:
46   case OpenACCDirectiveKind::HostData:
47   case OpenACCDirectiveKind::Wait:
48   case OpenACCDirectiveKind::Update:
49   case OpenACCDirectiveKind::Init:
50   case OpenACCDirectiveKind::Shutdown:
51   case OpenACCDirectiveKind::Cache:
52   case OpenACCDirectiveKind::Atomic:
53     if (!IsStmt)
54       return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
55     break;
56   }
57   return false;
58 }
59 
CollectActiveReductionClauses(llvm::SmallVector<OpenACCReductionClause * > & ActiveClauses,ArrayRef<OpenACCClause * > CurClauses)60 void CollectActiveReductionClauses(
61     llvm::SmallVector<OpenACCReductionClause *> &ActiveClauses,
62     ArrayRef<OpenACCClause *> CurClauses) {
63   for (auto *CurClause : CurClauses) {
64     if (auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause);
65         RedClause && !RedClause->getVarList().empty())
66       ActiveClauses.push_back(RedClause);
67   }
68 }
69 
70 // Depth needs to be preserved for all associated statements that aren't
71 // supposed to modify the compute/combined/loop construct information.
PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK)72 bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) {
73   switch (DK) {
74   case OpenACCDirectiveKind::Parallel:
75   case OpenACCDirectiveKind::ParallelLoop:
76   case OpenACCDirectiveKind::Serial:
77   case OpenACCDirectiveKind::SerialLoop:
78   case OpenACCDirectiveKind::Kernels:
79   case OpenACCDirectiveKind::KernelsLoop:
80   case OpenACCDirectiveKind::Loop:
81     return false;
82   case OpenACCDirectiveKind::Data:
83   case OpenACCDirectiveKind::HostData:
84   case OpenACCDirectiveKind::Atomic:
85     return true;
86   case OpenACCDirectiveKind::Cache:
87   case OpenACCDirectiveKind::Routine:
88   case OpenACCDirectiveKind::Declare:
89   case OpenACCDirectiveKind::EnterData:
90   case OpenACCDirectiveKind::ExitData:
91   case OpenACCDirectiveKind::Wait:
92   case OpenACCDirectiveKind::Init:
93   case OpenACCDirectiveKind::Shutdown:
94   case OpenACCDirectiveKind::Set:
95   case OpenACCDirectiveKind::Update:
96     llvm_unreachable("Doesn't have an associated stmt");
97   case OpenACCDirectiveKind::Invalid:
98     llvm_unreachable("Unhandled directive kind?");
99   }
100   llvm_unreachable("Unhandled directive kind?");
101 }
102 
103 } // namespace
104 
SemaOpenACC(Sema & S)105 SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {}
106 
AssociatedStmtRAII(SemaOpenACC & S,OpenACCDirectiveKind DK,SourceLocation DirLoc,ArrayRef<const OpenACCClause * > UnInstClauses,ArrayRef<OpenACCClause * > Clauses)107 SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
108     SemaOpenACC &S, OpenACCDirectiveKind DK, SourceLocation DirLoc,
109     ArrayRef<const OpenACCClause *> UnInstClauses,
110     ArrayRef<OpenACCClause *> Clauses)
111     : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
112       DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),
113       OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
114       OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),
115       OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),
116       ActiveReductionClauses(S.ActiveReductionClauses),
117       LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {
118 
119   // Compute constructs end up taking their 'loop'.
120   if (DirKind == OpenACCDirectiveKind::Parallel ||
121       DirKind == OpenACCDirectiveKind::Serial ||
122       DirKind == OpenACCDirectiveKind::Kernels) {
123     CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
124     SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
125     SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
126 
127     // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
128     // construct, the gang clause behaves as follows. ... The region of a loop
129     // with a gang clause may not contain another loop with a gang clause unless
130     // within a nested compute region.
131     //
132     // Implement the 'unless within a nested compute region' part.
133     SemaRef.LoopGangClauseOnKernel = {};
134     SemaRef.LoopWorkerClauseLoc = {};
135     SemaRef.LoopVectorClauseLoc = {};
136     SemaRef.LoopWithoutSeqInfo = {};
137   } else if (DirKind == OpenACCDirectiveKind::ParallelLoop ||
138              DirKind == OpenACCDirectiveKind::SerialLoop ||
139              DirKind == OpenACCDirectiveKind::KernelsLoop) {
140     SemaRef.ActiveComputeConstructInfo.Kind = DirKind;
141     SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;
142 
143     CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
144     SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
145     SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
146 
147     SemaRef.LoopGangClauseOnKernel = {};
148     SemaRef.LoopWorkerClauseLoc = {};
149     SemaRef.LoopVectorClauseLoc = {};
150 
151     // Set the active 'loop' location if there isn't a 'seq' on it, so we can
152     // diagnose the for loops.
153     SemaRef.LoopWithoutSeqInfo = {};
154     if (Clauses.end() ==
155         llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
156       SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
157 
158     // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
159     // construct, the gang clause behaves as follows. ... The region of a loop
160     // with a gang clause may not contain another loop with a gang clause unless
161     // within a nested compute region.
162     //
163     // We don't bother doing this when this is a template instantiation, as
164     // there is no reason to do these checks: the existance of a
165     // gang/kernels/etc cannot be dependent.
166     if (DirKind == OpenACCDirectiveKind::KernelsLoop && UnInstClauses.empty()) {
167       // This handles the 'outer loop' part of this.
168       auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
169       if (Itr != Clauses.end())
170         SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), DirKind};
171     }
172 
173     if (UnInstClauses.empty()) {
174       auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
175       if (Itr != Clauses.end())
176         SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
177 
178       auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
179       if (Itr2 != Clauses.end())
180         SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
181     }
182   } else if (DirKind == OpenACCDirectiveKind::Loop) {
183     CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);
184     SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
185     SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
186 
187     // Set the active 'loop' location if there isn't a 'seq' on it, so we can
188     // diagnose the for loops.
189     SemaRef.LoopWithoutSeqInfo = {};
190     if (Clauses.end() ==
191         llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>))
192       SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc};
193 
194     // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
195     // construct, the gang clause behaves as follows. ... The region of a loop
196     // with a gang clause may not contain another loop with a gang clause unless
197     // within a nested compute region.
198     //
199     // We don't bother doing this when this is a template instantiation, as
200     // there is no reason to do these checks: the existance of a
201     // gang/kernels/etc cannot be dependent.
202     if (SemaRef.getActiveComputeConstructInfo().Kind ==
203             OpenACCDirectiveKind::Kernels &&
204         UnInstClauses.empty()) {
205       // This handles the 'outer loop' part of this.
206       auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>);
207       if (Itr != Clauses.end())
208         SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(),
209                                           OpenACCDirectiveKind::Kernels};
210     }
211 
212     if (UnInstClauses.empty()) {
213       auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
214       if (Itr != Clauses.end())
215         SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
216 
217       auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>);
218       if (Itr2 != Clauses.end())
219         SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc();
220     }
221   }
222 }
223 
224 namespace {
225 // Given two collapse clauses, and the uninstanted version of the new one,
226 // return the 'best' one for the purposes of setting the collapse checking
227 // values.
228 const OpenACCCollapseClause *
getBestCollapseCandidate(const OpenACCCollapseClause * Old,const OpenACCCollapseClause * New,const OpenACCCollapseClause * UnInstNew)229 getBestCollapseCandidate(const OpenACCCollapseClause *Old,
230                          const OpenACCCollapseClause *New,
231                          const OpenACCCollapseClause *UnInstNew) {
232   // If the loop count is nullptr, it is because instantiation failed, so this
233   // can't be the best one.
234   if (!New->getLoopCount())
235     return Old;
236 
237   // If the loop-count had an error, than 'new' isn't a candidate.
238   if (!New->getLoopCount())
239     return Old;
240 
241   // Don't consider uninstantiated ones, since we can't really check these.
242   if (New->getLoopCount()->isInstantiationDependent())
243     return Old;
244 
245   // If this is an instantiation, and the old version wasn't instantation
246   // dependent, than nothing has changed and we've already done a diagnostic
247   // based on this one, so don't consider it.
248   if (UnInstNew && !UnInstNew->getLoopCount()->isInstantiationDependent())
249     return Old;
250 
251   // New is now a valid candidate, so if there isn't an old one at this point,
252   // New is the only valid one.
253   if (!Old)
254     return New;
255 
256   // If the 'New' expression has a larger value than 'Old', then it is the new
257   // best candidate.
258   if (cast<ConstantExpr>(Old->getLoopCount())->getResultAsAPSInt() <
259       cast<ConstantExpr>(New->getLoopCount())->getResultAsAPSInt())
260     return New;
261 
262   return Old;
263 }
264 } // namespace
265 
SetCollapseInfoBeforeAssociatedStmt(ArrayRef<const OpenACCClause * > UnInstClauses,ArrayRef<OpenACCClause * > Clauses)266 void SemaOpenACC::AssociatedStmtRAII::SetCollapseInfoBeforeAssociatedStmt(
267     ArrayRef<const OpenACCClause *> UnInstClauses,
268     ArrayRef<OpenACCClause *> Clauses) {
269 
270   // Reset this checking for loops that aren't covered in a RAII object.
271   SemaRef.LoopInfo.CurLevelHasLoopAlready = false;
272   SemaRef.CollapseInfo.CollapseDepthSatisfied = true;
273   SemaRef.CollapseInfo.CurCollapseCount = 0;
274   SemaRef.TileInfo.TileDepthSatisfied = true;
275 
276   // We make sure to take an optional list of uninstantiated clauses, so that
277   // we can check to make sure we don't 'double diagnose' in the event that
278   // the value of 'N' was not dependent in a template. Since we cannot count on
279   // there only being a single collapse clause, we count on the order to make
280   // sure get the matching ones, and we count on TreeTransform not removing
281   // these, even if loop-count instantiation failed. We can check the
282   // non-dependent ones right away, and realize that subsequent instantiation
283   // can only make it more specific.
284 
285   auto *UnInstClauseItr =
286       llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
287   auto *ClauseItr =
288       llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>);
289   const OpenACCCollapseClause *FoundClause = nullptr;
290 
291   // Loop through the list of Collapse clauses and find the one that:
292   // 1- Has a non-dependent, non-null loop count (null means error, likely
293   // during instantiation).
294   // 2- If UnInstClauses isn't empty, its corresponding
295   // loop count was dependent.
296   // 3- Has the largest 'loop count' of all.
297   while (ClauseItr != Clauses.end()) {
298     const OpenACCCollapseClause *CurClause =
299         cast<OpenACCCollapseClause>(*ClauseItr);
300     const OpenACCCollapseClause *UnInstCurClause =
301         UnInstClauseItr == UnInstClauses.end()
302             ? nullptr
303             : cast<OpenACCCollapseClause>(*UnInstClauseItr);
304 
305     FoundClause =
306         getBestCollapseCandidate(FoundClause, CurClause, UnInstCurClause);
307 
308     UnInstClauseItr =
309         UnInstClauseItr == UnInstClauses.end()
310             ? UnInstClauseItr
311             : std::find_if(std::next(UnInstClauseItr), UnInstClauses.end(),
312                            llvm::IsaPred<OpenACCCollapseClause>);
313     ClauseItr = std::find_if(std::next(ClauseItr), Clauses.end(),
314                              llvm::IsaPred<OpenACCCollapseClause>);
315   }
316 
317   if (!FoundClause)
318     return;
319 
320   SemaRef.CollapseInfo.ActiveCollapse = FoundClause;
321   SemaRef.CollapseInfo.CollapseDepthSatisfied = false;
322   SemaRef.CollapseInfo.CurCollapseCount =
323       cast<ConstantExpr>(FoundClause->getLoopCount())->getResultAsAPSInt();
324   SemaRef.CollapseInfo.DirectiveKind = DirKind;
325 }
326 
SetTileInfoBeforeAssociatedStmt(ArrayRef<const OpenACCClause * > UnInstClauses,ArrayRef<OpenACCClause * > Clauses)327 void SemaOpenACC::AssociatedStmtRAII::SetTileInfoBeforeAssociatedStmt(
328     ArrayRef<const OpenACCClause *> UnInstClauses,
329     ArrayRef<OpenACCClause *> Clauses) {
330   // We don't diagnose if this is during instantiation, since the only thing we
331   // care about is the number of arguments, which we can figure out without
332   // instantiation, so we don't want to double-diagnose.
333   if (UnInstClauses.size() > 0)
334     return;
335   auto *TileClauseItr =
336       llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>);
337 
338   if (Clauses.end() == TileClauseItr)
339     return;
340 
341   OpenACCTileClause *TileClause = cast<OpenACCTileClause>(*TileClauseItr);
342 
343   // Multiple tile clauses are allowed, so ensure that we use the one with the
344   // largest 'tile count'.
345   while (Clauses.end() !=
346          (TileClauseItr = std::find_if(std::next(TileClauseItr), Clauses.end(),
347                                        llvm::IsaPred<OpenACCTileClause>))) {
348     OpenACCTileClause *NewClause = cast<OpenACCTileClause>(*TileClauseItr);
349     if (NewClause->getSizeExprs().size() > TileClause->getSizeExprs().size())
350       TileClause = NewClause;
351   }
352 
353   SemaRef.TileInfo.ActiveTile = TileClause;
354   SemaRef.TileInfo.TileDepthSatisfied = false;
355   SemaRef.TileInfo.CurTileCount =
356       static_cast<unsigned>(TileClause->getSizeExprs().size());
357   SemaRef.TileInfo.DirectiveKind = DirKind;
358 }
359 
~AssociatedStmtRAII()360 SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() {
361   if (DirKind == OpenACCDirectiveKind::Parallel ||
362       DirKind == OpenACCDirectiveKind::Serial ||
363       DirKind == OpenACCDirectiveKind::Kernels ||
364       DirKind == OpenACCDirectiveKind::Loop ||
365       DirKind == OpenACCDirectiveKind::ParallelLoop ||
366       DirKind == OpenACCDirectiveKind::SerialLoop ||
367       DirKind == OpenACCDirectiveKind::KernelsLoop) {
368     SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
369     SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;
370     SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;
371     SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;
372     SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;
373     SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);
374   } else if (DirKind == OpenACCDirectiveKind::Data ||
375              DirKind == OpenACCDirectiveKind::HostData) {
376     // Intentionally doesn't reset the Loop, Compute Construct, or reduction
377     // effects.
378   }
379 }
380 
ActOnConstruct(OpenACCDirectiveKind K,SourceLocation DirLoc)381 void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
382                                  SourceLocation DirLoc) {
383   // Start an evaluation context to parse the clause arguments on.
384   SemaRef.PushExpressionEvaluationContext(
385       Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
386 
387   // There is nothing do do here as all we have at this point is the name of the
388   // construct itself.
389 }
390 
ActOnIntExpr(OpenACCDirectiveKind DK,OpenACCClauseKind CK,SourceLocation Loc,Expr * IntExpr)391 ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK,
392                                      OpenACCClauseKind CK, SourceLocation Loc,
393                                      Expr *IntExpr) {
394 
395   assert(((DK != OpenACCDirectiveKind::Invalid &&
396            CK == OpenACCClauseKind::Invalid) ||
397           (DK == OpenACCDirectiveKind::Invalid &&
398            CK != OpenACCClauseKind::Invalid) ||
399           (DK == OpenACCDirectiveKind::Invalid &&
400            CK == OpenACCClauseKind::Invalid)) &&
401          "Only one of directive or clause kind should be provided");
402 
403   class IntExprConverter : public Sema::ICEConvertDiagnoser {
404     OpenACCDirectiveKind DirectiveKind;
405     OpenACCClauseKind ClauseKind;
406     Expr *IntExpr;
407 
408     // gets the index into the diagnostics so we can use this for clauses,
409     // directives, and sub array.s
410     unsigned getDiagKind() const {
411       if (ClauseKind != OpenACCClauseKind::Invalid)
412         return 0;
413       if (DirectiveKind != OpenACCDirectiveKind::Invalid)
414         return 1;
415       return 2;
416     }
417 
418   public:
419     IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
420                      Expr *IntExpr)
421         : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false,
422                               /*Suppress=*/false,
423                               /*SuppressConversion=*/true),
424           DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
425 
426     bool match(QualType T) override {
427       // OpenACC spec just calls this 'integer expression' as having an
428       // 'integer type', so fall back on C99's 'integer type'.
429       return T->isIntegerType();
430     }
431     SemaBase::SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
432                                                    QualType T) override {
433       return S.Diag(Loc, diag::err_acc_int_expr_requires_integer)
434              << getDiagKind() << ClauseKind << DirectiveKind << T;
435     }
436 
437     SemaBase::SemaDiagnosticBuilder
438     diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override {
439       return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
440              << T << IntExpr->getSourceRange();
441     }
442 
443     SemaBase::SemaDiagnosticBuilder
444     diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T,
445                          QualType ConvTy) override {
446       return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
447              << T << ConvTy;
448     }
449 
450     SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S,
451                                                      CXXConversionDecl *Conv,
452                                                      QualType ConvTy) override {
453       return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
454              << ConvTy->isEnumeralType() << ConvTy;
455     }
456 
457     SemaBase::SemaDiagnosticBuilder
458     diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override {
459       return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T;
460     }
461 
462     SemaBase::SemaDiagnosticBuilder
463     noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
464       return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
465              << ConvTy->isEnumeralType() << ConvTy;
466     }
467 
468     SemaBase::SemaDiagnosticBuilder
469     diagnoseConversion(Sema &S, SourceLocation Loc, QualType T,
470                        QualType ConvTy) override {
471       llvm_unreachable("conversion functions are permitted");
472     }
473   } IntExprDiagnoser(DK, CK, IntExpr);
474 
475   if (!IntExpr)
476     return ExprError();
477 
478   ExprResult IntExprResult = SemaRef.PerformContextualImplicitConversion(
479       Loc, IntExpr, IntExprDiagnoser);
480   if (IntExprResult.isInvalid())
481     return ExprError();
482 
483   IntExpr = IntExprResult.get();
484   if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType())
485     return ExprError();
486 
487   // TODO OpenACC: Do we want to perform usual unary conversions here? When
488   // doing codegen we might find that is necessary, but skip it for now.
489   return IntExpr;
490 }
491 
CheckVarIsPointerType(OpenACCClauseKind ClauseKind,Expr * VarExpr)492 bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind,
493                                         Expr *VarExpr) {
494   // We already know that VarExpr is a proper reference to a variable, so we
495   // should be able to just take the type of the expression to get the type of
496   // the referenced variable.
497 
498   // We've already seen an error, don't diagnose anything else.
499   if (!VarExpr || VarExpr->containsErrors())
500     return false;
501 
502   if (isa<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()) ||
503       VarExpr->hasPlaceholderType(BuiltinType::ArraySection)) {
504     Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << /*OpenACC=*/0;
505     Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var);
506     return true;
507   }
508 
509   QualType Ty = VarExpr->getType();
510   Ty = Ty.getNonReferenceType().getUnqualifiedType();
511 
512   // Nothing we can do if this is a dependent type.
513   if (Ty->isDependentType())
514     return false;
515 
516   if (!Ty->isPointerType())
517     return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type)
518            << ClauseKind << Ty;
519   return false;
520 }
521 
ActOnStartParseVar(OpenACCDirectiveKind DK,OpenACCClauseKind CK)522 void SemaOpenACC::ActOnStartParseVar(OpenACCDirectiveKind DK,
523                                      OpenACCClauseKind CK) {
524   if (DK == OpenACCDirectiveKind::Cache) {
525     CacheInfo.ParsingCacheVarList = true;
526     CacheInfo.IsInvalidCacheRef = false;
527   }
528 }
529 
ActOnInvalidParseVar()530 void SemaOpenACC::ActOnInvalidParseVar() {
531   CacheInfo.ParsingCacheVarList = false;
532   CacheInfo.IsInvalidCacheRef = false;
533 }
534 
ActOnCacheVar(Expr * VarExpr)535 ExprResult SemaOpenACC::ActOnCacheVar(Expr *VarExpr) {
536   Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
537   // Clear this here, so we can do the returns based on the invalid cache ref
538   // here.  Note all return statements in this function must return ExprError if
539   // IsInvalidCacheRef. However, instead of doing an 'early return' in that
540   // case, we can let the rest of the diagnostics happen, as the invalid decl
541   // ref is a warning.
542   bool WasParsingInvalidCacheRef =
543       CacheInfo.ParsingCacheVarList && CacheInfo.IsInvalidCacheRef;
544   CacheInfo.ParsingCacheVarList = false;
545   CacheInfo.IsInvalidCacheRef = false;
546 
547   if (!isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
548     Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_cache);
549     return ExprError();
550   }
551 
552   // It isn't clear what 'simple array element or simple subarray' means, so we
553   // will just allow arbitrary depth.
554   while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
555     if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
556       CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts();
557     else
558       CurVarExpr =
559           cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts();
560   }
561 
562   // References to a VarDecl are fine.
563   if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
564     if (isa<VarDecl, NonTypeTemplateParmDecl>(
565             DRE->getFoundDecl()->getCanonicalDecl()))
566       return WasParsingInvalidCacheRef ? ExprEmpty() : VarExpr;
567   }
568 
569   if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
570     if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl())) {
571       return WasParsingInvalidCacheRef ? ExprEmpty() : VarExpr;
572     }
573   }
574 
575   // Nothing really we can do here, as these are dependent.  So just return they
576   // are valid.
577   if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(CurVarExpr))
578     return WasParsingInvalidCacheRef ? ExprEmpty() : VarExpr;
579 
580   // There isn't really anything we can do in the case of a recovery expr, so
581   // skip the diagnostic rather than produce a confusing diagnostic.
582   if (isa<RecoveryExpr>(CurVarExpr))
583     return ExprError();
584 
585   Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_cache);
586   return ExprError();
587 }
588 
CheckDeclReference(SourceLocation Loc,Expr * E,Decl * D)589 void SemaOpenACC::CheckDeclReference(SourceLocation Loc, Expr *E, Decl *D) {
590   if (!getLangOpts().OpenACC || !CacheInfo.ParsingCacheVarList || !D ||
591       D->isInvalidDecl())
592     return;
593   // A 'cache' variable reference MUST be declared before the 'acc.loop' we
594   // generate in codegen, so we have to mark it invalid here in some way.  We do
595   // so in a bit of a convoluted way as there is no good way to put this into
596   // the AST, so we store it in SemaOpenACC State.  We can check the Scope
597   // during parsing to make sure there is a 'loop' before the decl is
598   // declared(and skip during instantiation).
599   // We only diagnose this as a warning, as this isn't required by the standard
600   // (unless you take a VERY awkward reading of some awkward prose).
601 
602   Scope *CurScope = SemaRef.getCurScope();
603 
604   // if we are at TU level, we are either doing some EXTRA wacky, or are in a
605   // template instantiation, so just give up.
606   if (CurScope->getDepth() == 0)
607     return;
608 
609   while (CurScope) {
610     // If we run into a loop construct scope, than this is 'correct' in that the
611     // declaration is outside of the loop.
612     if (CurScope->isOpenACCLoopConstructScope())
613       return;
614 
615     if (CurScope->isDeclScope(D)) {
616       Diag(Loc, diag::warn_acc_cache_var_not_outside_loop);
617 
618       CacheInfo.IsInvalidCacheRef = true;
619     }
620 
621     CurScope = CurScope->getParent();
622   }
623   // If we don't find the decl at all, we assume that it must be outside of the
624   // loop (or we aren't in a loop!) so skip the diagnostic.
625 }
626 
ActOnVar(OpenACCDirectiveKind DK,OpenACCClauseKind CK,Expr * VarExpr)627 ExprResult SemaOpenACC::ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
628                                  Expr *VarExpr) {
629   // This has unique enough restrictions that we should split it to a separate
630   // function.
631   if (DK == OpenACCDirectiveKind::Cache)
632     return ActOnCacheVar(VarExpr);
633 
634   Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
635 
636   // 'use_device' doesn't allow array subscript or array sections.
637   // OpenACC3.3 2.8:
638   // A 'var' in a 'use_device' clause must be the name of a variable or array.
639   // OpenACC3.3 2.13:
640   // A 'var' in a 'declare' directive must be a variable or array name.
641   if ((CK == OpenACCClauseKind::UseDevice ||
642        DK == OpenACCDirectiveKind::Declare) &&
643       isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
644     Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
645         << (DK == OpenACCDirectiveKind::Declare);
646     return ExprError();
647   }
648 
649   // Sub-arrays/subscript-exprs are fine as long as the base is a
650   // VarExpr/MemberExpr. So strip all of those off.
651   while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
652     if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
653       CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts();
654     else
655       CurVarExpr =
656           cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts();
657   }
658 
659   // References to a VarDecl are fine.
660   if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
661     if (isa<VarDecl, NonTypeTemplateParmDecl>(
662             DRE->getFoundDecl()->getCanonicalDecl()))
663       return VarExpr;
664   }
665 
666   // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a
667   // reduction clause must be a scalar variable name, an aggregate variable
668   // name, an array element, or a subarray.
669   // If CK is a 'use_device', this also isn't valid, as it isn't the name of a
670   // variable or array, if not done as a member expr.
671   // A MemberExpr that references a Field is valid for other clauses.
672   if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
673     if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl())) {
674       if (DK == OpenACCDirectiveKind::Declare ||
675           CK == OpenACCClauseKind::Reduction ||
676           CK == OpenACCClauseKind::UseDevice) {
677 
678         // We can allow 'member expr' if the 'this' is implicit in the case of
679         // declare, reduction, and use_device.
680         const auto *This = dyn_cast<CXXThisExpr>(ME->getBase());
681         if (This && This->isImplicit())
682           return VarExpr;
683       } else {
684         return VarExpr;
685       }
686     }
687   }
688 
689   // Referring to 'this' is ok for the most part, but for 'use_device'/'declare'
690   // doesn't fall into 'variable or array name'
691   if (CK != OpenACCClauseKind::UseDevice &&
692       DK != OpenACCDirectiveKind::Declare && isa<CXXThisExpr>(CurVarExpr))
693     return VarExpr;
694 
695   // Nothing really we can do here, as these are dependent.  So just return they
696   // are valid.
697   if (isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
698       (CK != OpenACCClauseKind::Reduction &&
699        isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
700     return VarExpr;
701 
702   // There isn't really anything we can do in the case of a recovery expr, so
703   // skip the diagnostic rather than produce a confusing diagnostic.
704   if (isa<RecoveryExpr>(CurVarExpr))
705     return ExprError();
706 
707   if (DK == OpenACCDirectiveKind::Declare)
708     Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
709         << /*declare*/ 1;
710   else if (CK == OpenACCClauseKind::UseDevice)
711     Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
712         << /*use_device*/ 0;
713   else
714     Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)
715         << (CK != OpenACCClauseKind::Reduction);
716   return ExprError();
717 }
718 
ActOnArraySectionExpr(Expr * Base,SourceLocation LBLoc,Expr * LowerBound,SourceLocation ColonLoc,Expr * Length,SourceLocation RBLoc)719 ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
720                                               Expr *LowerBound,
721                                               SourceLocation ColonLoc,
722                                               Expr *Length,
723                                               SourceLocation RBLoc) {
724   ASTContext &Context = getASTContext();
725 
726   // Handle placeholders.
727   if (Base->hasPlaceholderType() &&
728       !Base->hasPlaceholderType(BuiltinType::ArraySection)) {
729     ExprResult Result = SemaRef.CheckPlaceholderExpr(Base);
730     if (Result.isInvalid())
731       return ExprError();
732     Base = Result.get();
733   }
734   if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) {
735     ExprResult Result = SemaRef.CheckPlaceholderExpr(LowerBound);
736     if (Result.isInvalid())
737       return ExprError();
738     Result = SemaRef.DefaultLvalueConversion(Result.get());
739     if (Result.isInvalid())
740       return ExprError();
741     LowerBound = Result.get();
742   }
743   if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
744     ExprResult Result = SemaRef.CheckPlaceholderExpr(Length);
745     if (Result.isInvalid())
746       return ExprError();
747     Result = SemaRef.DefaultLvalueConversion(Result.get());
748     if (Result.isInvalid())
749       return ExprError();
750     Length = Result.get();
751   }
752 
753   // Check the 'base' value, it must be an array or pointer type, and not to/of
754   // a function type.
755   QualType OriginalBaseTy = ArraySectionExpr::getBaseOriginalType(Base);
756   QualType ResultTy;
757   if (!Base->isTypeDependent()) {
758     if (OriginalBaseTy->isAnyPointerType()) {
759       ResultTy = OriginalBaseTy->getPointeeType();
760     } else if (OriginalBaseTy->isArrayType()) {
761       ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType();
762     } else {
763       return ExprError(
764           Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
765           << Base->getSourceRange());
766     }
767 
768     if (ResultTy->isFunctionType()) {
769       Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type)
770           << ResultTy << Base->getSourceRange();
771       return ExprError();
772     }
773 
774     if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy,
775                                     diag::err_acc_subarray_incomplete_type,
776                                     Base))
777       return ExprError();
778 
779     if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) {
780       ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base);
781       if (Result.isInvalid())
782         return ExprError();
783       Base = Result.get();
784     }
785   }
786 
787   auto GetRecovery = [&](Expr *E, QualType Ty) {
788     ExprResult Recovery =
789         SemaRef.CreateRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), E, Ty);
790     return Recovery.isUsable() ? Recovery.get() : nullptr;
791   };
792 
793   // Ensure both of the expressions are int-exprs.
794   if (LowerBound && !LowerBound->isTypeDependent()) {
795     ExprResult LBRes =
796         ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid,
797                      LowerBound->getExprLoc(), LowerBound);
798 
799     if (LBRes.isUsable())
800       LBRes = SemaRef.DefaultLvalueConversion(LBRes.get());
801     LowerBound =
802         LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);
803   }
804 
805   if (Length && !Length->isTypeDependent()) {
806     ExprResult LenRes =
807         ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid,
808                      Length->getExprLoc(), Length);
809 
810     if (LenRes.isUsable())
811       LenRes = SemaRef.DefaultLvalueConversion(LenRes.get());
812     Length =
813         LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);
814   }
815 
816   // Length is required if the base type is not an array of known bounds.
817   if (!Length && (OriginalBaseTy.isNull() ||
818                   (!OriginalBaseTy->isDependentType() &&
819                    !OriginalBaseTy->isConstantArrayType() &&
820                    !OriginalBaseTy->isDependentSizedArrayType()))) {
821     bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();
822     SourceLocation DiagLoc = ColonLoc.isInvalid() ? LBLoc : ColonLoc;
823     Diag(DiagLoc, diag::err_acc_subarray_no_length) << IsArray;
824     // Fill in a dummy 'length' so that when we instantiate this we don't
825     // double-diagnose here.
826     ExprResult Recovery = SemaRef.CreateRecoveryExpr(
827         DiagLoc, SourceLocation(), ArrayRef<Expr *>(), Context.IntTy);
828     Length = Recovery.isUsable() ? Recovery.get() : nullptr;
829   }
830 
831   // Check the values of each of the arguments, they cannot be negative(we
832   // assume), and if the array bound is known, must be within range. As we do
833   // so, do our best to continue with evaluation, we can set the
834   // value/expression to nullptr/nullopt if they are invalid, and treat them as
835   // not present for the rest of evaluation.
836 
837   // We don't have to check for dependence, because the dependent size is
838   // represented as a different AST node.
839   std::optional<llvm::APSInt> BaseSize;
840   if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) {
841     const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
842     BaseSize = ArrayTy->getSize();
843   }
844 
845   auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> {
846     if (!E || E->isInstantiationDependent())
847       return std::nullopt;
848 
849     Expr::EvalResult Res;
850     if (!E->EvaluateAsInt(Res, Context))
851       return std::nullopt;
852     return Res.Val.getInt();
853   };
854 
855   std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
856   std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
857 
858   // Check lower bound for negative or out of range.
859   if (LowerBoundValue.has_value()) {
860     if (LowerBoundValue->isNegative()) {
861       Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative)
862           << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10);
863       LowerBoundValue.reset();
864       LowerBound = GetRecovery(LowerBound, LowerBound->getType());
865     } else if (BaseSize.has_value() &&
866                llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
867       // Lower bound (start index) must be less than the size of the array.
868       Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range)
869           << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10)
870           << toString(*BaseSize, /*Radix=*/10);
871       LowerBoundValue.reset();
872       LowerBound = GetRecovery(LowerBound, LowerBound->getType());
873     }
874   }
875 
876   // Check length for negative or out of range.
877   if (LengthValue.has_value()) {
878     if (LengthValue->isNegative()) {
879       Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
880           << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10);
881       LengthValue.reset();
882       Length = GetRecovery(Length, Length->getType());
883     } else if (BaseSize.has_value() &&
884                llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
885       // Length must be lessthan or EQUAL to the size of the array.
886       Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
887           << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10)
888           << toString(*BaseSize, /*Radix=*/10);
889       LengthValue.reset();
890       Length = GetRecovery(Length, Length->getType());
891     }
892   }
893 
894   // Adding two APSInts requires matching sign, so extract that here.
895   auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
896     if (LHS.isSigned() == RHS.isSigned())
897       return LHS + RHS;
898 
899     unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
900     return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), /*Signed=*/true);
901   };
902 
903   // If we know all 3 values, we can diagnose that the total value would be out
904   // of range.
905   if (BaseSize.has_value() && LowerBoundValue.has_value() &&
906       LengthValue.has_value() &&
907       llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
908                                   *BaseSize) > 0) {
909     Diag(Base->getExprLoc(),
910          diag::err_acc_subarray_base_plus_length_out_of_range)
911         << toString(*LowerBoundValue, /*Radix=*/10)
912         << toString(*LengthValue, /*Radix=*/10)
913         << toString(*BaseSize, /*Radix=*/10);
914 
915     LowerBoundValue.reset();
916     LowerBound = GetRecovery(LowerBound, LowerBound->getType());
917     LengthValue.reset();
918     Length = GetRecovery(Length, Length->getType());
919   }
920 
921   // If any part of the expression is dependent, return a dependent sub-array.
922   QualType ArrayExprTy = Context.ArraySectionTy;
923   if (Base->isTypeDependent() ||
924       (LowerBound && LowerBound->isInstantiationDependent()) ||
925       (Length && Length->isInstantiationDependent()))
926     ArrayExprTy = Context.DependentTy;
927 
928   return new (Context)
929       ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue,
930                        OK_Ordinary, ColonLoc, RBLoc);
931 }
932 
ActOnWhileStmt(SourceLocation WhileLoc)933 void SemaOpenACC::ActOnWhileStmt(SourceLocation WhileLoc) {
934   if (!getLangOpts().OpenACC)
935     return;
936 
937   if (!LoopInfo.TopLevelLoopSeen)
938     return;
939 
940   if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
941     Diag(WhileLoc, diag::err_acc_invalid_in_loop)
942         << /*while loop*/ 1 << CollapseInfo.DirectiveKind
943         << OpenACCClauseKind::Collapse;
944     assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
945     Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
946          diag::note_acc_active_clause_here)
947         << OpenACCClauseKind::Collapse;
948 
949     // Remove the value so that we don't get cascading errors in the body. The
950     // caller RAII object will restore this.
951     CollapseInfo.CurCollapseCount = std::nullopt;
952   }
953 
954   if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
955     Diag(WhileLoc, diag::err_acc_invalid_in_loop)
956         << /*while loop*/ 1 << TileInfo.DirectiveKind
957         << OpenACCClauseKind::Tile;
958     assert(TileInfo.ActiveTile && "tile count without object?");
959     Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
960         << OpenACCClauseKind::Tile;
961 
962     // Remove the value so that we don't get cascading errors in the body. The
963     // caller RAII object will restore this.
964     TileInfo.CurTileCount = std::nullopt;
965   }
966 }
967 
ActOnDoStmt(SourceLocation DoLoc)968 void SemaOpenACC::ActOnDoStmt(SourceLocation DoLoc) {
969   if (!getLangOpts().OpenACC)
970     return;
971 
972   if (!LoopInfo.TopLevelLoopSeen)
973     return;
974 
975   if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
976     Diag(DoLoc, diag::err_acc_invalid_in_loop)
977         << /*do loop*/ 2 << CollapseInfo.DirectiveKind
978         << OpenACCClauseKind::Collapse;
979     assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
980     Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
981          diag::note_acc_active_clause_here)
982         << OpenACCClauseKind::Collapse;
983 
984     // Remove the value so that we don't get cascading errors in the body. The
985     // caller RAII object will restore this.
986     CollapseInfo.CurCollapseCount = std::nullopt;
987   }
988 
989   if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
990     Diag(DoLoc, diag::err_acc_invalid_in_loop)
991         << /*do loop*/ 2 << TileInfo.DirectiveKind << OpenACCClauseKind::Tile;
992     assert(TileInfo.ActiveTile && "tile count without object?");
993     Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
994         << OpenACCClauseKind::Tile;
995 
996     // Remove the value so that we don't get cascading errors in the body. The
997     // caller RAII object will restore this.
998     TileInfo.CurTileCount = std::nullopt;
999   }
1000 }
1001 
ForStmtBeginHelper(SourceLocation ForLoc,ForStmtBeginChecker & C)1002 void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc,
1003                                      ForStmtBeginChecker &C) {
1004   assert(getLangOpts().OpenACC && "Check enabled when not OpenACC?");
1005 
1006   // Enable the while/do-while checking.
1007   LoopInfo.TopLevelLoopSeen = true;
1008 
1009   if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1010     // Check the format of this loop if it is affected by the collapse.
1011     C.check();
1012 
1013     // OpenACC 3.3 2.9.1:
1014     // Each associated loop, except the innermost, must contain exactly one loop
1015     // or loop nest.
1016     // This checks for more than 1 loop at the current level, the
1017     // 'depth'-satisifed checking manages the 'not zero' case.
1018     if (LoopInfo.CurLevelHasLoopAlready) {
1019       Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1020           << CollapseInfo.DirectiveKind << OpenACCClauseKind::Collapse;
1021       assert(CollapseInfo.ActiveCollapse && "No collapse object?");
1022       Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1023            diag::note_acc_active_clause_here)
1024           << OpenACCClauseKind::Collapse;
1025     } else {
1026       --(*CollapseInfo.CurCollapseCount);
1027 
1028       // Once we've hit zero here, we know we have deep enough 'for' loops to
1029       // get to the bottom.
1030       if (*CollapseInfo.CurCollapseCount == 0)
1031         CollapseInfo.CollapseDepthSatisfied = true;
1032     }
1033   }
1034 
1035   if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1036     // Check the format of this loop if it is affected by the tile.
1037     C.check();
1038 
1039     if (LoopInfo.CurLevelHasLoopAlready) {
1040       Diag(ForLoc, diag::err_acc_clause_multiple_loops)
1041           << TileInfo.DirectiveKind << OpenACCClauseKind::Tile;
1042       assert(TileInfo.ActiveTile && "No tile object?");
1043       Diag(TileInfo.ActiveTile->getBeginLoc(),
1044            diag::note_acc_active_clause_here)
1045           << OpenACCClauseKind::Tile;
1046     } else {
1047       TileInfo.CurTileCount = *TileInfo.CurTileCount - 1;
1048       // Once we've hit zero here, we know we have deep enough 'for' loops to
1049       // get to the bottom.
1050       if (*TileInfo.CurTileCount == 0)
1051         TileInfo.TileDepthSatisfied = true;
1052     }
1053   }
1054 
1055   // Set this to 'false' for the body of this loop, so that the next level
1056   // checks independently.
1057   LoopInfo.CurLevelHasLoopAlready = false;
1058 }
1059 
1060 namespace {
isValidLoopVariableType(QualType LoopVarTy)1061 bool isValidLoopVariableType(QualType LoopVarTy) {
1062   // Just skip if it is dependent, it could be any of the below.
1063   if (LoopVarTy->isDependentType())
1064     return true;
1065 
1066   // The loop variable must be of integer,
1067   if (LoopVarTy->isIntegerType())
1068     return true;
1069 
1070   // C/C++ pointer,
1071   if (LoopVarTy->isPointerType())
1072     return true;
1073 
1074   // or C++ random-access iterator type.
1075   if (const auto *RD = LoopVarTy->getAsCXXRecordDecl()) {
1076     // Note: Only do CXXRecordDecl because RecordDecl can't be a random access
1077     // iterator type!
1078 
1079     // We could either do a lot of work to see if this matches
1080     // random-access-iterator, but it seems that just checking that the
1081     // 'iterator_category' typedef is more than sufficient. If programmers are
1082     // willing to lie about this, we can let them.
1083 
1084     for (const auto *TD :
1085          llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) {
1086       const auto *TDND = cast<TypedefNameDecl>(TD)->getCanonicalDecl();
1087 
1088       if (TDND->getName() != "iterator_category")
1089         continue;
1090 
1091       // If there is no type for this decl, return false.
1092       if (TDND->getUnderlyingType().isNull())
1093         return false;
1094 
1095       const CXXRecordDecl *ItrCategoryDecl =
1096           TDND->getUnderlyingType()->getAsCXXRecordDecl();
1097 
1098       // If the category isn't a record decl, it isn't the tag type.
1099       if (!ItrCategoryDecl)
1100         return false;
1101 
1102       auto IsRandomAccessIteratorTag = [](const CXXRecordDecl *RD) {
1103         if (RD->getName() != "random_access_iterator_tag")
1104           return false;
1105         // Checks just for std::random_access_iterator_tag.
1106         return RD->getEnclosingNamespaceContext()->isStdNamespace();
1107       };
1108 
1109       if (IsRandomAccessIteratorTag(ItrCategoryDecl))
1110         return true;
1111 
1112       // We can also support tag-types inherited from the
1113       // random_access_iterator_tag.
1114       for (CXXBaseSpecifier BS : ItrCategoryDecl->bases())
1115         if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))
1116           return true;
1117 
1118       return false;
1119     }
1120   }
1121 
1122   return false;
1123 }
getDeclFromExpr(const Expr * E)1124 const ValueDecl *getDeclFromExpr(const Expr *E) {
1125   E = E->IgnoreParenImpCasts();
1126   if (const auto *FE = dyn_cast<FullExpr>(E))
1127     E = FE->getSubExpr();
1128 
1129   E = E->IgnoreParenImpCasts();
1130 
1131   if (!E)
1132     return nullptr;
1133   if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
1134     return dyn_cast<ValueDecl>(DRE->getDecl());
1135 
1136   if (const auto *ME = dyn_cast<MemberExpr>(E))
1137     if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1138       return ME->getMemberDecl();
1139 
1140   return nullptr;
1141 }
1142 } // namespace
1143 
checkRangeFor()1144 void SemaOpenACC::ForStmtBeginChecker::checkRangeFor() {
1145   const RangeForInfo &RFI = std::get<RangeForInfo>(Info);
1146   // If this hasn't changed since last instantiated we're done.
1147   if (RFI.Uninstantiated == RFI.CurrentVersion)
1148     return;
1149 
1150   const DeclStmt *UninstRangeStmt =
1151       IsInstantiation ? RFI.Uninstantiated->getBeginStmt() : nullptr;
1152   const DeclStmt *RangeStmt = RFI.CurrentVersion->getBeginStmt();
1153 
1154   // If this isn't the first time we've checked this loop, suppress any cases
1155   // where we previously diagnosed.
1156   if (UninstRangeStmt) {
1157     const ValueDecl *InitVar =
1158         cast<ValueDecl>(UninstRangeStmt->getSingleDecl());
1159     QualType VarType = InitVar->getType().getNonReferenceType();
1160 
1161     if (!isValidLoopVariableType(VarType))
1162       return;
1163   }
1164 
1165   // In some dependent contexts, the autogenerated range statement doesn't get
1166   // included until instantiation, so skip for now.
1167   if (RangeStmt) {
1168     const ValueDecl *InitVar = cast<ValueDecl>(RangeStmt->getSingleDecl());
1169     QualType VarType = InitVar->getType().getNonReferenceType();
1170 
1171     if (!isValidLoopVariableType(VarType)) {
1172       SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type)
1173           << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1174       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1175                    diag::note_acc_construct_here)
1176           << SemaRef.LoopWithoutSeqInfo.Kind;
1177       return;
1178     }
1179   }
1180 }
checkForInit(const Stmt * InitStmt,const ValueDecl * & InitVar,bool Diag)1181 bool SemaOpenACC::ForStmtBeginChecker::checkForInit(const Stmt *InitStmt,
1182                                                     const ValueDecl *&InitVar,
1183                                                     bool Diag) {
1184   // Init statement is required.
1185   if (!InitStmt) {
1186     if (Diag) {
1187       SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)
1188           << SemaRef.LoopWithoutSeqInfo.Kind;
1189       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1190                    diag::note_acc_construct_here)
1191           << SemaRef.LoopWithoutSeqInfo.Kind;
1192     }
1193     return true;
1194   }
1195   auto DiagLoopVar = [this, Diag, InitStmt]() {
1196     if (Diag) {
1197       SemaRef.Diag(InitStmt->getBeginLoc(), diag::err_acc_loop_variable)
1198           << SemaRef.LoopWithoutSeqInfo.Kind;
1199       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1200                    diag::note_acc_construct_here)
1201           << SemaRef.LoopWithoutSeqInfo.Kind;
1202     }
1203     return true;
1204   };
1205 
1206   if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(InitStmt))
1207     InitStmt = ExprTemp->getSubExpr();
1208   if (const auto *E = dyn_cast<Expr>(InitStmt))
1209     InitStmt = E->IgnoreParenImpCasts();
1210 
1211   InitVar = nullptr;
1212   if (const auto *BO = dyn_cast<BinaryOperator>(InitStmt)) {
1213     // Allow assignment operator here.
1214 
1215     if (!BO->isAssignmentOp())
1216       return DiagLoopVar();
1217 
1218     const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts();
1219     if (const auto *DRE = dyn_cast<DeclRefExpr>(LHS))
1220       InitVar = DRE->getDecl();
1221   } else if (const auto *DS = dyn_cast<DeclStmt>(InitStmt)) {
1222     // Allow T t = <whatever>
1223     if (!DS->isSingleDecl())
1224       return DiagLoopVar();
1225     InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl());
1226 
1227     // Ensure we have an initializer, unless this is a record/dependent type.
1228     if (InitVar) {
1229       if (!isa<VarDecl>(InitVar))
1230         return DiagLoopVar();
1231 
1232       if (!InitVar->getType()->isRecordType() &&
1233           !InitVar->getType()->isDependentType() &&
1234           !cast<VarDecl>(InitVar)->hasInit())
1235         return DiagLoopVar();
1236     }
1237   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(InitStmt)) {
1238     // Allow assignment operator call.
1239     if (CE->getOperator() != OO_Equal)
1240       return DiagLoopVar();
1241 
1242     const Expr *LHS = CE->getArg(0)->IgnoreParenImpCasts();
1243     if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
1244       InitVar = DRE->getDecl();
1245     } else if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
1246       if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
1247         InitVar = ME->getMemberDecl();
1248     }
1249   }
1250 
1251   // If after all of that, we haven't found a variable, give up.
1252   if (!InitVar)
1253     return DiagLoopVar();
1254 
1255   InitVar = cast<ValueDecl>(InitVar->getCanonicalDecl());
1256   QualType VarType = InitVar->getType().getNonReferenceType();
1257 
1258   // Since we have one, all we need to do is ensure it is the right type.
1259   if (!isValidLoopVariableType(VarType)) {
1260     if (Diag) {
1261       SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type)
1262           << SemaRef.LoopWithoutSeqInfo.Kind << VarType;
1263       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1264                    diag::note_acc_construct_here)
1265           << SemaRef.LoopWithoutSeqInfo.Kind;
1266     }
1267     return true;
1268   }
1269 
1270   return false;
1271 }
1272 
checkForCond(const Stmt * CondStmt,const ValueDecl * InitVar,bool Diag)1273 bool SemaOpenACC::ForStmtBeginChecker::checkForCond(const Stmt *CondStmt,
1274                                                     const ValueDecl *InitVar,
1275                                                     bool Diag) {
1276   // A condition statement is required.
1277   if (!CondStmt) {
1278     if (Diag) {
1279       SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)
1280           << SemaRef.LoopWithoutSeqInfo.Kind;
1281       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1282                    diag::note_acc_construct_here)
1283           << SemaRef.LoopWithoutSeqInfo.Kind;
1284     }
1285 
1286     return true;
1287   }
1288   auto DiagCondVar = [this, Diag, CondStmt] {
1289     if (Diag) {
1290       SemaRef.Diag(CondStmt->getBeginLoc(),
1291                    diag::err_acc_loop_terminating_condition)
1292           << SemaRef.LoopWithoutSeqInfo.Kind;
1293       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1294                    diag::note_acc_construct_here)
1295           << SemaRef.LoopWithoutSeqInfo.Kind;
1296     }
1297     return true;
1298   };
1299 
1300   if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(CondStmt))
1301     CondStmt = ExprTemp->getSubExpr();
1302   if (const auto *E = dyn_cast<Expr>(CondStmt))
1303     CondStmt = E->IgnoreParenImpCasts();
1304 
1305   const ValueDecl *CondVar = nullptr;
1306   if (const auto *BO = dyn_cast<BinaryOperator>(CondStmt)) {
1307     switch (BO->getOpcode()) {
1308     default:
1309       return DiagCondVar();
1310     case BO_EQ:
1311     case BO_LT:
1312     case BO_GT:
1313     case BO_NE:
1314     case BO_LE:
1315     case BO_GE:
1316       break;
1317     }
1318 
1319     // Assign the condition-var to the LHS.  If it either comes back null, or
1320     // the LHS doesn't match the InitVar, assign it to the RHS so that 5 < N is
1321     // allowed.
1322     CondVar = getDeclFromExpr(BO->getLHS());
1323     if (!CondVar ||
1324         (InitVar && CondVar->getCanonicalDecl() != InitVar->getCanonicalDecl()))
1325       CondVar = getDeclFromExpr(BO->getRHS());
1326 
1327   } else if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(CondStmt)) {
1328     // Any of the comparison ops should be ok here, but we don't know how to
1329     // handle spaceship, so disallow for now.
1330     if (!CE->isComparisonOp() || CE->getOperator() == OO_Spaceship)
1331       return DiagCondVar();
1332 
1333     // Same logic here: Assign it to the LHS, unless the LHS comes back null or
1334     // not equal to the init var.
1335     CondVar = getDeclFromExpr(CE->getArg(0));
1336     if (!CondVar ||
1337         (InitVar &&
1338          CondVar->getCanonicalDecl() != InitVar->getCanonicalDecl() &&
1339          CE->getNumArgs() > 1))
1340       CondVar = getDeclFromExpr(CE->getArg(1));
1341   } else {
1342     return DiagCondVar();
1343   }
1344 
1345   if (!CondVar)
1346     return DiagCondVar();
1347 
1348   // Don't consider this an error unless the init variable was properly set,
1349   // else check to make sure they are the same variable.
1350   if (InitVar && CondVar->getCanonicalDecl() != InitVar->getCanonicalDecl())
1351     return DiagCondVar();
1352 
1353   return false;
1354 }
1355 
1356 namespace {
1357 // Helper to check the RHS of an assignment during for's step. We can allow
1358 // InitVar = InitVar + N, InitVar = N + InitVar, and Initvar = Initvar - N,
1359 // where N is an integer.
isValidForIncRHSAssign(const ValueDecl * InitVar,const Expr * RHS)1360 bool isValidForIncRHSAssign(const ValueDecl *InitVar, const Expr *RHS) {
1361 
1362   auto isValid = [](const ValueDecl *InitVar, const Expr *InnerLHS,
1363                     const Expr *InnerRHS, bool IsAddition) {
1364     // ONE of the sides has to be an integer type.
1365     if (!InnerLHS->getType()->isIntegerType() &&
1366         !InnerRHS->getType()->isIntegerType())
1367       return false;
1368 
1369     // If the init var is already an error, don't bother trying to check for
1370     // it.
1371     if (!InitVar)
1372       return true;
1373 
1374     const ValueDecl *LHSDecl = getDeclFromExpr(InnerLHS);
1375     const ValueDecl *RHSDecl = getDeclFromExpr(InnerRHS);
1376     // If we can't get a declaration, this is probably an error, so give up.
1377     if (!LHSDecl || !RHSDecl)
1378       return true;
1379 
1380     // If the LHS is the InitVar, the other must be int, so this is valid.
1381     if (LHSDecl->getCanonicalDecl() ==
1382         InitVar->getCanonicalDecl())
1383       return true;
1384 
1385     // Subtraction doesn't allow the RHS to be init var, so this is invalid.
1386     if (!IsAddition)
1387       return false;
1388 
1389     return RHSDecl->getCanonicalDecl() ==
1390            InitVar->getCanonicalDecl();
1391   };
1392 
1393   if (const auto *BO = dyn_cast<BinaryOperator>(RHS)) {
1394     BinaryOperatorKind OpC = BO->getOpcode();
1395     if (OpC != BO_Add && OpC != BO_Sub)
1396       return false;
1397     return isValid(InitVar, BO->getLHS(), BO->getRHS(), OpC == BO_Add);
1398   } else if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
1399     OverloadedOperatorKind Op = CE->getOperator();
1400     if (Op != OO_Plus && Op != OO_Minus)
1401       return false;
1402     return isValid(InitVar, CE->getArg(0), CE->getArg(1), Op == OO_Plus);
1403   }
1404 
1405   return false;
1406 }
1407 } // namespace
1408 
checkForInc(const Stmt * IncStmt,const ValueDecl * InitVar,bool Diag)1409 bool SemaOpenACC::ForStmtBeginChecker::checkForInc(const Stmt *IncStmt,
1410                                                    const ValueDecl *InitVar,
1411                                                    bool Diag) {
1412   if (!IncStmt) {
1413     if (Diag) {
1414       SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)
1415           << SemaRef.LoopWithoutSeqInfo.Kind;
1416       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1417                    diag::note_acc_construct_here)
1418           << SemaRef.LoopWithoutSeqInfo.Kind;
1419     }
1420     return true;
1421   }
1422   auto DiagIncVar = [this, Diag, IncStmt] {
1423     if (Diag) {
1424       SemaRef.Diag(IncStmt->getBeginLoc(), diag::err_acc_loop_not_monotonic)
1425           << SemaRef.LoopWithoutSeqInfo.Kind;
1426       SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc,
1427                    diag::note_acc_construct_here)
1428           << SemaRef.LoopWithoutSeqInfo.Kind;
1429     }
1430     return true;
1431   };
1432 
1433   if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(IncStmt))
1434     IncStmt = ExprTemp->getSubExpr();
1435   if (const auto *E = dyn_cast<Expr>(IncStmt))
1436     IncStmt = E->IgnoreParenImpCasts();
1437 
1438   const ValueDecl *IncVar = nullptr;
1439   // Here we enforce the monotonically increase/decrease:
1440   if (const auto *UO = dyn_cast<UnaryOperator>(IncStmt)) {
1441     // Allow increment/decrement ops.
1442     if (!UO->isIncrementDecrementOp())
1443       return DiagIncVar();
1444     IncVar = getDeclFromExpr(UO->getSubExpr());
1445   } else if (const auto *BO = dyn_cast<BinaryOperator>(IncStmt)) {
1446     switch (BO->getOpcode()) {
1447     default:
1448       return DiagIncVar();
1449     case BO_AddAssign:
1450     case BO_SubAssign:
1451       break;
1452     case BO_Assign:
1453       // For assignment we also allow InitVar = InitVar + N, InitVar = N +
1454       // InitVar, and InitVar = InitVar - N;  BUT only if 'N' is integral.
1455       if (!isValidForIncRHSAssign(InitVar, BO->getRHS()))
1456         return DiagIncVar();
1457       break;
1458     }
1459     IncVar = getDeclFromExpr(BO->getLHS());
1460   } else if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(IncStmt)) {
1461     switch (CE->getOperator()) {
1462     default:
1463       return DiagIncVar();
1464     case OO_PlusPlus:
1465     case OO_MinusMinus:
1466     case OO_PlusEqual:
1467     case OO_MinusEqual:
1468       break;
1469     case OO_Equal:
1470       // For assignment we also allow InitVar = InitVar + N, InitVar = N +
1471       // InitVar, and InitVar = InitVar - N;  BUT only if 'N' is integral.
1472       if (!isValidForIncRHSAssign(InitVar, CE->getArg(1)))
1473         return DiagIncVar();
1474       break;
1475     }
1476 
1477     IncVar = getDeclFromExpr(CE->getArg(0));
1478   } else {
1479     return DiagIncVar();
1480   }
1481 
1482   if (!IncVar)
1483     return DiagIncVar();
1484 
1485   // InitVar shouldn't be null unless there was an error, so don't diagnose if
1486   // that is the case. Else we should ensure that it refers to the  loop
1487   // value.
1488   if (InitVar && IncVar->getCanonicalDecl() != InitVar->getCanonicalDecl())
1489     return DiagIncVar();
1490 
1491   return false;
1492 }
1493 
checkFor()1494 void SemaOpenACC::ForStmtBeginChecker::checkFor() {
1495   const CheckForInfo &CFI = std::get<CheckForInfo>(Info);
1496 
1497   if (!IsInstantiation) {
1498     // If this isn't an instantiation, we can just check all of these and
1499     // diagnose.
1500     const ValueDecl *CurInitVar = nullptr;
1501     checkForInit(CFI.Current.Init, CurInitVar, /*Diag=*/true);
1502     checkForCond(CFI.Current.Condition, CurInitVar, /*Diag=*/true);
1503     checkForInc(CFI.Current.Increment, CurInitVar, /*DIag=*/true);
1504   } else {
1505     const ValueDecl *UninstInitVar = nullptr;
1506     // Checking the 'init' section first. We have to always run both versions,
1507     // at minimum with the 'diag' off, so that we can ensure we get the correct
1508     // instantiation var for checking by later ones.
1509     bool UninstInitFailed =
1510         checkForInit(CFI.Uninst.Init, UninstInitVar, /*Diag=*/false);
1511 
1512     // VarDecls are always rebuild because they are dependent, so we can do a
1513     // little work to suppress some of the double checking based on whether the
1514     // type is instantiation dependent. This is imperfect, but will get us most
1515     // cases suppressed. Currently this only handles the 'T t =' case.
1516     auto InitChanged = [=]() {
1517       if (CFI.Uninst.Init == CFI.Current.Init)
1518         return false;
1519 
1520       QualType OldVDTy;
1521       QualType NewVDTy;
1522 
1523       if (const auto *DS = dyn_cast<DeclStmt>(CFI.Uninst.Init))
1524         if (const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1525                 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
1526           OldVDTy = VD->getType();
1527       if (const auto *DS = dyn_cast<DeclStmt>(CFI.Current.Init))
1528         if (const VarDecl *VD = dyn_cast_if_present<VarDecl>(
1529                 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))
1530           NewVDTy = VD->getType();
1531 
1532       if (OldVDTy.isNull() || NewVDTy.isNull())
1533         return true;
1534 
1535       return OldVDTy->isInstantiationDependentType() !=
1536              NewVDTy->isInstantiationDependentType();
1537     };
1538 
1539     // Only diagnose the new 'init' if the previous version didn't fail, AND the
1540     // current init changed meaningfully.
1541     bool ShouldDiagNewInit = !UninstInitFailed && InitChanged();
1542     const ValueDecl *CurInitVar = nullptr;
1543     checkForInit(CFI.Current.Init, CurInitVar, /*Diag=*/ShouldDiagNewInit);
1544 
1545     // Check the condition and increment only if the previous version passed,
1546     // and this changed.
1547     if (CFI.Uninst.Condition != CFI.Current.Condition &&
1548         !checkForCond(CFI.Uninst.Condition, UninstInitVar, /*Diag=*/false))
1549       checkForCond(CFI.Current.Condition, CurInitVar, /*Diag=*/true);
1550     if (CFI.Uninst.Increment != CFI.Current.Increment &&
1551         !checkForInc(CFI.Uninst.Increment, UninstInitVar, /*Diag=*/false))
1552       checkForInc(CFI.Current.Increment, CurInitVar, /*Diag=*/true);
1553   }
1554 }
1555 
check()1556 void SemaOpenACC::ForStmtBeginChecker::check() {
1557   // If this isn't an active loop without a seq, immediately return, nothing to
1558   // check.
1559   if (SemaRef.LoopWithoutSeqInfo.Kind == OpenACCDirectiveKind::Invalid)
1560     return;
1561 
1562   // If we've already checked, because this is a 'top level' one (and asking
1563   // again because 'tile' and 'collapse' might apply), just return, nothing to
1564   // do here.
1565   if (AlreadyChecked)
1566     return;
1567   AlreadyChecked = true;
1568 
1569   // OpenACC3.3 2.1:
1570   // A loop associated with a loop construct that does not have a seq clause
1571   // must be written to meet all the following conditions:
1572   // - The loop variable must be of integer, C/C++ pointer, or C++ random-access
1573   // iterator type.
1574   // - The loop variable must monotonically increase or decrease in the
1575   // direction of its termination condition.
1576   // - The loop trip count must be computable in constant time when entering the
1577   // loop construct.
1578   //
1579   // For a C++ range-based for loop, the loop variable
1580   // identified by the above conditions is the internal iterator, such as a
1581   // pointer, that the compiler generates to iterate the range.  it is not the
1582   // variable declared by the for loop.
1583 
1584   if (std::holds_alternative<RangeForInfo>(Info))
1585     return checkRangeFor();
1586 
1587   return checkFor();
1588 }
1589 
ActOnForStmtBegin(SourceLocation ForLoc,const Stmt * OldFirst,const Stmt * First,const Stmt * OldSecond,const Stmt * Second,const Stmt * OldThird,const Stmt * Third)1590 void SemaOpenACC::ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst,
1591                                     const Stmt *First, const Stmt *OldSecond,
1592                                     const Stmt *Second, const Stmt *OldThird,
1593                                     const Stmt *Third) {
1594   if (!getLangOpts().OpenACC)
1595     return;
1596 
1597   ForStmtBeginChecker FSBC{*this,    ForLoc, OldFirst, OldSecond,
1598                            OldThird, First,  Second,   Third};
1599   // Check if this is the top-level 'for' for a 'loop'.  Else it will be checked
1600   // as a part of the helper if a tile/collapse applies.
1601   if (!LoopInfo.TopLevelLoopSeen) {
1602     FSBC.check();
1603   }
1604 
1605   ForStmtBeginHelper(ForLoc, FSBC);
1606 }
1607 
ActOnForStmtBegin(SourceLocation ForLoc,const Stmt * First,const Stmt * Second,const Stmt * Third)1608 void SemaOpenACC::ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First,
1609                                     const Stmt *Second, const Stmt *Third) {
1610   if (!getLangOpts().OpenACC)
1611     return;
1612 
1613   ForStmtBeginChecker FSBC{*this, ForLoc, First, Second, Third};
1614 
1615   // Check if this is the top-level 'for' for a 'loop'.  Else it will be checked
1616   // as a part of the helper if a tile/collapse applies.
1617   if (!LoopInfo.TopLevelLoopSeen)
1618     FSBC.check();
1619 
1620   ForStmtBeginHelper(ForLoc, FSBC);
1621 }
1622 
ActOnRangeForStmtBegin(SourceLocation ForLoc,const Stmt * OldRangeFor,const Stmt * RangeFor)1623 void SemaOpenACC::ActOnRangeForStmtBegin(SourceLocation ForLoc,
1624                                          const Stmt *OldRangeFor,
1625                                          const Stmt *RangeFor) {
1626   if (!getLangOpts().OpenACC || OldRangeFor == nullptr || RangeFor == nullptr)
1627     return;
1628 
1629   ForStmtBeginChecker FSBC{*this, ForLoc,
1630                            cast_if_present<CXXForRangeStmt>(OldRangeFor),
1631                            cast_if_present<CXXForRangeStmt>(RangeFor)};
1632   // Check if this is the top-level 'for' for a 'loop'.  Else it will be checked
1633   // as a part of the helper if a tile/collapse applies.
1634   if (!LoopInfo.TopLevelLoopSeen) {
1635     FSBC.check();
1636   }
1637   ForStmtBeginHelper(ForLoc, FSBC);
1638 }
1639 
ActOnRangeForStmtBegin(SourceLocation ForLoc,const Stmt * RangeFor)1640 void SemaOpenACC::ActOnRangeForStmtBegin(SourceLocation ForLoc,
1641                                          const Stmt *RangeFor) {
1642   if (!getLangOpts().OpenACC || RangeFor == nullptr)
1643     return;
1644 
1645   ForStmtBeginChecker FSBC = {*this, ForLoc,
1646                               cast_if_present<CXXForRangeStmt>(RangeFor)};
1647 
1648   // Check if this is the top-level 'for' for a 'loop'.  Else it will be checked
1649   // as a part of the helper if a tile/collapse applies.
1650   if (!LoopInfo.TopLevelLoopSeen)
1651     FSBC.check();
1652 
1653   ForStmtBeginHelper(ForLoc, FSBC);
1654 }
1655 
1656 namespace {
FindInterveningCodeInLoop(const Stmt * CurStmt)1657 SourceLocation FindInterveningCodeInLoop(const Stmt *CurStmt) {
1658   // We should diagnose on anything except `CompoundStmt`, `NullStmt`,
1659   // `ForStmt`, `CXXForRangeStmt`, since those are legal, and `WhileStmt` and
1660   // `DoStmt`, as those are caught as a violation elsewhere.
1661   // For `CompoundStmt` we need to search inside of it.
1662   if (!CurStmt ||
1663       isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(
1664           CurStmt))
1665     return SourceLocation{};
1666 
1667   // Any other construct is an error anyway, so it has already been diagnosed.
1668   if (isa<OpenACCConstructStmt>(CurStmt))
1669     return SourceLocation{};
1670 
1671   // Search inside the compound statement, this allows for arbitrary nesting
1672   // of compound statements, as long as there isn't any code inside.
1673   if (const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) {
1674     for (const auto *ChildStmt : CS->children()) {
1675       SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);
1676       if (ChildStmtLoc.isValid())
1677         return ChildStmtLoc;
1678     }
1679     // Empty/not invalid compound statements are legal.
1680     return SourceLocation{};
1681   }
1682   return CurStmt->getBeginLoc();
1683 }
1684 } // namespace
1685 
ActOnForStmtEnd(SourceLocation ForLoc,StmtResult Body)1686 void SemaOpenACC::ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body) {
1687   if (!getLangOpts().OpenACC)
1688     return;
1689 
1690   // Set this to 'true' so if we find another one at this level we can diagnose.
1691   LoopInfo.CurLevelHasLoopAlready = true;
1692 
1693   if (!Body.isUsable())
1694     return;
1695 
1696   bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&
1697                           *CollapseInfo.CurCollapseCount > 0 &&
1698                           !CollapseInfo.ActiveCollapse->hasForce();
1699   bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;
1700 
1701   if (IsActiveCollapse || IsActiveTile) {
1702     SourceLocation OtherStmtLoc = FindInterveningCodeInLoop(Body.get());
1703 
1704     if (OtherStmtLoc.isValid() && IsActiveCollapse) {
1705       Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1706           << OpenACCClauseKind::Collapse << CollapseInfo.DirectiveKind;
1707       Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1708            diag::note_acc_active_clause_here)
1709           << OpenACCClauseKind::Collapse;
1710     }
1711 
1712     if (OtherStmtLoc.isValid() && IsActiveTile) {
1713       Diag(OtherStmtLoc, diag::err_acc_intervening_code)
1714           << OpenACCClauseKind::Tile << TileInfo.DirectiveKind;
1715       Diag(TileInfo.ActiveTile->getBeginLoc(),
1716            diag::note_acc_active_clause_here)
1717           << OpenACCClauseKind::Tile;
1718     }
1719   }
1720 }
1721 
1722 namespace {
1723 // Helper that should mirror ActOnRoutineName to get the FunctionDecl out for
1724 // magic-static checking.
getFunctionFromRoutineName(Expr * RoutineName)1725 FunctionDecl *getFunctionFromRoutineName(Expr *RoutineName) {
1726   if (!RoutineName)
1727     return nullptr;
1728   RoutineName = RoutineName->IgnoreParenImpCasts();
1729   if (isa<RecoveryExpr>(RoutineName)) {
1730     // There is nothing we can do here, this isn't a function we can count on.
1731     return nullptr;
1732   } else if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(
1733                  RoutineName)) {
1734     // The lookup is dependent, so we'll have to figure this out later.
1735     return nullptr;
1736   } else if (auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1737     ValueDecl *VD = DRE->getDecl();
1738 
1739     if (auto *FD = dyn_cast<FunctionDecl>(VD))
1740       return FD;
1741 
1742     // Allow lambdas.
1743     if (auto *VarD = dyn_cast<VarDecl>(VD)) {
1744       QualType VarDTy = VarD->getType();
1745       if (!VarDTy.isNull()) {
1746         if (auto *RD = VarDTy->getAsCXXRecordDecl()) {
1747           if (RD->isGenericLambda())
1748             return nullptr;
1749           if (RD->isLambda())
1750             return RD->getLambdaCallOperator();
1751         } else if (VarDTy->isDependentType()) {
1752           // We don't really know what this is going to be.
1753           return nullptr;
1754         }
1755       }
1756       return nullptr;
1757     } else if (isa<OverloadExpr>(RoutineName)) {
1758       return nullptr;
1759     }
1760   }
1761   return nullptr;
1762 }
1763 } // namespace
1764 
ActOnRoutineName(Expr * RoutineName)1765 ExprResult SemaOpenACC::ActOnRoutineName(Expr *RoutineName) {
1766   assert(RoutineName && "Routine name cannot be null here");
1767   RoutineName = RoutineName->IgnoreParenImpCasts();
1768 
1769   if (isa<RecoveryExpr>(RoutineName)) {
1770     // This has already been diagnosed, so we can skip it.
1771     return ExprError();
1772   } else if (isa<DependentScopeDeclRefExpr, CXXDependentScopeMemberExpr>(
1773                  RoutineName)) {
1774     // These are dependent and we can't really check them, so delay until
1775     // instantiation.
1776     return RoutineName;
1777   } else if (const auto *DRE = dyn_cast<DeclRefExpr>(RoutineName)) {
1778     const ValueDecl *VD = DRE->getDecl();
1779 
1780     if (isa<FunctionDecl>(VD))
1781       return RoutineName;
1782 
1783     // Allow lambdas.
1784     if (const auto *VarD = dyn_cast<VarDecl>(VD)) {
1785       QualType VarDTy = VarD->getType();
1786       if (!VarDTy.isNull()) {
1787         if (const auto *RD = VarDTy->getAsCXXRecordDecl()) {
1788           if (RD->isGenericLambda()) {
1789             Diag(RoutineName->getBeginLoc(), diag::err_acc_routine_overload_set)
1790                 << RoutineName;
1791             return ExprError();
1792           }
1793           if (RD->isLambda())
1794             return RoutineName;
1795         } else if (VarDTy->isDependentType()) {
1796           // If this is a dependent variable, it might be a lambda. So we just
1797           // accept this and catch it next time.
1798           return RoutineName;
1799         }
1800       }
1801     }
1802 
1803     Diag(RoutineName->getBeginLoc(), diag::err_acc_routine_not_func)
1804         << RoutineName;
1805     return ExprError();
1806   } else if (isa<OverloadExpr>(RoutineName)) {
1807     // This happens in function templates, even when the template arguments are
1808     // fully specified. We could possibly do some sort of matching to make sure
1809     // that this is looked up/deduced, but GCC does not do this, so there
1810     // doesn't seem to be a good reason for us to do it either.
1811     Diag(RoutineName->getBeginLoc(), diag::err_acc_routine_overload_set)
1812         << RoutineName;
1813     return ExprError();
1814   }
1815 
1816   Diag(RoutineName->getBeginLoc(), diag::err_acc_routine_not_func)
1817       << RoutineName;
1818   return ExprError();
1819 }
ActOnVariableDeclarator(VarDecl * VD)1820 void SemaOpenACC::ActOnVariableDeclarator(VarDecl *VD) {
1821   if (!getLangOpts().OpenACC || VD->isInvalidDecl() || !VD->isStaticLocal())
1822     return;
1823 
1824   // This cast should be safe, since a static-local can only happen in a
1825   // function declaration.
1826   auto *ContextDecl = cast<FunctionDecl>(getCurContext());
1827 
1828   // OpenACC 3.3 2.15:
1829   // In C and C++, function static variables are not supported in functions to
1830   // which a routine directive applies.
1831   for (const auto *A : ContextDecl->attrs()) {
1832     if (isa<OpenACCRoutineDeclAttr, OpenACCRoutineAnnotAttr>(A)) {
1833       Diag(VD->getBeginLoc(), diag::err_acc_magic_static_in_routine);
1834       Diag(A->getLocation(), diag::note_acc_construct_here)
1835           << OpenACCDirectiveKind::Routine;
1836       return;
1837     }
1838   }
1839 
1840   MagicStaticLocs.insert({ContextDecl->getCanonicalDecl(), VD->getBeginLoc()});
1841 }
CheckLastRoutineDeclNameConflict(const NamedDecl * ND)1842 void SemaOpenACC::CheckLastRoutineDeclNameConflict(const NamedDecl *ND) {
1843   // OpenACC 3.3 A.3.4
1844   // When a procedure with that name is in scope and it is not the same
1845   // procedure as the immediately following procedure declaration or
1846   // definition, the resolution of the name can be confusing.  Implementations
1847   // should then issue a compile-time warning diagnostic even though the
1848   // application is conforming.
1849 
1850   // If we haven't created one, also can't diagnose.
1851   if (!LastRoutineDecl)
1852     return;
1853 
1854   // If the currently created function doesn't have a name, we can't diagnose on
1855   // a match.
1856   if (!ND->getDeclName().isIdentifier())
1857     return;
1858 
1859   // If the two are in different decl contexts, it doesn't make sense to
1860   // diagnose.
1861   if (LastRoutineDecl->getDeclContext() != ND->getLexicalDeclContext())
1862     return;
1863 
1864   // If we don't have a referenced thing yet, we can't diagnose.
1865   FunctionDecl *RoutineTarget =
1866       getFunctionFromRoutineName(LastRoutineDecl->getFunctionReference());
1867   if (!RoutineTarget)
1868     return;
1869 
1870   // If the Routine target doesn't have a name, we can't diagnose.
1871   if (!RoutineTarget->getDeclName().isIdentifier())
1872     return;
1873 
1874   // Of course don't diagnose if the names don't match.
1875   if (ND->getName() != RoutineTarget->getName())
1876     return;
1877 
1878   long NDLine = SemaRef.SourceMgr.getSpellingLineNumber(ND->getBeginLoc());
1879   long LastLine =
1880       SemaRef.SourceMgr.getSpellingLineNumber(LastRoutineDecl->getBeginLoc());
1881 
1882   // Do some line-number math to make sure they are within a line of eachother.
1883   // Comments or newlines can be inserted to clarify intent.
1884   if (NDLine - LastLine > 1)
1885     return;
1886 
1887   // Don't warn if it actually DOES apply to this function via redecls.
1888   if (ND->getCanonicalDecl() == RoutineTarget->getCanonicalDecl())
1889     return;
1890 
1891   Diag(LastRoutineDecl->getFunctionReference()->getBeginLoc(),
1892        diag::warn_acc_confusing_routine_name);
1893   Diag(RoutineTarget->getBeginLoc(), diag::note_previous_decl) << ND;
1894 }
1895 
ActOnVariableInit(VarDecl * VD,QualType InitType)1896 void SemaOpenACC::ActOnVariableInit(VarDecl *VD, QualType InitType) {
1897   if (!VD || !getLangOpts().OpenACC || InitType.isNull())
1898     return;
1899 
1900   // To avoid double-diagnostic, just diagnose this during instantiation.  We'll
1901   // get 1 warning per instantiation, but this permits us to be more sensible
1902   // for cases where the lookup is confusing.
1903   if (VD->getLexicalDeclContext()->isDependentContext())
1904     return;
1905 
1906   const auto *RD = InitType->getAsCXXRecordDecl();
1907   // If this isn't a lambda, no sense in diagnosing.
1908   if (!RD || !RD->isLambda())
1909     return;
1910 
1911   CheckLastRoutineDeclNameConflict(VD);
1912 }
1913 
ActOnFunctionDeclarator(FunctionDecl * FD)1914 void SemaOpenACC::ActOnFunctionDeclarator(FunctionDecl *FD) {
1915   if (!FD || !getLangOpts().OpenACC)
1916     return;
1917   CheckLastRoutineDeclNameConflict(FD);
1918 }
1919 
ActOnStartStmtDirective(OpenACCDirectiveKind K,SourceLocation StartLoc,ArrayRef<const OpenACCClause * > Clauses)1920 bool SemaOpenACC::ActOnStartStmtDirective(
1921     OpenACCDirectiveKind K, SourceLocation StartLoc,
1922     ArrayRef<const OpenACCClause *> Clauses) {
1923 
1924   // Declaration directives an appear in a statement location, so call into that
1925   // function here.
1926   if (K == OpenACCDirectiveKind::Declare || K == OpenACCDirectiveKind::Routine)
1927     return ActOnStartDeclDirective(K, StartLoc, Clauses);
1928 
1929   SemaRef.DiscardCleanupsInEvaluationContext();
1930   SemaRef.PopExpressionEvaluationContext();
1931 
1932   // OpenACC 3.3 2.9.1:
1933   // Intervening code must not contain other OpenACC directives or calls to API
1934   // routines.
1935   //
1936   // ALL constructs are ill-formed if there is an active 'collapse'
1937   if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {
1938     Diag(StartLoc, diag::err_acc_invalid_in_loop)
1939         << /*OpenACC Construct*/ 0 << CollapseInfo.DirectiveKind
1940         << OpenACCClauseKind::Collapse << K;
1941     assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
1942     Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
1943          diag::note_acc_active_clause_here)
1944         << OpenACCClauseKind::Collapse;
1945   }
1946   if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {
1947     Diag(StartLoc, diag::err_acc_invalid_in_loop)
1948         << /*OpenACC Construct*/ 0 << TileInfo.DirectiveKind
1949         << OpenACCClauseKind::Tile << K;
1950     assert(TileInfo.ActiveTile && "Tile count without object?");
1951     Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)
1952         << OpenACCClauseKind::Tile;
1953   }
1954 
1955   if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
1956     return true;
1957   return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
1958 }
1959 
ActOnEndStmtDirective(OpenACCDirectiveKind K,SourceLocation StartLoc,SourceLocation DirLoc,SourceLocation LParenLoc,SourceLocation MiscLoc,ArrayRef<Expr * > Exprs,OpenACCAtomicKind AtomicKind,SourceLocation RParenLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses,StmtResult AssocStmt)1960 StmtResult SemaOpenACC::ActOnEndStmtDirective(
1961     OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc,
1962     SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
1963     OpenACCAtomicKind AtomicKind, SourceLocation RParenLoc,
1964     SourceLocation EndLoc, ArrayRef<OpenACCClause *> Clauses,
1965     StmtResult AssocStmt) {
1966   switch (K) {
1967   case OpenACCDirectiveKind::Invalid:
1968     return StmtError();
1969   case OpenACCDirectiveKind::Parallel:
1970   case OpenACCDirectiveKind::Serial:
1971   case OpenACCDirectiveKind::Kernels: {
1972     return OpenACCComputeConstruct::Create(
1973         getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
1974         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1975   }
1976   case OpenACCDirectiveKind::ParallelLoop:
1977   case OpenACCDirectiveKind::SerialLoop:
1978   case OpenACCDirectiveKind::KernelsLoop: {
1979     return OpenACCCombinedConstruct::Create(
1980         getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
1981         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1982   }
1983   case OpenACCDirectiveKind::Loop: {
1984     return OpenACCLoopConstruct::Create(
1985         getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,
1986         EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1987   }
1988   case OpenACCDirectiveKind::Data: {
1989     return OpenACCDataConstruct::Create(
1990         getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
1991         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1992   }
1993   case OpenACCDirectiveKind::EnterData: {
1994     return OpenACCEnterDataConstruct::Create(getASTContext(), StartLoc, DirLoc,
1995                                              EndLoc, Clauses);
1996   }
1997   case OpenACCDirectiveKind::ExitData: {
1998     return OpenACCExitDataConstruct::Create(getASTContext(), StartLoc, DirLoc,
1999                                             EndLoc, Clauses);
2000   }
2001   case OpenACCDirectiveKind::HostData: {
2002     return OpenACCHostDataConstruct::Create(
2003         getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
2004         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
2005   }
2006   case OpenACCDirectiveKind::Wait: {
2007     return OpenACCWaitConstruct::Create(
2008         getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
2009         Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
2010   }
2011   case OpenACCDirectiveKind::Init: {
2012     return OpenACCInitConstruct::Create(getASTContext(), StartLoc, DirLoc,
2013                                         EndLoc, Clauses);
2014   }
2015   case OpenACCDirectiveKind::Shutdown: {
2016     return OpenACCShutdownConstruct::Create(getASTContext(), StartLoc, DirLoc,
2017                                             EndLoc, Clauses);
2018   }
2019   case OpenACCDirectiveKind::Set: {
2020     return OpenACCSetConstruct::Create(getASTContext(), StartLoc, DirLoc,
2021                                        EndLoc, Clauses);
2022   }
2023   case OpenACCDirectiveKind::Update: {
2024     return OpenACCUpdateConstruct::Create(getASTContext(), StartLoc, DirLoc,
2025                                           EndLoc, Clauses);
2026   }
2027   case OpenACCDirectiveKind::Atomic: {
2028     return OpenACCAtomicConstruct::Create(
2029         getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, Clauses,
2030         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
2031   }
2032   case OpenACCDirectiveKind::Cache: {
2033     assert(Clauses.empty() && "Cache doesn't allow clauses");
2034     return OpenACCCacheConstruct::Create(getASTContext(), StartLoc, DirLoc,
2035                                          LParenLoc, MiscLoc, Exprs, RParenLoc,
2036                                          EndLoc);
2037   }
2038   case OpenACCDirectiveKind::Routine:
2039     llvm_unreachable("routine shouldn't handled here");
2040   case OpenACCDirectiveKind::Declare: {
2041     // Declare and routine arei declaration directives, but can be used here as
2042     // long as we wrap it in a DeclStmt.  So make sure we do that here.
2043     DeclGroupRef DR = ActOnEndDeclDirective(K, StartLoc, DirLoc, LParenLoc,
2044                                             RParenLoc, EndLoc, Clauses);
2045 
2046     return SemaRef.ActOnDeclStmt(DeclGroupPtrTy::make(DR), StartLoc, EndLoc);
2047   }
2048   }
2049   llvm_unreachable("Unhandled case in directive handling?");
2050 }
2051 
ActOnAssociatedStmt(SourceLocation DirectiveLoc,OpenACCDirectiveKind K,OpenACCAtomicKind AtKind,ArrayRef<const OpenACCClause * > Clauses,StmtResult AssocStmt)2052 StmtResult SemaOpenACC::ActOnAssociatedStmt(
2053     SourceLocation DirectiveLoc, OpenACCDirectiveKind K,
2054     OpenACCAtomicKind AtKind, ArrayRef<const OpenACCClause *> Clauses,
2055     StmtResult AssocStmt) {
2056   switch (K) {
2057   default:
2058     llvm_unreachable("Unimplemented associated statement application");
2059   case OpenACCDirectiveKind::EnterData:
2060   case OpenACCDirectiveKind::ExitData:
2061   case OpenACCDirectiveKind::Wait:
2062   case OpenACCDirectiveKind::Init:
2063   case OpenACCDirectiveKind::Shutdown:
2064   case OpenACCDirectiveKind::Set:
2065   case OpenACCDirectiveKind::Cache:
2066     llvm_unreachable(
2067         "these don't have associated statements, so shouldn't get here");
2068   case OpenACCDirectiveKind::Atomic:
2069     return CheckAtomicAssociatedStmt(DirectiveLoc, AtKind, AssocStmt);
2070   case OpenACCDirectiveKind::Parallel:
2071   case OpenACCDirectiveKind::Serial:
2072   case OpenACCDirectiveKind::Kernels:
2073   case OpenACCDirectiveKind::Data:
2074   case OpenACCDirectiveKind::HostData:
2075     // There really isn't any checking here that could happen. As long as we
2076     // have a statement to associate, this should be fine.
2077     // OpenACC 3.3 Section 6:
2078     // Structured Block: in C or C++, an executable statement, possibly
2079     // compound, with a single entry at the top and a single exit at the
2080     // bottom.
2081     // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and
2082     // an interpretation of it is to allow this and treat the initializer as
2083     // the 'structured block'.
2084     return AssocStmt;
2085   case OpenACCDirectiveKind::Loop:
2086   case OpenACCDirectiveKind::ParallelLoop:
2087   case OpenACCDirectiveKind::SerialLoop:
2088   case OpenACCDirectiveKind::KernelsLoop:
2089     if (!AssocStmt.isUsable())
2090       return StmtError();
2091 
2092     if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) {
2093       Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop)
2094           << K;
2095       Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
2096       return StmtError();
2097     }
2098 
2099     if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {
2100       if (!CollapseInfo.CollapseDepthSatisfied) {
2101         Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2102             << OpenACCClauseKind::Collapse;
2103         assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");
2104         Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),
2105              diag::note_acc_active_clause_here)
2106             << OpenACCClauseKind::Collapse;
2107       }
2108 
2109       if (!TileInfo.TileDepthSatisfied) {
2110         Diag(DirectiveLoc, diag::err_acc_insufficient_loops)
2111             << OpenACCClauseKind::Tile;
2112         assert(TileInfo.ActiveTile && "Collapse count without object?");
2113         Diag(TileInfo.ActiveTile->getBeginLoc(),
2114              diag::note_acc_active_clause_here)
2115             << OpenACCClauseKind::Tile;
2116       }
2117       return StmtError();
2118     }
2119 
2120     return AssocStmt.get();
2121   }
2122   llvm_unreachable("Invalid associated statement application");
2123 }
2124 
2125 namespace {
2126 
2127 // Routine has some pretty complicated set of rules for how device_type
2128 // interacts with 'gang', 'worker', 'vector', and 'seq'. Enforce  part of it
2129 // here.
CheckValidRoutineGangWorkerVectorSeqClauses(SemaOpenACC & SemaRef,SourceLocation DirectiveLoc,ArrayRef<const OpenACCClause * > Clauses)2130 bool CheckValidRoutineGangWorkerVectorSeqClauses(
2131     SemaOpenACC &SemaRef, SourceLocation DirectiveLoc,
2132     ArrayRef<const OpenACCClause *> Clauses) {
2133   auto RequiredPred = llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
2134                                     OpenACCVectorClause, OpenACCSeqClause>;
2135   // The clause handling has assured us that there is no duplicates.  That is,
2136   // if there is 1 before a device_type, there are none after a device_type.
2137   // If not, there is at most 1 applying to each device_type.
2138 
2139   // What is left to legalize is that either:
2140   // 1- there is 1 before the first device_type.
2141   // 2- there is 1 AFTER each device_type.
2142   auto *FirstDeviceType =
2143       llvm::find_if(Clauses, llvm::IsaPred<OpenACCDeviceTypeClause>);
2144 
2145   // If there is 1 before the first device_type (or at all if no device_type),
2146   // we are legal.
2147   auto *ClauseItr =
2148       std::find_if(Clauses.begin(), FirstDeviceType, RequiredPred);
2149 
2150   if (ClauseItr != FirstDeviceType)
2151     return false;
2152 
2153   // If there IS no device_type, and no clause, diagnose.
2154   if (FirstDeviceType == Clauses.end())
2155     return SemaRef.Diag(DirectiveLoc, diag::err_acc_construct_one_clause_of)
2156            << OpenACCDirectiveKind::Routine
2157            << "'gang', 'seq', 'vector', or 'worker'";
2158 
2159   // Else, we have to check EACH device_type group. PrevDeviceType is the
2160   // device-type before the current group.
2161   auto *PrevDeviceType = FirstDeviceType;
2162 
2163   while (PrevDeviceType != Clauses.end()) {
2164     auto *NextDeviceType =
2165         std::find_if(std::next(PrevDeviceType), Clauses.end(),
2166                      llvm::IsaPred<OpenACCDeviceTypeClause>);
2167 
2168     ClauseItr = std::find_if(PrevDeviceType, NextDeviceType, RequiredPred);
2169 
2170     if (ClauseItr == NextDeviceType)
2171       return SemaRef.Diag((*PrevDeviceType)->getBeginLoc(),
2172                           diag::err_acc_clause_routine_one_of_in_region);
2173 
2174     PrevDeviceType = NextDeviceType;
2175   }
2176 
2177   return false;
2178 }
2179 } // namespace
2180 
ActOnStartDeclDirective(OpenACCDirectiveKind K,SourceLocation StartLoc,ArrayRef<const OpenACCClause * > Clauses)2181 bool SemaOpenACC::ActOnStartDeclDirective(
2182     OpenACCDirectiveKind K, SourceLocation StartLoc,
2183     ArrayRef<const OpenACCClause *> Clauses) {
2184   // OpenCC3.3 2.1 (line 889)
2185   // A program must not depend on the order of evaluation of expressions in
2186   // clause arguments or on any side effects of the evaluations.
2187   SemaRef.DiscardCleanupsInEvaluationContext();
2188   SemaRef.PopExpressionEvaluationContext();
2189 
2190   if (DiagnoseRequiredClauses(K, StartLoc, Clauses))
2191     return true;
2192   if (K == OpenACCDirectiveKind::Routine &&
2193       CheckValidRoutineGangWorkerVectorSeqClauses(*this, StartLoc, Clauses))
2194     return true;
2195 
2196   return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
2197 }
2198 
ActOnEndDeclDirective(OpenACCDirectiveKind K,SourceLocation StartLoc,SourceLocation DirLoc,SourceLocation LParenLoc,SourceLocation RParenLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses)2199 DeclGroupRef SemaOpenACC::ActOnEndDeclDirective(
2200     OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc,
2201     SourceLocation LParenLoc, SourceLocation RParenLoc, SourceLocation EndLoc,
2202     ArrayRef<OpenACCClause *> Clauses) {
2203   switch (K) {
2204   default:
2205   case OpenACCDirectiveKind::Invalid:
2206     return DeclGroupRef{};
2207   case OpenACCDirectiveKind::Declare: {
2208     // OpenACC3.3 2.13: At least one clause must appear on a declare directive.
2209     if (Clauses.empty()) {
2210       Diag(EndLoc, diag::err_acc_declare_required_clauses);
2211       // No reason to add this to the AST, as we would just end up trying to
2212       // instantiate this, which would double-diagnose here, which we wouldn't
2213       // want to do.
2214       return DeclGroupRef{};
2215     }
2216 
2217     auto *DeclareDecl = OpenACCDeclareDecl::Create(
2218         getASTContext(), getCurContext(), StartLoc, DirLoc, EndLoc, Clauses);
2219     DeclareDecl->setAccess(AS_public);
2220     getCurContext()->addDecl(DeclareDecl);
2221     return DeclGroupRef{DeclareDecl};
2222   }
2223   case OpenACCDirectiveKind::Routine:
2224     llvm_unreachable("routine shouldn't be handled here");
2225   }
2226   llvm_unreachable("unhandled case in directive handling?");
2227 }
2228 
2229 namespace {
2230 // Given the decl on the next line, figure out if it is one that is acceptable
2231 // to `routine`, or looks like the sort of decl we should be diagnosing against.
LegalizeNextParsedDecl(Decl * D)2232 FunctionDecl *LegalizeNextParsedDecl(Decl *D) {
2233   if (!D)
2234     return nullptr;
2235 
2236   // Functions are per-fact acceptable as-is.
2237   if (auto *FD = dyn_cast<FunctionDecl>(D))
2238     return FD;
2239 
2240   // Function templates are functions, so attach to the templated decl.
2241   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
2242     return FTD->getTemplatedDecl();
2243 
2244   if (auto *FD = dyn_cast<FieldDecl>(D)) {
2245     auto *RD =
2246         FD->getType().isNull() ? nullptr : FD->getType()->getAsCXXRecordDecl();
2247 
2248     if (RD && RD->isGenericLambda())
2249       return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2250     if (RD && RD->isLambda())
2251       return RD->getLambdaCallOperator();
2252   }
2253   // VarDecl we can look at the init instead of the type of the variable, this
2254   // makes us more tolerant of the 'auto' deduced type.
2255   if (auto *VD = dyn_cast<VarDecl>(D)) {
2256     Expr *Init = VD->getInit();
2257     if (!Init || Init->getType().isNull())
2258       return nullptr;
2259 
2260     const auto *RD = Init->getType()->getAsCXXRecordDecl();
2261     if (RD && RD->isGenericLambda())
2262       return RD->getDependentLambdaCallOperator()->getTemplatedDecl();
2263     if (RD && RD->isLambda())
2264       return RD->getLambdaCallOperator();
2265 
2266     // FIXME: We could try harder in the case where this is a dependent thing
2267     // that ends up being a lambda (that is, the init is an unresolved lookup
2268     // expr), but we can't attach to the call/lookup expr. If we instead try to
2269     // attach to the VarDecl, when we go to instantiate it, attributes are
2270     // instantiated before the init, so we can't actually see the type at any
2271     // point where it would be relevant/able to be checked. We could perhaps do
2272     // some sort of 'after-init' instantiation/checking here, but that doesn't
2273     // seem valuable for a situation that other compilers don't handle.
2274   }
2275   return nullptr;
2276 }
2277 
CreateRoutineDeclAttr(SemaOpenACC & SemaRef,SourceLocation DirLoc,ArrayRef<const OpenACCClause * > Clauses,ValueDecl * AddTo)2278 void CreateRoutineDeclAttr(SemaOpenACC &SemaRef, SourceLocation DirLoc,
2279                            ArrayRef<const OpenACCClause *> Clauses,
2280                            ValueDecl *AddTo) {
2281   OpenACCRoutineDeclAttr *A =
2282       OpenACCRoutineDeclAttr::Create(SemaRef.getASTContext(), DirLoc);
2283   A->Clauses.assign(Clauses.begin(), Clauses.end());
2284   AddTo->addAttr(A);
2285 }
2286 } // namespace
2287 
2288 // Variant that adds attributes, because this is the unnamed case.
CheckRoutineDecl(SourceLocation DirLoc,ArrayRef<const OpenACCClause * > Clauses,Decl * NextParsedDecl)2289 void SemaOpenACC::CheckRoutineDecl(SourceLocation DirLoc,
2290                                    ArrayRef<const OpenACCClause *> Clauses,
2291                                    Decl *NextParsedDecl) {
2292 
2293   FunctionDecl *NextParsedFDecl = LegalizeNextParsedDecl(NextParsedDecl);
2294 
2295   if (!NextParsedFDecl) {
2296     // If we don't have a valid 'next thing', just diagnose.
2297     SemaRef.Diag(DirLoc, diag::err_acc_decl_for_routine);
2298     return;
2299   }
2300 
2301   // OpenACC 3.3 2.15:
2302   // In C and C++, function static variables are not supported in functions to
2303   // which a routine directive applies.
2304   if (auto Itr = MagicStaticLocs.find(NextParsedFDecl->getCanonicalDecl());
2305       Itr != MagicStaticLocs.end()) {
2306     Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2307     Diag(DirLoc, diag::note_acc_construct_here)
2308         << OpenACCDirectiveKind::Routine;
2309 
2310     return;
2311   }
2312 
2313   auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2314   for (auto *A : NextParsedFDecl->attrs()) {
2315     // OpenACC 3.3 2.15:
2316     // If a procedure has a bind clause on both the declaration and definition
2317     // than they both must bind to the same name.
2318     if (auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2319       auto OtherBindItr =
2320           llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2321       if (OtherBindItr != RA->Clauses.end() &&
2322           (*cast<OpenACCBindClause>(*BindItr)) !=
2323               (*cast<OpenACCBindClause>(*OtherBindItr))) {
2324         Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
2325         Diag((*OtherBindItr)->getEndLoc(), diag::note_acc_previous_clause_here)
2326             << (*BindItr)->getClauseKind();
2327         return;
2328       }
2329     }
2330 
2331     // OpenACC 3.3 2.15:
2332     // A bind clause may not bind to a routine name that has a visible bind
2333     // clause.
2334     // We take the combo of these two 2.15 restrictions to mean that the
2335     // 'declaration'/'definition' quote is an exception to this. So we're going
2336     // to disallow mixing of the two types entirely.
2337     if (auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2338         RA && RA->getRange().getEnd().isValid()) {
2339       Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2340       Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2341           << "bind";
2342       return;
2343     }
2344   }
2345 
2346   CreateRoutineDeclAttr(*this, DirLoc, Clauses, NextParsedFDecl);
2347 }
2348 
2349 // Variant that adds a decl, because this is the named case.
CheckRoutineDecl(SourceLocation StartLoc,SourceLocation DirLoc,SourceLocation LParenLoc,Expr * FuncRef,SourceLocation RParenLoc,ArrayRef<const OpenACCClause * > Clauses,SourceLocation EndLoc)2350 OpenACCRoutineDecl *SemaOpenACC::CheckRoutineDecl(
2351     SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
2352     Expr *FuncRef, SourceLocation RParenLoc,
2353     ArrayRef<const OpenACCClause *> Clauses, SourceLocation EndLoc) {
2354   assert(LParenLoc.isValid());
2355 
2356   if (FunctionDecl *FD = getFunctionFromRoutineName(FuncRef)) {
2357     // OpenACC 3.3 2.15:
2358     // In C and C++, function static variables are not supported in functions to
2359     // which a routine directive applies.
2360     if (auto Itr = MagicStaticLocs.find(FD->getCanonicalDecl());
2361         Itr != MagicStaticLocs.end()) {
2362       Diag(Itr->second, diag::err_acc_magic_static_in_routine);
2363       Diag(DirLoc, diag::note_acc_construct_here)
2364           << OpenACCDirectiveKind::Routine;
2365 
2366       return nullptr;
2367     }
2368 
2369     // OpenACC 3.3 2.15:
2370     // A bind clause may not bind to a routine name that has a visible bind
2371     // clause.
2372     auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
2373     SourceLocation BindLoc;
2374     if (BindItr != Clauses.end()) {
2375       BindLoc = (*BindItr)->getBeginLoc();
2376       // Since this is adding a 'named' routine, we aren't allowed to combine
2377       // with ANY other visible bind clause. Error if we see either.
2378 
2379       for (auto *A : FD->attrs()) {
2380         if (auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
2381           auto OtherBindItr =
2382               llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
2383           if (OtherBindItr != RA->Clauses.end()) {
2384             Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2385             Diag((*OtherBindItr)->getEndLoc(),
2386                  diag::note_acc_previous_clause_here)
2387                 << (*BindItr)->getClauseKind();
2388             return nullptr;
2389           }
2390         }
2391 
2392         if (auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
2393             RA && RA->getRange().getEnd().isValid()) {
2394           Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
2395           Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
2396               << (*BindItr)->getClauseKind();
2397           return nullptr;
2398         }
2399       }
2400     }
2401 
2402     // Set the end-range to the 'bind' clause here, so we can look it up
2403     // later.
2404     auto *RAA = OpenACCRoutineAnnotAttr::CreateImplicit(getASTContext(),
2405                                                         {DirLoc, BindLoc});
2406     FD->addAttr(RAA);
2407     // In case we are referencing not the 'latest' version, make sure we add
2408     // the attribute to all declarations.
2409     while (FD != FD->getMostRecentDecl()) {
2410       FD = FD->getMostRecentDecl();
2411       FD->addAttr(RAA);
2412     }
2413   }
2414 
2415   LastRoutineDecl = OpenACCRoutineDecl::Create(
2416       getASTContext(), getCurContext(), StartLoc, DirLoc, LParenLoc, FuncRef,
2417       RParenLoc, EndLoc, Clauses);
2418   LastRoutineDecl->setAccess(AS_public);
2419   getCurContext()->addDecl(LastRoutineDecl);
2420 
2421   return LastRoutineDecl;
2422 }
2423 
ActOnEndRoutineDeclDirective(SourceLocation StartLoc,SourceLocation DirLoc,SourceLocation LParenLoc,Expr * ReferencedFunc,SourceLocation RParenLoc,ArrayRef<const OpenACCClause * > Clauses,SourceLocation EndLoc,DeclGroupPtrTy NextDecl)2424 DeclGroupRef SemaOpenACC::ActOnEndRoutineDeclDirective(
2425     SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
2426     Expr *ReferencedFunc, SourceLocation RParenLoc,
2427     ArrayRef<const OpenACCClause *> Clauses, SourceLocation EndLoc,
2428     DeclGroupPtrTy NextDecl) {
2429   assert((!ReferencedFunc || !NextDecl) &&
2430          "Only one of these should be filled");
2431 
2432   if (LParenLoc.isInvalid()) {
2433     Decl *NextLineDecl = nullptr;
2434     if (NextDecl && NextDecl.get().isSingleDecl())
2435       NextLineDecl = NextDecl.get().getSingleDecl();
2436 
2437     CheckRoutineDecl(DirLoc, Clauses, NextLineDecl);
2438 
2439     return NextDecl.get();
2440   }
2441 
2442   return DeclGroupRef{CheckRoutineDecl(
2443       StartLoc, DirLoc, LParenLoc, ReferencedFunc, RParenLoc, Clauses, EndLoc)};
2444 }
2445 
ActOnEndRoutineStmtDirective(SourceLocation StartLoc,SourceLocation DirLoc,SourceLocation LParenLoc,Expr * ReferencedFunc,SourceLocation RParenLoc,ArrayRef<const OpenACCClause * > Clauses,SourceLocation EndLoc,Stmt * NextStmt)2446 StmtResult SemaOpenACC::ActOnEndRoutineStmtDirective(
2447     SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
2448     Expr *ReferencedFunc, SourceLocation RParenLoc,
2449     ArrayRef<const OpenACCClause *> Clauses, SourceLocation EndLoc,
2450     Stmt *NextStmt) {
2451   assert((!ReferencedFunc || !NextStmt) &&
2452          "Only one of these should be filled");
2453 
2454   if (LParenLoc.isInvalid()) {
2455     Decl *NextLineDecl = nullptr;
2456     if (NextStmt)
2457       if (DeclStmt *DS = dyn_cast<DeclStmt>(NextStmt); DS && DS->isSingleDecl())
2458         NextLineDecl = DS->getSingleDecl();
2459 
2460     CheckRoutineDecl(DirLoc, Clauses, NextLineDecl);
2461     return NextStmt;
2462   }
2463 
2464   DeclGroupRef DR{CheckRoutineDecl(StartLoc, DirLoc, LParenLoc, ReferencedFunc,
2465                                    RParenLoc, Clauses, EndLoc)};
2466   return SemaRef.ActOnDeclStmt(DeclGroupPtrTy::make(DR), StartLoc, EndLoc);
2467 }
2468 
2469 OpenACCRoutineDeclAttr *
mergeRoutineDeclAttr(const OpenACCRoutineDeclAttr & Old)2470 SemaOpenACC::mergeRoutineDeclAttr(const OpenACCRoutineDeclAttr &Old) {
2471   OpenACCRoutineDeclAttr *New =
2472       OpenACCRoutineDeclAttr::Create(getASTContext(), Old.getLocation());
2473   // We should jsut be able to copy these, there isn't really any
2474   // merging/inheriting we have to do, so no worry about doing a deep copy.
2475   New->Clauses = Old.Clauses;
2476   return New;
2477 }
2478 ExprResult
BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)2479 SemaOpenACC::BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
2480   return OpenACCAsteriskSizeExpr::Create(getASTContext(), AsteriskLoc);
2481 }
2482 
2483 ExprResult
ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)2484 SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
2485   return BuildOpenACCAsteriskSizeExpr(AsteriskLoc);
2486 }
2487