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