xref: /freebsd/contrib/llvm-project/clang/include/clang/Sema/SemaOpenACC.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===----- SemaOpenACC.h - 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 declares semantic analysis for OpenACC constructs and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_SEMA_SEMAOPENACC_H
15 #define LLVM_CLANG_SEMA_SEMAOPENACC_H
16 
17 #include "clang/AST/DeclGroup.h"
18 #include "clang/AST/StmtOpenACC.h"
19 #include "clang/Basic/LLVM.h"
20 #include "clang/Basic/OpenACCKinds.h"
21 #include "clang/Basic/SourceLocation.h"
22 #include "clang/Sema/Ownership.h"
23 #include "clang/Sema/SemaBase.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/Support/Compiler.h"
26 #include <cassert>
27 #include <optional>
28 #include <utility>
29 #include <variant>
30 
31 namespace clang {
32 class IdentifierInfo;
33 class OpenACCClause;
34 class Scope;
35 
36 class SemaOpenACC : public SemaBase {
37 public:
38   using DeclGroupPtrTy = OpaquePtr<DeclGroupRef>;
39 
40 private:
41   struct ComputeConstructInfo {
42     /// Which type of compute construct we are inside of, which we can use to
43     /// determine whether we should add loops to the above collection.  We can
44     /// also use it to diagnose loop construct clauses.
45     OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid;
46     // If we have an active compute construct, stores the list of clauses we've
47     // prepared for it, so that we can diagnose limitations on child constructs.
48     ArrayRef<OpenACCClause *> Clauses;
49   } ActiveComputeConstructInfo;
50 
isInComputeConstruct()51   bool isInComputeConstruct() const {
52     return ActiveComputeConstructInfo.Kind != OpenACCDirectiveKind::Invalid;
53   }
54 
55   /// Certain clauses care about the same things that aren't specific to the
56   /// individual clause, but can be shared by a few, so store them here. All
57   /// require a 'no intervening constructs' rule, so we know they are all from
58   /// the same 'place'.
59   struct LoopCheckingInfo {
60     /// Records whether we've seen the top level 'for'. We already diagnose
61     /// later that the 'top level' is a for loop, so we use this to suppress the
62     /// 'collapse inner loop not a 'for' loop' diagnostic.
63     LLVM_PREFERRED_TYPE(bool)
64     unsigned TopLevelLoopSeen : 1;
65 
66     /// Records whether this 'tier' of the loop has already seen a 'for' loop,
67     /// used to diagnose if there are multiple 'for' loops at any one level.
68     LLVM_PREFERRED_TYPE(bool)
69     unsigned CurLevelHasLoopAlready : 1;
70 
71   } LoopInfo{/*TopLevelLoopSeen=*/false, /*CurLevelHasLoopAlready=*/false};
72 
73   /// The 'collapse' clause requires quite a bit of checking while
74   /// parsing/instantiating its body, so this structure/object keeps all of the
75   /// necessary information as we do checking.  This should rarely be directly
76   /// modified, and typically should be controlled by the RAII objects.
77   ///
78   /// Collapse has an 'N' count that makes it apply to a number of loops 'below'
79   /// it.
80   struct CollapseCheckingInfo {
81     const OpenACCCollapseClause *ActiveCollapse = nullptr;
82 
83     /// This is a value that maintains the current value of the 'N' on the
84     /// current collapse, minus the depth that has already been traversed. When
85     /// there is not an active collapse, or a collapse whose depth we don't know
86     /// (for example, if it is a dependent value), this should be `nullopt`,
87     /// else it should be 'N' minus the current depth traversed.
88     std::optional<llvm::APSInt> CurCollapseCount;
89 
90     /// Records whether we've hit a CurCollapseCount of '0' on the way down,
91     /// which allows us to diagnose if the value of 'N' is too large for the
92     /// current number of 'for' loops.
93     bool CollapseDepthSatisfied = true;
94 
95     /// Records the kind of the directive that this clause is attached to, which
96     /// allows us to use it in diagnostics.
97     OpenACCDirectiveKind DirectiveKind = OpenACCDirectiveKind::Invalid;
98   } CollapseInfo;
99 
100   /// The 'tile' clause requires a bit of additional checking as well, so like
101   /// the `CollapseCheckingInfo`, ensure we maintain information here too.
102   struct TileCheckingInfo {
103     OpenACCTileClause *ActiveTile = nullptr;
104 
105     /// This is the number of expressions on a 'tile' clause.  This doesn't have
106     /// to be an APSInt because it isn't the result of a constexpr, just by our
107     /// own counting of elements.
108     UnsignedOrNone CurTileCount = std::nullopt;
109 
110     /// Records whether we've hit a 'CurTileCount' of '0' on the way down,
111     /// which allows us to diagnose if the number of arguments is too large for
112     /// the current number of 'for' loops.
113     bool TileDepthSatisfied = true;
114 
115     /// Records the kind of the directive that this clause is attached to, which
116     /// allows us to use it in diagnostics.
117     OpenACCDirectiveKind DirectiveKind = OpenACCDirectiveKind::Invalid;
118   } TileInfo;
119 
120   /// The 'cache' var-list requires some additional work to track variable
121   /// references to make sure they are on the 'other' side of a `loop`. This
122   /// structure is used during parse time to track vardecl use while parsing a
123   /// cache var list.
124   struct CacheParseInfo {
125     bool ParsingCacheVarList = false;
126     bool IsInvalidCacheRef = false;
127   } CacheInfo;
128 
129   /// A list of the active reduction clauses, which allows us to check that all
130   /// vars on nested constructs for the same reduction var have the same
131   /// reduction operator. Currently this is enforced against all constructs
132   /// despite the rule being in the 'loop' section. By current reading, this
133   /// should apply to all anyway, but we may need to make this more like the
134   /// 'loop' clause enforcement, where this is 'blocked' by a compute construct.
135   llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
136 
137   // Type to check the 'for' (or range-for) statement for compatibility with the
138   // 'loop' directive.
139   class ForStmtBeginChecker {
140     SemaOpenACC &SemaRef;
141     SourceLocation ForLoc;
142     bool IsInstantiation = false;
143 
144     struct RangeForInfo {
145       const CXXForRangeStmt *Uninstantiated = nullptr;
146       const CXXForRangeStmt *CurrentVersion = nullptr;
147       // GCC 7.x requires this constructor, else the construction of variant
148       // doesn't work correctly.
RangeForInfoRangeForInfo149       RangeForInfo() : Uninstantiated{nullptr}, CurrentVersion{nullptr} {}
RangeForInfoRangeForInfo150       RangeForInfo(const CXXForRangeStmt *Uninst, const CXXForRangeStmt *Cur)
151           : Uninstantiated{Uninst}, CurrentVersion{Cur} {}
152     };
153 
154     struct ForInfo {
155       const Stmt *Init = nullptr;
156       const Stmt *Condition = nullptr;
157       const Stmt *Increment = nullptr;
158     };
159 
160     struct CheckForInfo {
161       ForInfo Uninst;
162       ForInfo Current;
163     };
164 
165     std::variant<RangeForInfo, CheckForInfo> Info;
166     // Prevent us from checking 2x, which can happen with collapse & tile.
167     bool AlreadyChecked = false;
168 
169     void checkRangeFor();
170 
171     bool checkForInit(const Stmt *InitStmt, const ValueDecl *&InitVar,
172                       bool Diag);
173     bool checkForCond(const Stmt *CondStmt, const ValueDecl *InitVar,
174                       bool Diag);
175     bool checkForInc(const Stmt *IncStmt, const ValueDecl *InitVar, bool Diag);
176 
177     void checkFor();
178 
179     //  void checkRangeFor(); ?? ERICH
180     //  const ValueDecl *checkInit();
181     //  void checkCond(const ValueDecl *Init);
182     //  void checkInc(const ValueDecl *Init);
183   public:
184     // Checking for non-instantiation version of a Range-for.
ForStmtBeginChecker(SemaOpenACC & SemaRef,SourceLocation ForLoc,const CXXForRangeStmt * RangeFor)185     ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
186                         const CXXForRangeStmt *RangeFor)
187         : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(false),
188           Info(RangeForInfo{nullptr, RangeFor}) {}
189     // Checking for an instantiation of the range-for.
ForStmtBeginChecker(SemaOpenACC & SemaRef,SourceLocation ForLoc,const CXXForRangeStmt * OldRangeFor,const CXXForRangeStmt * RangeFor)190     ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
191                         const CXXForRangeStmt *OldRangeFor,
192                         const CXXForRangeStmt *RangeFor)
193         : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(true),
194           Info(RangeForInfo{OldRangeFor, RangeFor}) {}
195     // Checking for a non-instantiation version of a traditional for.
ForStmtBeginChecker(SemaOpenACC & SemaRef,SourceLocation ForLoc,const Stmt * Init,const Stmt * Cond,const Stmt * Inc)196     ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
197                         const Stmt *Init, const Stmt *Cond, const Stmt *Inc)
198         : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(false),
199           Info(CheckForInfo{{}, {Init, Cond, Inc}}) {}
200     // Checking for an instantiation version of a traditional for.
ForStmtBeginChecker(SemaOpenACC & SemaRef,SourceLocation ForLoc,const Stmt * OldInit,const Stmt * OldCond,const Stmt * OldInc,const Stmt * Init,const Stmt * Cond,const Stmt * Inc)201     ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
202                         const Stmt *OldInit, const Stmt *OldCond,
203                         const Stmt *OldInc, const Stmt *Init, const Stmt *Cond,
204                         const Stmt *Inc)
205         : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(true),
206           Info(CheckForInfo{{OldInit, OldCond, OldInc}, {Init, Cond, Inc}}) {}
207 
208     void check();
209   };
210 
211   /// Helper function for checking the 'for' and 'range for' stmts.
212   void ForStmtBeginHelper(SourceLocation ForLoc, ForStmtBeginChecker &C);
213 
214   // The 'declare' construct requires only a single reference among ALL declare
215   // directives in a context. We store existing references to check. Because the
216   // rules prevent referencing the same variable from multiple declaration
217   // contexts, we can just store the declaration and location of the reference.
218   llvm::DenseMap<const clang::DeclaratorDecl *, SourceLocation>
219       DeclareVarReferences;
220   // The 'routine' construct disallows magic-statics in a function referred to
221   // by a 'routine' directive.  So record any of these that we see so we can
222   // check them later.
223   llvm::SmallDenseMap<const clang::FunctionDecl *, SourceLocation>
224       MagicStaticLocs;
225   OpenACCRoutineDecl *LastRoutineDecl = nullptr;
226 
227   void CheckLastRoutineDeclNameConflict(const NamedDecl *ND);
228 
229   bool DiagnoseRequiredClauses(OpenACCDirectiveKind DK, SourceLocation DirLoc,
230                                ArrayRef<const OpenACCClause *> Clauses);
231 
232   bool DiagnoseAllowedClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
233                               SourceLocation ClauseLoc);
234 
235 public:
236   // Needed from the visitor, so should be public.
237   bool DiagnoseAllowedOnceClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
238                                   SourceLocation ClauseLoc,
239                                   ArrayRef<const OpenACCClause *> Clauses);
240   bool DiagnoseExclusiveClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
241                                 SourceLocation ClauseLoc,
242                                 ArrayRef<const OpenACCClause *> Clauses);
243 
244 public:
getActiveComputeConstructInfo()245   ComputeConstructInfo &getActiveComputeConstructInfo() {
246     return ActiveComputeConstructInfo;
247   }
248 
249   /// If there is a current 'active' loop construct with a 'gang' clause on a
250   /// 'kernel' construct, this will have the source location for it, and the
251   /// 'kernel kind'. This permits us to implement the restriction of no further
252   /// 'gang' clauses.
253   struct LoopGangOnKernelTy {
254     SourceLocation Loc;
255     OpenACCDirectiveKind DirKind = OpenACCDirectiveKind::Invalid;
256   } LoopGangClauseOnKernel;
257 
258   /// If there is a current 'active' loop construct with a 'worker' clause on it
259   /// (on any sort of construct), this has the source location for it.  This
260   /// permits us to implement the restriction of no further 'gang' or 'worker'
261   /// clauses.
262   SourceLocation LoopWorkerClauseLoc;
263   /// If there is a current 'active' loop construct with a 'vector' clause on it
264   /// (on any sort of construct), this has the source location for it.  This
265   /// permits us to implement the restriction of no further 'gang', 'vector', or
266   /// 'worker' clauses.
267   SourceLocation LoopVectorClauseLoc;
268   /// If there is a current 'active' loop construct that does NOT have a 'seq'
269   /// clause on it, this has that source location and loop Directive 'kind'.
270   /// This permits us to implement the 'loop' restrictions on the loop variable.
271   /// This can be extended via 'collapse', so we need to keep this around for a
272   /// while.
273   struct LoopWithoutSeqCheckingInfo {
274     OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid;
275     SourceLocation Loc;
276   } LoopWithoutSeqInfo;
277 
278   // Redeclaration of the version in OpenACCClause.h.
279   using DeviceTypeArgument = IdentifierLoc;
280 
281   /// A type to represent all the data for an OpenACC Clause that has been
282   /// parsed, but not yet created/semantically analyzed. This is effectively a
283   /// discriminated union on the 'Clause Kind', with all of the individual
284   /// clause details stored in a std::variant.
285   class OpenACCParsedClause {
286     OpenACCDirectiveKind DirKind;
287     OpenACCClauseKind ClauseKind;
288     SourceRange ClauseRange;
289     SourceLocation LParenLoc;
290 
291     struct DefaultDetails {
292       OpenACCDefaultClauseKind DefaultClauseKind;
293     };
294 
295     struct ConditionDetails {
296       Expr *ConditionExpr;
297     };
298 
299     struct IntExprDetails {
300       SmallVector<Expr *> IntExprs;
301     };
302 
303     struct VarListDetails {
304       SmallVector<Expr *> VarList;
305       OpenACCModifierKind ModifierKind;
306     };
307 
308     struct WaitDetails {
309       Expr *DevNumExpr;
310       SourceLocation QueuesLoc;
311       SmallVector<Expr *> QueueIdExprs;
312     };
313 
314     struct DeviceTypeDetails {
315       SmallVector<DeviceTypeArgument> Archs;
316     };
317     struct ReductionDetails {
318       OpenACCReductionOperator Op;
319       SmallVector<Expr *> VarList;
320     };
321 
322     struct CollapseDetails {
323       bool IsForce;
324       Expr *LoopCount;
325     };
326 
327     struct GangDetails {
328       SmallVector<OpenACCGangKind> GangKinds;
329       SmallVector<Expr *> IntExprs;
330     };
331     struct BindDetails {
332       std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
333           Argument;
334     };
335 
336     std::variant<std::monostate, DefaultDetails, ConditionDetails,
337                  IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
338                  ReductionDetails, CollapseDetails, GangDetails, BindDetails>
339         Details = std::monostate{};
340 
341   public:
OpenACCParsedClause(OpenACCDirectiveKind DirKind,OpenACCClauseKind ClauseKind,SourceLocation BeginLoc)342     OpenACCParsedClause(OpenACCDirectiveKind DirKind,
343                         OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
344         : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
345 
getDirectiveKind()346     OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }
347 
getClauseKind()348     OpenACCClauseKind getClauseKind() const { return ClauseKind; }
349 
getBeginLoc()350     SourceLocation getBeginLoc() const { return ClauseRange.getBegin(); }
351 
getLParenLoc()352     SourceLocation getLParenLoc() const { return LParenLoc; }
353 
getEndLoc()354     SourceLocation getEndLoc() const { return ClauseRange.getEnd(); }
355 
getDefaultClauseKind()356     OpenACCDefaultClauseKind getDefaultClauseKind() const {
357       assert(ClauseKind == OpenACCClauseKind::Default &&
358              "Parsed clause is not a default clause");
359       return std::get<DefaultDetails>(Details).DefaultClauseKind;
360     }
361 
getConditionExpr()362     const Expr *getConditionExpr() const {
363       return const_cast<OpenACCParsedClause *>(this)->getConditionExpr();
364     }
365 
getConditionExpr()366     Expr *getConditionExpr() {
367       assert((ClauseKind == OpenACCClauseKind::If ||
368               (ClauseKind == OpenACCClauseKind::Self &&
369                DirKind != OpenACCDirectiveKind::Update)) &&
370              "Parsed clause kind does not have a condition expr");
371 
372       // 'self' has an optional ConditionExpr, so be tolerant of that. This will
373       // assert in variant otherwise.
374       if (ClauseKind == OpenACCClauseKind::Self &&
375           std::holds_alternative<std::monostate>(Details))
376         return nullptr;
377 
378       return std::get<ConditionDetails>(Details).ConditionExpr;
379     }
380 
getNumIntExprs()381     unsigned getNumIntExprs() const {
382       assert((ClauseKind == OpenACCClauseKind::NumGangs ||
383               ClauseKind == OpenACCClauseKind::NumWorkers ||
384               ClauseKind == OpenACCClauseKind::Async ||
385               ClauseKind == OpenACCClauseKind::DeviceNum ||
386               ClauseKind == OpenACCClauseKind::DefaultAsync ||
387               ClauseKind == OpenACCClauseKind::Tile ||
388               ClauseKind == OpenACCClauseKind::Worker ||
389               ClauseKind == OpenACCClauseKind::Vector ||
390               ClauseKind == OpenACCClauseKind::VectorLength) &&
391              "Parsed clause kind does not have a int exprs");
392 
393       // 'async', 'worker', 'vector', and 'wait' have an optional IntExpr, so be
394       // tolerant of that.
395       if ((ClauseKind == OpenACCClauseKind::Async ||
396            ClauseKind == OpenACCClauseKind::Worker ||
397            ClauseKind == OpenACCClauseKind::Vector ||
398            ClauseKind == OpenACCClauseKind::Wait) &&
399           std::holds_alternative<std::monostate>(Details))
400         return 0;
401       return std::get<IntExprDetails>(Details).IntExprs.size();
402     }
403 
getQueuesLoc()404     SourceLocation getQueuesLoc() const {
405       assert(ClauseKind == OpenACCClauseKind::Wait &&
406              "Parsed clause kind does not have a queues location");
407 
408       if (std::holds_alternative<std::monostate>(Details))
409         return SourceLocation{};
410 
411       return std::get<WaitDetails>(Details).QueuesLoc;
412     }
413 
getDevNumExpr()414     Expr *getDevNumExpr() const {
415       assert(ClauseKind == OpenACCClauseKind::Wait &&
416              "Parsed clause kind does not have a device number expr");
417 
418       if (std::holds_alternative<std::monostate>(Details))
419         return nullptr;
420 
421       return std::get<WaitDetails>(Details).DevNumExpr;
422     }
423 
getQueueIdExprs()424     ArrayRef<Expr *> getQueueIdExprs() const {
425       assert(ClauseKind == OpenACCClauseKind::Wait &&
426              "Parsed clause kind does not have a queue id expr list");
427 
428       if (std::holds_alternative<std::monostate>(Details))
429         return ArrayRef<Expr *>();
430 
431       return std::get<WaitDetails>(Details).QueueIdExprs;
432     }
433 
getIntExprs()434     ArrayRef<Expr *> getIntExprs() {
435       assert((ClauseKind == OpenACCClauseKind::NumGangs ||
436               ClauseKind == OpenACCClauseKind::NumWorkers ||
437               ClauseKind == OpenACCClauseKind::Async ||
438               ClauseKind == OpenACCClauseKind::DeviceNum ||
439               ClauseKind == OpenACCClauseKind::DefaultAsync ||
440               ClauseKind == OpenACCClauseKind::Tile ||
441               ClauseKind == OpenACCClauseKind::Gang ||
442               ClauseKind == OpenACCClauseKind::Worker ||
443               ClauseKind == OpenACCClauseKind::Vector ||
444               ClauseKind == OpenACCClauseKind::VectorLength) &&
445              "Parsed clause kind does not have a int exprs");
446 
447       if (ClauseKind == OpenACCClauseKind::Gang) {
448         // There might not be any gang int exprs, as this is an optional
449         // argument.
450         if (std::holds_alternative<std::monostate>(Details))
451           return {};
452         return std::get<GangDetails>(Details).IntExprs;
453       }
454 
455       return std::get<IntExprDetails>(Details).IntExprs;
456     }
457 
getIntExprs()458     ArrayRef<Expr *> getIntExprs() const {
459       return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
460     }
461 
getReductionOp()462     OpenACCReductionOperator getReductionOp() const {
463       return std::get<ReductionDetails>(Details).Op;
464     }
465 
getGangKinds()466     ArrayRef<OpenACCGangKind> getGangKinds() const {
467       assert(ClauseKind == OpenACCClauseKind::Gang &&
468              "Parsed clause kind does not have gang kind");
469       // The args on gang are optional, so this might not actually hold
470       // anything.
471       if (std::holds_alternative<std::monostate>(Details))
472         return {};
473       return std::get<GangDetails>(Details).GangKinds;
474     }
475 
getVarList()476     ArrayRef<Expr *> getVarList() {
477       assert((ClauseKind == OpenACCClauseKind::Private ||
478               ClauseKind == OpenACCClauseKind::NoCreate ||
479               ClauseKind == OpenACCClauseKind::Present ||
480               ClauseKind == OpenACCClauseKind::Copy ||
481               ClauseKind == OpenACCClauseKind::PCopy ||
482               ClauseKind == OpenACCClauseKind::PresentOrCopy ||
483               ClauseKind == OpenACCClauseKind::CopyIn ||
484               ClauseKind == OpenACCClauseKind::PCopyIn ||
485               ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
486               ClauseKind == OpenACCClauseKind::CopyOut ||
487               ClauseKind == OpenACCClauseKind::PCopyOut ||
488               ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
489               ClauseKind == OpenACCClauseKind::Create ||
490               ClauseKind == OpenACCClauseKind::PCreate ||
491               ClauseKind == OpenACCClauseKind::PresentOrCreate ||
492               ClauseKind == OpenACCClauseKind::Attach ||
493               ClauseKind == OpenACCClauseKind::Delete ||
494               ClauseKind == OpenACCClauseKind::UseDevice ||
495               ClauseKind == OpenACCClauseKind::Detach ||
496               ClauseKind == OpenACCClauseKind::DevicePtr ||
497               ClauseKind == OpenACCClauseKind::Reduction ||
498               ClauseKind == OpenACCClauseKind::Host ||
499               ClauseKind == OpenACCClauseKind::Device ||
500               ClauseKind == OpenACCClauseKind::DeviceResident ||
501               ClauseKind == OpenACCClauseKind::Link ||
502               (ClauseKind == OpenACCClauseKind::Self &&
503                DirKind == OpenACCDirectiveKind::Update) ||
504               ClauseKind == OpenACCClauseKind::FirstPrivate) &&
505              "Parsed clause kind does not have a var-list");
506 
507       if (ClauseKind == OpenACCClauseKind::Reduction)
508         return std::get<ReductionDetails>(Details).VarList;
509 
510       return std::get<VarListDetails>(Details).VarList;
511     }
512 
getVarList()513     ArrayRef<Expr *> getVarList() const {
514       return const_cast<OpenACCParsedClause *>(this)->getVarList();
515     }
516 
getModifierList()517     OpenACCModifierKind getModifierList() const {
518       return std::get<VarListDetails>(Details).ModifierKind;
519     }
520 
isForce()521     bool isForce() const {
522       assert(ClauseKind == OpenACCClauseKind::Collapse &&
523              "Only 'collapse' has a force tag");
524       return std::get<CollapseDetails>(Details).IsForce;
525     }
526 
getLoopCount()527     Expr *getLoopCount() const {
528       assert(ClauseKind == OpenACCClauseKind::Collapse &&
529              "Only 'collapse' has a loop count");
530       return std::get<CollapseDetails>(Details).LoopCount;
531     }
532 
getDeviceTypeArchitectures()533     ArrayRef<DeviceTypeArgument> getDeviceTypeArchitectures() const {
534       assert((ClauseKind == OpenACCClauseKind::DeviceType ||
535               ClauseKind == OpenACCClauseKind::DType) &&
536              "Only 'device_type'/'dtype' has a device-type-arg list");
537       return std::get<DeviceTypeDetails>(Details).Archs;
538     }
539 
540     std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
getBindDetails()541     getBindDetails() const {
542       assert(ClauseKind == OpenACCClauseKind::Bind &&
543              "Only 'bind' has bind details");
544       return std::get<BindDetails>(Details).Argument;
545     }
546 
setLParenLoc(SourceLocation EndLoc)547     void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
setEndLoc(SourceLocation EndLoc)548     void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }
549 
setDefaultDetails(OpenACCDefaultClauseKind DefKind)550     void setDefaultDetails(OpenACCDefaultClauseKind DefKind) {
551       assert(ClauseKind == OpenACCClauseKind::Default &&
552              "Parsed clause is not a default clause");
553       Details = DefaultDetails{DefKind};
554     }
555 
setConditionDetails(Expr * ConditionExpr)556     void setConditionDetails(Expr *ConditionExpr) {
557       assert((ClauseKind == OpenACCClauseKind::If ||
558               (ClauseKind == OpenACCClauseKind::Self &&
559                DirKind != OpenACCDirectiveKind::Update)) &&
560              "Parsed clause kind does not have a condition expr");
561       // In C++ we can count on this being a 'bool', but in C this gets left as
562       // some sort of scalar that codegen will have to take care of converting.
563       assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() ||
564               ConditionExpr->getType()->isScalarType()) &&
565              "Condition expression type not scalar/dependent");
566 
567       Details = ConditionDetails{ConditionExpr};
568     }
569 
setIntExprDetails(ArrayRef<Expr * > IntExprs)570     void setIntExprDetails(ArrayRef<Expr *> IntExprs) {
571       assert((ClauseKind == OpenACCClauseKind::NumGangs ||
572               ClauseKind == OpenACCClauseKind::NumWorkers ||
573               ClauseKind == OpenACCClauseKind::Async ||
574               ClauseKind == OpenACCClauseKind::DeviceNum ||
575               ClauseKind == OpenACCClauseKind::DefaultAsync ||
576               ClauseKind == OpenACCClauseKind::Tile ||
577               ClauseKind == OpenACCClauseKind::Worker ||
578               ClauseKind == OpenACCClauseKind::Vector ||
579               ClauseKind == OpenACCClauseKind::VectorLength) &&
580              "Parsed clause kind does not have a int exprs");
581       Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
582     }
setIntExprDetails(llvm::SmallVector<Expr * > && IntExprs)583     void setIntExprDetails(llvm::SmallVector<Expr *> &&IntExprs) {
584       assert((ClauseKind == OpenACCClauseKind::NumGangs ||
585               ClauseKind == OpenACCClauseKind::NumWorkers ||
586               ClauseKind == OpenACCClauseKind::Async ||
587               ClauseKind == OpenACCClauseKind::DeviceNum ||
588               ClauseKind == OpenACCClauseKind::DefaultAsync ||
589               ClauseKind == OpenACCClauseKind::Tile ||
590               ClauseKind == OpenACCClauseKind::Worker ||
591               ClauseKind == OpenACCClauseKind::Vector ||
592               ClauseKind == OpenACCClauseKind::VectorLength) &&
593              "Parsed clause kind does not have a int exprs");
594       Details = IntExprDetails{std::move(IntExprs)};
595     }
596 
setGangDetails(ArrayRef<OpenACCGangKind> GKs,ArrayRef<Expr * > IntExprs)597     void setGangDetails(ArrayRef<OpenACCGangKind> GKs,
598                         ArrayRef<Expr *> IntExprs) {
599       assert(ClauseKind == OpenACCClauseKind::Gang &&
600              "Parsed Clause kind does not have gang details");
601       assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?");
602 
603       Details = GangDetails{{GKs.begin(), GKs.end()},
604                             {IntExprs.begin(), IntExprs.end()}};
605     }
606 
setGangDetails(llvm::SmallVector<OpenACCGangKind> && GKs,llvm::SmallVector<Expr * > && IntExprs)607     void setGangDetails(llvm::SmallVector<OpenACCGangKind> &&GKs,
608                         llvm::SmallVector<Expr *> &&IntExprs) {
609       assert(ClauseKind == OpenACCClauseKind::Gang &&
610              "Parsed Clause kind does not have gang details");
611       assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?");
612 
613       Details = GangDetails{std::move(GKs), std::move(IntExprs)};
614     }
615 
setVarListDetails(ArrayRef<Expr * > VarList,OpenACCModifierKind ModKind)616     void setVarListDetails(ArrayRef<Expr *> VarList,
617                            OpenACCModifierKind ModKind) {
618       assert((ClauseKind == OpenACCClauseKind::Private ||
619               ClauseKind == OpenACCClauseKind::NoCreate ||
620               ClauseKind == OpenACCClauseKind::Present ||
621               ClauseKind == OpenACCClauseKind::Copy ||
622               ClauseKind == OpenACCClauseKind::PCopy ||
623               ClauseKind == OpenACCClauseKind::PresentOrCopy ||
624               ClauseKind == OpenACCClauseKind::CopyIn ||
625               ClauseKind == OpenACCClauseKind::PCopyIn ||
626               ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
627               ClauseKind == OpenACCClauseKind::CopyOut ||
628               ClauseKind == OpenACCClauseKind::PCopyOut ||
629               ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
630               ClauseKind == OpenACCClauseKind::Create ||
631               ClauseKind == OpenACCClauseKind::PCreate ||
632               ClauseKind == OpenACCClauseKind::PresentOrCreate ||
633               ClauseKind == OpenACCClauseKind::Attach ||
634               ClauseKind == OpenACCClauseKind::Delete ||
635               ClauseKind == OpenACCClauseKind::UseDevice ||
636               ClauseKind == OpenACCClauseKind::Detach ||
637               ClauseKind == OpenACCClauseKind::DevicePtr ||
638               ClauseKind == OpenACCClauseKind::Host ||
639               ClauseKind == OpenACCClauseKind::Device ||
640               ClauseKind == OpenACCClauseKind::DeviceResident ||
641               ClauseKind == OpenACCClauseKind::Link ||
642               (ClauseKind == OpenACCClauseKind::Self &&
643                DirKind == OpenACCDirectiveKind::Update) ||
644               ClauseKind == OpenACCClauseKind::FirstPrivate) &&
645              "Parsed clause kind does not have a var-list");
646       assert((ModKind == OpenACCModifierKind::Invalid ||
647               ClauseKind == OpenACCClauseKind::Copy ||
648               ClauseKind == OpenACCClauseKind::PCopy ||
649               ClauseKind == OpenACCClauseKind::PresentOrCopy ||
650               ClauseKind == OpenACCClauseKind::CopyIn ||
651               ClauseKind == OpenACCClauseKind::PCopyIn ||
652               ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
653               ClauseKind == OpenACCClauseKind::CopyOut ||
654               ClauseKind == OpenACCClauseKind::PCopyOut ||
655               ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
656               ClauseKind == OpenACCClauseKind::Create ||
657               ClauseKind == OpenACCClauseKind::PCreate ||
658               ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
659              "Modifier Kind only valid on copy, copyin, copyout, create");
660       Details = VarListDetails{{VarList.begin(), VarList.end()}, ModKind};
661     }
662 
setVarListDetails(llvm::SmallVector<Expr * > && VarList,OpenACCModifierKind ModKind)663     void setVarListDetails(llvm::SmallVector<Expr *> &&VarList,
664                            OpenACCModifierKind ModKind) {
665       assert((ClauseKind == OpenACCClauseKind::Private ||
666               ClauseKind == OpenACCClauseKind::NoCreate ||
667               ClauseKind == OpenACCClauseKind::Present ||
668               ClauseKind == OpenACCClauseKind::Copy ||
669               ClauseKind == OpenACCClauseKind::PCopy ||
670               ClauseKind == OpenACCClauseKind::PresentOrCopy ||
671               ClauseKind == OpenACCClauseKind::CopyIn ||
672               ClauseKind == OpenACCClauseKind::PCopyIn ||
673               ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
674               ClauseKind == OpenACCClauseKind::CopyOut ||
675               ClauseKind == OpenACCClauseKind::PCopyOut ||
676               ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
677               ClauseKind == OpenACCClauseKind::Create ||
678               ClauseKind == OpenACCClauseKind::PCreate ||
679               ClauseKind == OpenACCClauseKind::PresentOrCreate ||
680               ClauseKind == OpenACCClauseKind::Attach ||
681               ClauseKind == OpenACCClauseKind::Delete ||
682               ClauseKind == OpenACCClauseKind::UseDevice ||
683               ClauseKind == OpenACCClauseKind::Detach ||
684               ClauseKind == OpenACCClauseKind::DevicePtr ||
685               ClauseKind == OpenACCClauseKind::Host ||
686               ClauseKind == OpenACCClauseKind::Device ||
687               ClauseKind == OpenACCClauseKind::DeviceResident ||
688               ClauseKind == OpenACCClauseKind::Link ||
689               (ClauseKind == OpenACCClauseKind::Self &&
690                DirKind == OpenACCDirectiveKind::Update) ||
691               ClauseKind == OpenACCClauseKind::FirstPrivate) &&
692              "Parsed clause kind does not have a var-list");
693       assert((ModKind == OpenACCModifierKind::Invalid ||
694               ClauseKind == OpenACCClauseKind::Copy ||
695               ClauseKind == OpenACCClauseKind::PCopy ||
696               ClauseKind == OpenACCClauseKind::PresentOrCopy ||
697               ClauseKind == OpenACCClauseKind::CopyIn ||
698               ClauseKind == OpenACCClauseKind::PCopyIn ||
699               ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
700               ClauseKind == OpenACCClauseKind::CopyOut ||
701               ClauseKind == OpenACCClauseKind::PCopyOut ||
702               ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
703               ClauseKind == OpenACCClauseKind::Create ||
704               ClauseKind == OpenACCClauseKind::PCreate ||
705               ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
706              "Modifier Kind only valid on copy, copyin, copyout, create");
707       Details = VarListDetails{std::move(VarList), ModKind};
708     }
709 
setReductionDetails(OpenACCReductionOperator Op,llvm::SmallVector<Expr * > && VarList)710     void setReductionDetails(OpenACCReductionOperator Op,
711                              llvm::SmallVector<Expr *> &&VarList) {
712       assert(ClauseKind == OpenACCClauseKind::Reduction &&
713              "reduction details only valid on reduction");
714       Details = ReductionDetails{Op, std::move(VarList)};
715     }
716 
setWaitDetails(Expr * DevNum,SourceLocation QueuesLoc,llvm::SmallVector<Expr * > && IntExprs)717     void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc,
718                         llvm::SmallVector<Expr *> &&IntExprs) {
719       assert(ClauseKind == OpenACCClauseKind::Wait &&
720              "Parsed clause kind does not have a wait-details");
721       Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
722     }
723 
setDeviceTypeDetails(llvm::SmallVector<DeviceTypeArgument> && Archs)724     void setDeviceTypeDetails(llvm::SmallVector<DeviceTypeArgument> &&Archs) {
725       assert((ClauseKind == OpenACCClauseKind::DeviceType ||
726               ClauseKind == OpenACCClauseKind::DType) &&
727              "Only 'device_type'/'dtype' has a device-type-arg list");
728       Details = DeviceTypeDetails{std::move(Archs)};
729     }
730 
setCollapseDetails(bool IsForce,Expr * LoopCount)731     void setCollapseDetails(bool IsForce, Expr *LoopCount) {
732       assert(ClauseKind == OpenACCClauseKind::Collapse &&
733              "Only 'collapse' has collapse details");
734       Details = CollapseDetails{IsForce, LoopCount};
735     }
736 
setBindDetails(std::variant<std::monostate,clang::StringLiteral *,IdentifierInfo * > Arg)737     void setBindDetails(
738         std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
739             Arg) {
740       assert(ClauseKind == OpenACCClauseKind::Bind &&
741              "Only 'bind' has bind details");
742       Details = BindDetails{Arg};
743     }
744   };
745 
746   SemaOpenACC(Sema &S);
747 
748   // Called when we encounter a 'while' statement, before looking at its 'body'.
749   void ActOnWhileStmt(SourceLocation WhileLoc);
750   // Called when we encounter a 'do' statement, before looking at its 'body'.
751   void ActOnDoStmt(SourceLocation DoLoc);
752   // Called when we encounter a 'for' statement, before looking at its 'body',
753   // for the 'range-for'. 'ActOnForStmtEnd' is used after the body.
754   void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor,
755                               const Stmt *RangeFor);
756   void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *RangeFor);
757   // Called when we encounter a 'for' statement, before looking at its 'body'.
758   // 'ActOnForStmtEnd' is used after the body.
759   void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First,
760                          const Stmt *Second, const Stmt *Third);
761   void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst,
762                          const Stmt *First, const Stmt *OldSecond,
763                          const Stmt *Second, const Stmt *OldThird,
764                          const Stmt *Third);
765   // Called when we encounter a 'for' statement, after we've consumed/checked
766   // the body. This is necessary for a number of checks on the contents of the
767   // 'for' statement.
768   void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body);
769 
770   /// Called after parsing an OpenACC Clause so that it can be checked.
771   OpenACCClause *ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
772                              OpenACCParsedClause &Clause);
773 
774   /// Called after the construct has been parsed, but clauses haven't been
775   /// parsed.  This allows us to diagnose not-implemented, as well as set up any
776   /// state required for parsing the clauses.
777   void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc);
778 
779   /// Called after the directive, including its clauses, have been parsed and
780   /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
781   /// happen before any associated declarations or statements have been parsed.
782   /// This function is only called when we are parsing a 'statement' context.
783   bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
784                                ArrayRef<const OpenACCClause *> Clauses);
785 
786   /// Called after the directive, including its clauses, have been parsed and
787   /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
788   /// happen before any associated declarations or statements have been parsed.
789   /// This function is only called when we are parsing a 'Decl' context.
790   bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
791                                ArrayRef<const OpenACCClause *> Clauses);
792   /// Called when we encounter an associated statement for our construct, this
793   /// should check legality of the statement as it appertains to this Construct.
794   StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc,
795                                  OpenACCDirectiveKind K,
796                                  OpenACCAtomicKind AtKind,
797                                  ArrayRef<const OpenACCClause *> Clauses,
798                                  StmtResult AssocStmt);
799 
ActOnAssociatedStmt(SourceLocation DirectiveLoc,OpenACCDirectiveKind K,ArrayRef<const OpenACCClause * > Clauses,StmtResult AssocStmt)800   StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc,
801                                  OpenACCDirectiveKind K,
802                                  ArrayRef<const OpenACCClause *> Clauses,
803                                  StmtResult AssocStmt) {
804     return ActOnAssociatedStmt(DirectiveLoc, K, OpenACCAtomicKind::None,
805                                Clauses, AssocStmt);
806   }
807   /// Called to check the form of the `atomic` construct which has some fairly
808   /// sizable restrictions.
809   StmtResult CheckAtomicAssociatedStmt(SourceLocation AtomicDirLoc,
810                                        OpenACCAtomicKind AtKind,
811                                        StmtResult AssocStmt);
812 
813   /// Called after the directive has been completely parsed, including the
814   /// declaration group or associated statement.
815   /// DirLoc: Location of the actual directive keyword.
816   /// LParenLoc: Location of the left paren, if it exists (not on all
817   /// constructs).
818   /// MiscLoc: First misc location, if necessary (not all constructs).
819   /// Exprs: List of expressions on the construct itself, if necessary (not all
820   /// constructs).
821   /// FuncRef: used only for Routine, this is the function being referenced.
822   /// AK: The atomic kind of the directive, if necessary (atomic only)
823   /// RParenLoc: Location of the right paren, if it exists (not on all
824   /// constructs).
825   /// EndLoc: The last source location of the driective.
826   /// Clauses: The list of clauses for the directive, if present.
827   /// AssocStmt: The associated statement for this construct, if necessary.
828   StmtResult ActOnEndStmtDirective(
829       OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc,
830       SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
831       OpenACCAtomicKind AK, SourceLocation RParenLoc, SourceLocation EndLoc,
832       ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt);
833 
834   /// Called after the directive has been completely parsed, including the
835   /// declaration group or associated statement.
836   DeclGroupRef
837   ActOnEndDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
838                         SourceLocation DirLoc, SourceLocation LParenLoc,
839                         SourceLocation RParenLoc, SourceLocation EndLoc,
840                         ArrayRef<OpenACCClause *> Clauses);
841 
842   // Helper functions for ActOnEndRoutine*Directive, which does all the checking
843   // given the proper list of declarations.
844   void CheckRoutineDecl(SourceLocation DirLoc,
845                         ArrayRef<const OpenACCClause *> Clauses,
846                         Decl *NextParsedDecl);
847   OpenACCRoutineDecl *CheckRoutineDecl(SourceLocation StartLoc,
848                                        SourceLocation DirLoc,
849                                        SourceLocation LParenLoc, Expr *FuncRef,
850                                        SourceLocation RParenLoc,
851                                        ArrayRef<const OpenACCClause *> Clauses,
852                                        SourceLocation EndLoc);
853   OpenACCRoutineDeclAttr *
854   mergeRoutineDeclAttr(const OpenACCRoutineDeclAttr &Old);
855   DeclGroupRef
856   ActOnEndRoutineDeclDirective(SourceLocation StartLoc, SourceLocation DirLoc,
857                                SourceLocation LParenLoc, Expr *ReferencedFunc,
858                                SourceLocation RParenLoc,
859                                ArrayRef<const OpenACCClause *> Clauses,
860                                SourceLocation EndLoc, DeclGroupPtrTy NextDecl);
861   StmtResult
862   ActOnEndRoutineStmtDirective(SourceLocation StartLoc, SourceLocation DirLoc,
863                                SourceLocation LParenLoc, Expr *ReferencedFunc,
864                                SourceLocation RParenLoc,
865                                ArrayRef<const OpenACCClause *> Clauses,
866                                SourceLocation EndLoc, Stmt *NextStmt);
867 
868   /// Called when encountering an 'int-expr' for OpenACC, and manages
869   /// conversions and diagnostics to 'int'.
870   ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
871                           SourceLocation Loc, Expr *IntExpr);
872 
873   /// Called right before a 'var' is parsed, so we can set the state for parsing
874   /// a 'cache' var.
875   void ActOnStartParseVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK);
876   /// Called only if the parse of a 'var' was invalid, else 'ActOnVar' should be
877   /// called.
878   void ActOnInvalidParseVar();
879   /// Called when encountering a 'var' for OpenACC, ensures it is actually a
880   /// declaration reference to a variable of the correct type.
881   ExprResult ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
882                       Expr *VarExpr);
883   /// Helper function called by ActonVar that is used to check a 'cache' var.
884   ExprResult ActOnCacheVar(Expr *VarExpr);
885   /// Function called when a variable declarator is created, which lets us
886   /// implement the 'routine' 'function static variables' restriction.
887   void ActOnVariableDeclarator(VarDecl *VD);
888   /// Called when a function decl is created, which lets us implement the
889   /// 'routine' 'doesn't match next thing' warning.
890   void ActOnFunctionDeclarator(FunctionDecl *FD);
891   /// Called when a variable is initialized, so we can implement the 'routine
892   /// 'doesn't match the next thing' warning for lambda init.
893   void ActOnVariableInit(VarDecl *VD, QualType InitType);
894 
895   // Called after 'ActOnVar' specifically for a 'link' clause, which has to do
896   // some minor additional checks.
897   llvm::SmallVector<Expr *> CheckLinkClauseVarList(ArrayRef<Expr *> VarExpr);
898 
899   // Checking for the arguments specific to the declare-clause that need to be
900   // checked during both phases of template translation.
901   bool CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause,
902                           OpenACCModifierKind Mods);
903 
904   ExprResult ActOnRoutineName(Expr *RoutineName);
905 
906   /// Called while semantically analyzing the reduction clause, ensuring the var
907   /// is the correct kind of reference.
908   ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
909                                OpenACCReductionOperator ReductionOp,
910                                Expr *VarExpr);
911 
912   /// Called to check the 'var' type is a variable of pointer type, necessary
913   /// for 'deviceptr' and 'attach' clauses. Returns true on success.
914   bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr);
915 
916   /// Checks and creates an Array Section used in an OpenACC construct/clause.
917   ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
918                                    Expr *LowerBound,
919                                    SourceLocation ColonLocFirst, Expr *Length,
920                                    SourceLocation RBLoc);
921   /// Checks the loop depth value for a collapse clause.
922   ExprResult CheckCollapseLoopCount(Expr *LoopCount);
923   /// Checks a single size expr for a tile clause.
924   ExprResult CheckTileSizeExpr(Expr *SizeExpr);
925 
926   // Check a single expression on a gang clause.
927   ExprResult CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses,
928                            OpenACCDirectiveKind DK, OpenACCGangKind GK,
929                            Expr *E);
930 
931   // Called when a declaration is referenced, so that we can make sure certain
932   // clauses don't do the 'wrong' thing/have incorrect references.
933   void CheckDeclReference(SourceLocation Loc, Expr *E, Decl *D);
934 
935   // Does the checking for a 'gang' clause that needs to be done in dependent
936   // and not dependent cases.
937   OpenACCClause *
938   CheckGangClause(OpenACCDirectiveKind DirKind,
939                   ArrayRef<const OpenACCClause *> ExistingClauses,
940                   SourceLocation BeginLoc, SourceLocation LParenLoc,
941                   ArrayRef<OpenACCGangKind> GangKinds,
942                   ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
943   // Does the checking for a 'reduction ' clause that needs to be done in
944   // dependent and not dependent cases.
945   OpenACCClause *
946   CheckReductionClause(ArrayRef<const OpenACCClause *> ExistingClauses,
947                        OpenACCDirectiveKind DirectiveKind,
948                        SourceLocation BeginLoc, SourceLocation LParenLoc,
949                        OpenACCReductionOperator ReductionOp,
950                        ArrayRef<Expr *> Vars, SourceLocation EndLoc);
951 
952   ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc);
953   ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc);
954 
955   /// Helper type to restore the state of various 'loop' constructs when we run
956   /// into a loop (for, etc) inside the construct.
957   class LoopInConstructRAII {
958     SemaOpenACC &SemaRef;
959     LoopCheckingInfo OldLoopInfo;
960     CollapseCheckingInfo OldCollapseInfo;
961     TileCheckingInfo OldTileInfo;
962     bool PreserveDepth;
963 
964   public:
965     LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth = true)
SemaRef(SemaRef)966         : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
967           OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
968           PreserveDepth(PreserveDepth) {}
~LoopInConstructRAII()969     ~LoopInConstructRAII() {
970       // The associated-statement level of this should NOT preserve this, as it
971       // is a new construct, but other loop uses need to preserve the depth so
972       // it makes it to the 'top level' for diagnostics.
973       bool CollapseDepthSatisified =
974           PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
975                         : OldCollapseInfo.CollapseDepthSatisfied;
976       bool TileDepthSatisfied = PreserveDepth
977                                     ? SemaRef.TileInfo.TileDepthSatisfied
978                                     : OldTileInfo.TileDepthSatisfied;
979       bool CurLevelHasLoopAlready =
980           PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
981                         : OldLoopInfo.CurLevelHasLoopAlready;
982 
983       SemaRef.LoopInfo = OldLoopInfo;
984       SemaRef.CollapseInfo = OldCollapseInfo;
985       SemaRef.TileInfo = OldTileInfo;
986 
987       SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
988       SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
989       SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
990     }
991   };
992 
993   /// Helper type for the registration/assignment of constructs that need to
994   /// 'know' about their parent constructs and hold a reference to them, such as
995   /// Loop needing its parent construct.
996   class AssociatedStmtRAII {
997     SemaOpenACC &SemaRef;
998     ComputeConstructInfo OldActiveComputeConstructInfo;
999     OpenACCDirectiveKind DirKind;
1000     LoopGangOnKernelTy OldLoopGangClauseOnKernel;
1001     SourceLocation OldLoopWorkerClauseLoc;
1002     SourceLocation OldLoopVectorClauseLoc;
1003     LoopWithoutSeqCheckingInfo OldLoopWithoutSeqInfo;
1004     llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
1005     LoopInConstructRAII LoopRAII;
1006 
1007   public:
1008     AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind, SourceLocation,
1009                        ArrayRef<const OpenACCClause *>,
1010                        ArrayRef<OpenACCClause *>);
1011     void SetCollapseInfoBeforeAssociatedStmt(
1012         ArrayRef<const OpenACCClause *> UnInstClauses,
1013         ArrayRef<OpenACCClause *> Clauses);
1014     void SetTileInfoBeforeAssociatedStmt(
1015         ArrayRef<const OpenACCClause *> UnInstClauses,
1016         ArrayRef<OpenACCClause *> Clauses);
1017     ~AssociatedStmtRAII();
1018   };
1019 };
1020 
1021 } // namespace clang
1022 
1023 #endif // LLVM_CLANG_SEMA_SEMAOPENACC_H
1024