clang 20.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"
19#include "clang/Basic/LLVM.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
31namespace clang {
32class IdentifierInfo;
33class OpenACCClause;
34
35class SemaOpenACC : public SemaBase {
36private:
37 struct ComputeConstructInfo {
38 /// Which type of compute construct we are inside of, which we can use to
39 /// determine whether we should add loops to the above collection. We can
40 /// also use it to diagnose loop construct clauses.
42 // If we have an active compute construct, stores the list of clauses we've
43 // prepared for it, so that we can diagnose limitations on child constructs.
45 } ActiveComputeConstructInfo;
46
47 bool isInComputeConstruct() const {
48 return ActiveComputeConstructInfo.Kind != OpenACCDirectiveKind::Invalid;
49 }
50
51 /// Certain clauses care about the same things that aren't specific to the
52 /// individual clause, but can be shared by a few, so store them here. All
53 /// require a 'no intervening constructs' rule, so we know they are all from
54 /// the same 'place'.
55 struct LoopCheckingInfo {
56 /// Records whether we've seen the top level 'for'. We already diagnose
57 /// later that the 'top level' is a for loop, so we use this to suppress the
58 /// 'collapse inner loop not a 'for' loop' diagnostic.
59 LLVM_PREFERRED_TYPE(bool)
60 unsigned TopLevelLoopSeen : 1;
61
62 /// Records whether this 'tier' of the loop has already seen a 'for' loop,
63 /// used to diagnose if there are multiple 'for' loops at any one level.
64 LLVM_PREFERRED_TYPE(bool)
65 unsigned CurLevelHasLoopAlready : 1;
66
67 } LoopInfo{/*TopLevelLoopSeen=*/false, /*CurLevelHasLoopAlready=*/false};
68
69 /// The 'collapse' clause requires quite a bit of checking while
70 /// parsing/instantiating its body, so this structure/object keeps all of the
71 /// necessary information as we do checking. This should rarely be directly
72 /// modified, and typically should be controlled by the RAII objects.
73 ///
74 /// Collapse has an 'N' count that makes it apply to a number of loops 'below'
75 /// it.
76 struct CollapseCheckingInfo {
77 OpenACCCollapseClause *ActiveCollapse = nullptr;
78
79 /// This is a value that maintains the current value of the 'N' on the
80 /// current collapse, minus the depth that has already been traversed. When
81 /// there is not an active collapse, or a collapse whose depth we don't know
82 /// (for example, if it is a dependent value), this should be `nullopt`,
83 /// else it should be 'N' minus the current depth traversed.
84 std::optional<llvm::APSInt> CurCollapseCount;
85
86 /// Records whether we've hit a CurCollapseCount of '0' on the way down,
87 /// which allows us to diagnose if the value of 'N' is too large for the
88 /// current number of 'for' loops.
89 bool CollapseDepthSatisfied = true;
90
91 /// Records the kind of the directive that this clause is attached to, which
92 /// allows us to use it in diagnostics.
94 } CollapseInfo;
95
96 /// The 'tile' clause requires a bit of additional checking as well, so like
97 /// the `CollapseCheckingInfo`, ensure we maintain information here too.
98 struct TileCheckingInfo {
99 OpenACCTileClause *ActiveTile = nullptr;
100
101 /// This is the number of expressions on a 'tile' clause. This doesn't have
102 /// to be an APSInt because it isn't the result of a constexpr, just by our
103 /// own counting of elements.
104 std::optional<unsigned> CurTileCount;
105
106 /// Records whether we've hit a 'CurTileCount' of '0' on the wya down,
107 /// which allows us to diagnose if the number of arguments is too large for
108 /// the current number of 'for' loops.
109 bool TileDepthSatisfied = true;
110
111 /// Records the kind of the directive that this clause is attached to, which
112 /// allows us to use it in diagnostics.
114 } TileInfo;
115
116 /// A list of the active reduction clauses, which allows us to check that all
117 /// vars on nested constructs for the same reduction var have the same
118 /// reduction operator. Currently this is enforced against all constructs
119 /// despite the rule being in the 'loop' section. By current reading, this
120 /// should apply to all anyway, but we may need to make this more like the
121 /// 'loop' clause enforcement, where this is 'blocked' by a compute construct.
122 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
123
124 // Type to check the info about the 'for stmt'.
125 struct ForStmtBeginChecker {
126 SemaOpenACC &SemaRef;
127 SourceLocation ForLoc;
128 bool IsRangeFor = false;
129 std::optional<const CXXForRangeStmt *> RangeFor = nullptr;
130 const Stmt *Init = nullptr;
131 bool InitChanged = false;
132 std::optional<const Stmt *> Cond = nullptr;
133 std::optional<const Stmt *> Inc = nullptr;
134 // Prevent us from checking 2x, which can happen with collapse & tile.
135 bool AlreadyChecked = false;
136
137 ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
138 std::optional<const CXXForRangeStmt *> S)
139 : SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(true), RangeFor(S) {}
140
141 ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
142 const Stmt *I, bool InitChanged,
143 std::optional<const Stmt *> C,
144 std::optional<const Stmt *> Inc)
145 : SemaRef(SemaRef), ForLoc(ForLoc), IsRangeFor(false), Init(I),
146 InitChanged(InitChanged), Cond(C), Inc(Inc) {}
147 // Do the checking for the For/Range-For. Currently this implements the 'not
148 // seq' restrictions only, and should be called either if we know we are a
149 // top-level 'for' (the one associated via associated-stmt), or extended via
150 // 'collapse'.
151 void check();
152
153 const ValueDecl *checkInit();
154 void checkCond();
155 void checkInc(const ValueDecl *Init);
156 };
157
158 /// Helper function for checking the 'for' and 'range for' stmts.
159 void ForStmtBeginHelper(SourceLocation ForLoc, ForStmtBeginChecker &C);
160
161public:
162 ComputeConstructInfo &getActiveComputeConstructInfo() {
163 return ActiveComputeConstructInfo;
164 }
165
166 /// If there is a current 'active' loop construct with a 'gang' clause on a
167 /// 'kernel' construct, this will have the source location for it, and the
168 /// 'kernel kind'. This permits us to implement the restriction of no further
169 /// 'gang' clauses.
174
175 /// If there is a current 'active' loop construct with a 'worker' clause on it
176 /// (on any sort of construct), this has the source location for it. This
177 /// permits us to implement the restriction of no further 'gang' or 'worker'
178 /// clauses.
180 /// If there is a current 'active' loop construct with a 'vector' clause on it
181 /// (on any sort of construct), this has the source location for it. This
182 /// permits us to implement the restriction of no further 'gang', 'vector', or
183 /// 'worker' clauses.
185 /// If there is a current 'active' loop construct that does NOT have a 'seq'
186 /// clause on it, this has that source location and loop Directive 'kind'.
187 /// This permits us to implement the 'loop' restrictions on the loop variable.
188 /// This can be extended via 'collapse', so we need to keep this around for a
189 /// while.
194
195 // Redeclaration of the version in OpenACCClause.h.
196 using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
197
198 /// A type to represent all the data for an OpenACC Clause that has been
199 /// parsed, but not yet created/semantically analyzed. This is effectively a
200 /// discriminated union on the 'Clause Kind', with all of the individual
201 /// clause details stored in a std::variant.
203 OpenACCDirectiveKind DirKind;
204 OpenACCClauseKind ClauseKind;
205 SourceRange ClauseRange;
206 SourceLocation LParenLoc;
207
208 struct DefaultDetails {
209 OpenACCDefaultClauseKind DefaultClauseKind;
210 };
211
212 struct ConditionDetails {
213 Expr *ConditionExpr;
214 };
215
216 struct IntExprDetails {
217 SmallVector<Expr *> IntExprs;
218 };
219
220 struct VarListDetails {
221 SmallVector<Expr *> VarList;
222 bool IsReadOnly;
223 bool IsZero;
224 };
225
226 struct WaitDetails {
227 Expr *DevNumExpr;
228 SourceLocation QueuesLoc;
229 SmallVector<Expr *> QueueIdExprs;
230 };
231
232 struct DeviceTypeDetails {
234 };
235 struct ReductionDetails {
237 SmallVector<Expr *> VarList;
238 };
239
240 struct CollapseDetails {
241 bool IsForce;
242 Expr *LoopCount;
243 };
244
245 struct GangDetails {
247 SmallVector<Expr *> IntExprs;
248 };
249
250 std::variant<std::monostate, DefaultDetails, ConditionDetails,
251 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
252 ReductionDetails, CollapseDetails, GangDetails>
253 Details = std::monostate{};
254
255 public:
257 OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
258 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
259
260 OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }
261
262 OpenACCClauseKind getClauseKind() const { return ClauseKind; }
263
264 SourceLocation getBeginLoc() const { return ClauseRange.getBegin(); }
265
266 SourceLocation getLParenLoc() const { return LParenLoc; }
267
268 SourceLocation getEndLoc() const { return ClauseRange.getEnd(); }
269
271 assert(ClauseKind == OpenACCClauseKind::Default &&
272 "Parsed clause is not a default clause");
273 return std::get<DefaultDetails>(Details).DefaultClauseKind;
274 }
275
276 const Expr *getConditionExpr() const {
277 return const_cast<OpenACCParsedClause *>(this)->getConditionExpr();
278 }
279
281 assert((ClauseKind == OpenACCClauseKind::If ||
282 (ClauseKind == OpenACCClauseKind::Self &&
283 DirKind != OpenACCDirectiveKind::Update)) &&
284 "Parsed clause kind does not have a condition expr");
285
286 // 'self' has an optional ConditionExpr, so be tolerant of that. This will
287 // assert in variant otherwise.
288 if (ClauseKind == OpenACCClauseKind::Self &&
289 std::holds_alternative<std::monostate>(Details))
290 return nullptr;
291
292 return std::get<ConditionDetails>(Details).ConditionExpr;
293 }
294
295 unsigned getNumIntExprs() const {
296 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
297 ClauseKind == OpenACCClauseKind::NumWorkers ||
298 ClauseKind == OpenACCClauseKind::Async ||
299 ClauseKind == OpenACCClauseKind::DeviceNum ||
300 ClauseKind == OpenACCClauseKind::DefaultAsync ||
301 ClauseKind == OpenACCClauseKind::Tile ||
302 ClauseKind == OpenACCClauseKind::Worker ||
303 ClauseKind == OpenACCClauseKind::Vector ||
304 ClauseKind == OpenACCClauseKind::VectorLength) &&
305 "Parsed clause kind does not have a int exprs");
306
307 // 'async', 'worker', 'vector', and 'wait' have an optional IntExpr, so be
308 // tolerant of that.
309 if ((ClauseKind == OpenACCClauseKind::Async ||
310 ClauseKind == OpenACCClauseKind::Worker ||
311 ClauseKind == OpenACCClauseKind::Vector ||
312 ClauseKind == OpenACCClauseKind::Wait) &&
313 std::holds_alternative<std::monostate>(Details))
314 return 0;
315 return std::get<IntExprDetails>(Details).IntExprs.size();
316 }
317
319 assert(ClauseKind == OpenACCClauseKind::Wait &&
320 "Parsed clause kind does not have a queues location");
321
322 if (std::holds_alternative<std::monostate>(Details))
323 return SourceLocation{};
324
325 return std::get<WaitDetails>(Details).QueuesLoc;
326 }
327
329 assert(ClauseKind == OpenACCClauseKind::Wait &&
330 "Parsed clause kind does not have a device number expr");
331
332 if (std::holds_alternative<std::monostate>(Details))
333 return nullptr;
334
335 return std::get<WaitDetails>(Details).DevNumExpr;
336 }
337
339 assert(ClauseKind == OpenACCClauseKind::Wait &&
340 "Parsed clause kind does not have a queue id expr list");
341
342 if (std::holds_alternative<std::monostate>(Details))
343 return ArrayRef<Expr *>();
344
345 return std::get<WaitDetails>(Details).QueueIdExprs;
346 }
347
349 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
350 ClauseKind == OpenACCClauseKind::NumWorkers ||
351 ClauseKind == OpenACCClauseKind::Async ||
352 ClauseKind == OpenACCClauseKind::DeviceNum ||
353 ClauseKind == OpenACCClauseKind::DefaultAsync ||
354 ClauseKind == OpenACCClauseKind::Tile ||
355 ClauseKind == OpenACCClauseKind::Gang ||
356 ClauseKind == OpenACCClauseKind::Worker ||
357 ClauseKind == OpenACCClauseKind::Vector ||
358 ClauseKind == OpenACCClauseKind::VectorLength) &&
359 "Parsed clause kind does not have a int exprs");
360
361 if (ClauseKind == OpenACCClauseKind::Gang) {
362 // There might not be any gang int exprs, as this is an optional
363 // argument.
364 if (std::holds_alternative<std::monostate>(Details))
365 return {};
366 return std::get<GangDetails>(Details).IntExprs;
367 }
368
369 return std::get<IntExprDetails>(Details).IntExprs;
370 }
371
373 return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
374 }
375
377 return std::get<ReductionDetails>(Details).Op;
378 }
379
381 assert(ClauseKind == OpenACCClauseKind::Gang &&
382 "Parsed clause kind does not have gang kind");
383 // The args on gang are optional, so this might not actually hold
384 // anything.
385 if (std::holds_alternative<std::monostate>(Details))
386 return {};
387 return std::get<GangDetails>(Details).GangKinds;
388 }
389
391 assert((ClauseKind == OpenACCClauseKind::Private ||
392 ClauseKind == OpenACCClauseKind::NoCreate ||
393 ClauseKind == OpenACCClauseKind::Present ||
394 ClauseKind == OpenACCClauseKind::Copy ||
395 ClauseKind == OpenACCClauseKind::PCopy ||
396 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
397 ClauseKind == OpenACCClauseKind::CopyIn ||
398 ClauseKind == OpenACCClauseKind::PCopyIn ||
400 ClauseKind == OpenACCClauseKind::CopyOut ||
401 ClauseKind == OpenACCClauseKind::PCopyOut ||
403 ClauseKind == OpenACCClauseKind::Create ||
404 ClauseKind == OpenACCClauseKind::PCreate ||
406 ClauseKind == OpenACCClauseKind::Attach ||
407 ClauseKind == OpenACCClauseKind::Delete ||
408 ClauseKind == OpenACCClauseKind::UseDevice ||
409 ClauseKind == OpenACCClauseKind::Detach ||
410 ClauseKind == OpenACCClauseKind::DevicePtr ||
411 ClauseKind == OpenACCClauseKind::Reduction ||
412 ClauseKind == OpenACCClauseKind::Host ||
413 ClauseKind == OpenACCClauseKind::Device ||
414 (ClauseKind == OpenACCClauseKind::Self &&
415 DirKind == OpenACCDirectiveKind::Update) ||
416 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
417 "Parsed clause kind does not have a var-list");
418
419 if (ClauseKind == OpenACCClauseKind::Reduction)
420 return std::get<ReductionDetails>(Details).VarList;
421
422 return std::get<VarListDetails>(Details).VarList;
423 }
424
426 return const_cast<OpenACCParsedClause *>(this)->getVarList();
427 }
428
429 bool isReadOnly() const {
430 assert((ClauseKind == OpenACCClauseKind::CopyIn ||
431 ClauseKind == OpenACCClauseKind::PCopyIn ||
432 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
433 "Only copyin accepts 'readonly:' tag");
434 return std::get<VarListDetails>(Details).IsReadOnly;
435 }
436
437 bool isZero() const {
438 assert((ClauseKind == OpenACCClauseKind::CopyOut ||
439 ClauseKind == OpenACCClauseKind::PCopyOut ||
441 ClauseKind == OpenACCClauseKind::Create ||
442 ClauseKind == OpenACCClauseKind::PCreate ||
443 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
444 "Only copyout/create accepts 'zero' tag");
445 return std::get<VarListDetails>(Details).IsZero;
446 }
447
448 bool isForce() const {
449 assert(ClauseKind == OpenACCClauseKind::Collapse &&
450 "Only 'collapse' has a force tag");
451 return std::get<CollapseDetails>(Details).IsForce;
452 }
453
455 assert(ClauseKind == OpenACCClauseKind::Collapse &&
456 "Only 'collapse' has a loop count");
457 return std::get<CollapseDetails>(Details).LoopCount;
458 }
459
461 assert((ClauseKind == OpenACCClauseKind::DeviceType ||
462 ClauseKind == OpenACCClauseKind::DType) &&
463 "Only 'device_type'/'dtype' has a device-type-arg list");
464 return std::get<DeviceTypeDetails>(Details).Archs;
465 }
466
467 void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
468 void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }
469
471 assert(ClauseKind == OpenACCClauseKind::Default &&
472 "Parsed clause is not a default clause");
473 Details = DefaultDetails{DefKind};
474 }
475
476 void setConditionDetails(Expr *ConditionExpr) {
477 assert((ClauseKind == OpenACCClauseKind::If ||
478 (ClauseKind == OpenACCClauseKind::Self &&
479 DirKind != OpenACCDirectiveKind::Update)) &&
480 "Parsed clause kind does not have a condition expr");
481 // In C++ we can count on this being a 'bool', but in C this gets left as
482 // some sort of scalar that codegen will have to take care of converting.
483 assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() ||
484 ConditionExpr->getType()->isScalarType()) &&
485 "Condition expression type not scalar/dependent");
486
487 Details = ConditionDetails{ConditionExpr};
488 }
489
491 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
492 ClauseKind == OpenACCClauseKind::NumWorkers ||
493 ClauseKind == OpenACCClauseKind::Async ||
494 ClauseKind == OpenACCClauseKind::DeviceNum ||
495 ClauseKind == OpenACCClauseKind::DefaultAsync ||
496 ClauseKind == OpenACCClauseKind::Tile ||
497 ClauseKind == OpenACCClauseKind::Worker ||
498 ClauseKind == OpenACCClauseKind::Vector ||
499 ClauseKind == OpenACCClauseKind::VectorLength) &&
500 "Parsed clause kind does not have a int exprs");
501 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
502 }
504 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
505 ClauseKind == OpenACCClauseKind::NumWorkers ||
506 ClauseKind == OpenACCClauseKind::Async ||
507 ClauseKind == OpenACCClauseKind::DeviceNum ||
508 ClauseKind == OpenACCClauseKind::DefaultAsync ||
509 ClauseKind == OpenACCClauseKind::Tile ||
510 ClauseKind == OpenACCClauseKind::Worker ||
511 ClauseKind == OpenACCClauseKind::Vector ||
512 ClauseKind == OpenACCClauseKind::VectorLength) &&
513 "Parsed clause kind does not have a int exprs");
514 Details = IntExprDetails{std::move(IntExprs)};
515 }
516
518 ArrayRef<Expr *> IntExprs) {
519 assert(ClauseKind == OpenACCClauseKind::Gang &&
520 "Parsed Clause kind does not have gang details");
521 assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?");
522
523 Details = GangDetails{{GKs.begin(), GKs.end()},
524 {IntExprs.begin(), IntExprs.end()}};
525 }
526
528 llvm::SmallVector<Expr *> &&IntExprs) {
529 assert(ClauseKind == OpenACCClauseKind::Gang &&
530 "Parsed Clause kind does not have gang details");
531 assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?");
532
533 Details = GangDetails{std::move(GKs), std::move(IntExprs)};
534 }
535
536 void setVarListDetails(ArrayRef<Expr *> VarList, bool IsReadOnly,
537 bool IsZero) {
538 assert((ClauseKind == OpenACCClauseKind::Private ||
539 ClauseKind == OpenACCClauseKind::NoCreate ||
540 ClauseKind == OpenACCClauseKind::Present ||
541 ClauseKind == OpenACCClauseKind::Copy ||
542 ClauseKind == OpenACCClauseKind::PCopy ||
543 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
544 ClauseKind == OpenACCClauseKind::CopyIn ||
545 ClauseKind == OpenACCClauseKind::PCopyIn ||
547 ClauseKind == OpenACCClauseKind::CopyOut ||
548 ClauseKind == OpenACCClauseKind::PCopyOut ||
550 ClauseKind == OpenACCClauseKind::Create ||
551 ClauseKind == OpenACCClauseKind::PCreate ||
553 ClauseKind == OpenACCClauseKind::Attach ||
554 ClauseKind == OpenACCClauseKind::Delete ||
555 ClauseKind == OpenACCClauseKind::UseDevice ||
556 ClauseKind == OpenACCClauseKind::Detach ||
557 ClauseKind == OpenACCClauseKind::DevicePtr ||
558 ClauseKind == OpenACCClauseKind::Host ||
559 ClauseKind == OpenACCClauseKind::Device ||
560 (ClauseKind == OpenACCClauseKind::Self &&
561 DirKind == OpenACCDirectiveKind::Update) ||
562 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
563 "Parsed clause kind does not have a var-list");
564 assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
565 ClauseKind == OpenACCClauseKind::PCopyIn ||
566 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
567 "readonly: tag only valid on copyin");
568 assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
569 ClauseKind == OpenACCClauseKind::PCopyOut ||
571 ClauseKind == OpenACCClauseKind::Create ||
572 ClauseKind == OpenACCClauseKind::PCreate ||
573 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
574 "zero: tag only valid on copyout/create");
575 Details =
576 VarListDetails{{VarList.begin(), VarList.end()}, IsReadOnly, IsZero};
577 }
578
579 void setVarListDetails(llvm::SmallVector<Expr *> &&VarList, bool IsReadOnly,
580 bool IsZero) {
581 assert((ClauseKind == OpenACCClauseKind::Private ||
582 ClauseKind == OpenACCClauseKind::NoCreate ||
583 ClauseKind == OpenACCClauseKind::Present ||
584 ClauseKind == OpenACCClauseKind::Copy ||
585 ClauseKind == OpenACCClauseKind::PCopy ||
586 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
587 ClauseKind == OpenACCClauseKind::CopyIn ||
588 ClauseKind == OpenACCClauseKind::PCopyIn ||
590 ClauseKind == OpenACCClauseKind::CopyOut ||
591 ClauseKind == OpenACCClauseKind::PCopyOut ||
593 ClauseKind == OpenACCClauseKind::Create ||
594 ClauseKind == OpenACCClauseKind::PCreate ||
596 ClauseKind == OpenACCClauseKind::Attach ||
597 ClauseKind == OpenACCClauseKind::Delete ||
598 ClauseKind == OpenACCClauseKind::UseDevice ||
599 ClauseKind == OpenACCClauseKind::Detach ||
600 ClauseKind == OpenACCClauseKind::DevicePtr ||
601 ClauseKind == OpenACCClauseKind::Host ||
602 ClauseKind == OpenACCClauseKind::Device ||
603 (ClauseKind == OpenACCClauseKind::Self &&
604 DirKind == OpenACCDirectiveKind::Update) ||
605 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
606 "Parsed clause kind does not have a var-list");
607 assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
608 ClauseKind == OpenACCClauseKind::PCopyIn ||
609 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
610 "readonly: tag only valid on copyin");
611 assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
612 ClauseKind == OpenACCClauseKind::PCopyOut ||
614 ClauseKind == OpenACCClauseKind::Create ||
615 ClauseKind == OpenACCClauseKind::PCreate ||
616 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
617 "zero: tag only valid on copyout/create");
618 Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero};
619 }
620
622 llvm::SmallVector<Expr *> &&VarList) {
623 assert(ClauseKind == OpenACCClauseKind::Reduction &&
624 "reduction details only valid on reduction");
625 Details = ReductionDetails{Op, std::move(VarList)};
626 }
627
628 void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc,
629 llvm::SmallVector<Expr *> &&IntExprs) {
630 assert(ClauseKind == OpenACCClauseKind::Wait &&
631 "Parsed clause kind does not have a wait-details");
632 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
633 }
634
636 assert((ClauseKind == OpenACCClauseKind::DeviceType ||
637 ClauseKind == OpenACCClauseKind::DType) &&
638 "Only 'device_type'/'dtype' has a device-type-arg list");
639 Details = DeviceTypeDetails{std::move(Archs)};
640 }
641
642 void setCollapseDetails(bool IsForce, Expr *LoopCount) {
643 assert(ClauseKind == OpenACCClauseKind::Collapse &&
644 "Only 'collapse' has collapse details");
645 Details = CollapseDetails{IsForce, LoopCount};
646 }
647 };
648
649 SemaOpenACC(Sema &S);
650
651 // Called when we encounter a 'while' statement, before looking at its 'body'.
652 void ActOnWhileStmt(SourceLocation WhileLoc);
653 // Called when we encounter a 'do' statement, before looking at its 'body'.
654 void ActOnDoStmt(SourceLocation DoLoc);
655 // Called when we encounter a 'for' statement, before looking at its 'body',
656 // for the 'range-for'. 'ActOnForStmtEnd' is used after the body.
657 void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor,
658 const Stmt *RangeFor);
659 void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *RangeFor);
660 // Called when we encounter a 'for' statement, before looking at its 'body'.
661 // 'ActOnForStmtEnd' is used after the body.
662 void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First,
663 const Stmt *Second, const Stmt *Third);
664 void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst,
665 const Stmt *First, const Stmt *OldSecond,
666 const Stmt *Second, const Stmt *OldThird,
667 const Stmt *Third);
668 // Called when we encounter a 'for' statement, after we've consumed/checked
669 // the body. This is necessary for a number of checks on the contents of the
670 // 'for' statement.
671 void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body);
672
673 /// Called after parsing an OpenACC Clause so that it can be checked.
675 OpenACCParsedClause &Clause);
676
677 /// Called after the construct has been parsed, but clauses haven't been
678 /// parsed. This allows us to diagnose not-implemented, as well as set up any
679 /// state required for parsing the clauses.
681
682 /// Called after the directive, including its clauses, have been parsed and
683 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
684 /// happen before any associated declarations or statements have been parsed.
685 /// This function is only called when we are parsing a 'statement' context.
688
689 /// Called after the directive, including its clauses, have been parsed and
690 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
691 /// happen before any associated declarations or statements have been parsed.
692 /// This function is only called when we are parsing a 'Decl' context.
694 /// Called when we encounter an associated statement for our construct, this
695 /// should check legality of the statement as it appertains to this Construct.
699 StmtResult AssocStmt);
700
701 /// Called after the directive has been completely parsed, including the
702 /// declaration group or associated statement.
703 /// LParenLoc: Location of the left paren, if it exists (not on all
704 /// constructs).
705 /// MiscLoc: First misc location, if necessary (not all constructs).
706 /// Exprs: List of expressions on the construct itself, if necessary (not all
707 /// constructs).
708 /// RParenLoc: Location of the right paren, if it exists (not on all
709 /// constructs).
712 SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
713 SourceLocation RParenLoc, SourceLocation EndLoc,
714 ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt);
715
716 /// Called after the directive has been completely parsed, including the
717 /// declaration group or associated statement.
719
720 /// Called when encountering an 'int-expr' for OpenACC, and manages
721 /// conversions and diagnostics to 'int'.
723 SourceLocation Loc, Expr *IntExpr);
724
725 /// Called when encountering a 'var' for OpenACC, ensures it is actually a
726 /// declaration reference to a variable of the correct type.
728
729 /// Called while semantically analyzing the reduction clause, ensuring the var
730 /// is the correct kind of reference.
732 OpenACCReductionOperator ReductionOp,
733 Expr *VarExpr);
734
735 /// Called to check the 'var' type is a variable of pointer type, necessary
736 /// for 'deviceptr' and 'attach' clauses. Returns true on success.
737 bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr);
738
739 /// Checks and creates an Array Section used in an OpenACC construct/clause.
741 Expr *LowerBound,
742 SourceLocation ColonLocFirst, Expr *Length,
743 SourceLocation RBLoc);
744 /// Checks the loop depth value for a collapse clause.
746 /// Checks a single size expr for a tile clause.
748
749 // Check a single expression on a gang clause.
752 Expr *E);
753
754 // Does the checking for a 'gang' clause that needs to be done in dependent
755 // and not dependent cases.
758 ArrayRef<const OpenACCClause *> ExistingClauses,
759 SourceLocation BeginLoc, SourceLocation LParenLoc,
761 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
762 // Does the checking for a 'reduction ' clause that needs to be done in
763 // dependent and not dependent cases.
766 OpenACCDirectiveKind DirectiveKind,
767 SourceLocation BeginLoc, SourceLocation LParenLoc,
768 OpenACCReductionOperator ReductionOp,
769 ArrayRef<Expr *> Vars, SourceLocation EndLoc);
770
773
774 /// Helper type to restore the state of various 'loop' constructs when we run
775 /// into a loop (for, etc) inside the construct.
777 SemaOpenACC &SemaRef;
778 LoopCheckingInfo OldLoopInfo;
779 CollapseCheckingInfo OldCollapseInfo;
780 TileCheckingInfo OldTileInfo;
781 bool PreserveDepth;
782
783 public:
784 LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth = true)
785 : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
786 OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
787 PreserveDepth(PreserveDepth) {}
789 // The associated-statement level of this should NOT preserve this, as it
790 // is a new construct, but other loop uses need to preserve the depth so
791 // it makes it to the 'top level' for diagnostics.
792 bool CollapseDepthSatisified =
793 PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
794 : OldCollapseInfo.CollapseDepthSatisfied;
795 bool TileDepthSatisfied = PreserveDepth
796 ? SemaRef.TileInfo.TileDepthSatisfied
797 : OldTileInfo.TileDepthSatisfied;
798 bool CurLevelHasLoopAlready =
799 PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
800 : OldLoopInfo.CurLevelHasLoopAlready;
801
802 SemaRef.LoopInfo = OldLoopInfo;
803 SemaRef.CollapseInfo = OldCollapseInfo;
804 SemaRef.TileInfo = OldTileInfo;
805
806 SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
807 SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
808 SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
809 }
810 };
811
812 /// Helper type for the registration/assignment of constructs that need to
813 /// 'know' about their parent constructs and hold a reference to them, such as
814 /// Loop needing its parent construct.
816 SemaOpenACC &SemaRef;
817 ComputeConstructInfo OldActiveComputeConstructInfo;
818 OpenACCDirectiveKind DirKind;
819 LoopGangOnKernelTy OldLoopGangClauseOnKernel;
820 SourceLocation OldLoopWorkerClauseLoc;
821 SourceLocation OldLoopVectorClauseLoc;
822 LoopWithoutSeqCheckingInfo OldLoopWithoutSeqInfo;
823 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
824 LoopInConstructRAII LoopRAII;
825
826 public:
837 };
838};
839
840} // namespace clang
841
842#endif // LLVM_CLANG_SEMA_SEMAOPENACC_H
Expr * E
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines some OpenACC-specific enums and functions.
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the clang::SourceLocation class and associated facilities.
This file defines OpenACC AST classes for statement-level contructs.
This represents one expression.
Definition: Expr.h:110
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition: Expr.h:221
QualType getType() const
Definition: Expr.h:142
This is the base type for all OpenACC Clauses.
Definition: OpenACCClause.h:24
Represents a 'collapse' clause on a 'loop' construct.
Helper type for the registration/assignment of constructs that need to 'know' about their parent cons...
Definition: SemaOpenACC.h:815
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,...
Definition: SemaOpenACC.h:776
LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth=true)
Definition: SemaOpenACC.h:784
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
Definition: SemaOpenACC.h:202
ArrayRef< Expr * > getQueueIdExprs() const
Definition: SemaOpenACC.h:338
OpenACCDirectiveKind getDirectiveKind() const
Definition: SemaOpenACC.h:260
ArrayRef< OpenACCGangKind > getGangKinds() const
Definition: SemaOpenACC.h:380
OpenACCParsedClause(OpenACCDirectiveKind DirKind, OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
Definition: SemaOpenACC.h:256
OpenACCReductionOperator getReductionOp() const
Definition: SemaOpenACC.h:376
void setLParenLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:467
void setConditionDetails(Expr *ConditionExpr)
Definition: SemaOpenACC.h:476
void setCollapseDetails(bool IsForce, Expr *LoopCount)
Definition: SemaOpenACC.h:642
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:262
void setGangDetails(ArrayRef< OpenACCGangKind > GKs, ArrayRef< Expr * > IntExprs)
Definition: SemaOpenACC.h:517
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:266
ArrayRef< DeviceTypeArgument > getDeviceTypeArchitectures() const
Definition: SemaOpenACC.h:460
void setIntExprDetails(llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:503
void setReductionDetails(OpenACCReductionOperator Op, llvm::SmallVector< Expr * > &&VarList)
Definition: SemaOpenACC.h:621
ArrayRef< Expr * > getVarList() const
Definition: SemaOpenACC.h:425
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:264
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
Definition: SemaOpenACC.h:470
SourceLocation getQueuesLoc() const
Definition: SemaOpenACC.h:318
void setVarListDetails(llvm::SmallVector< Expr * > &&VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:579
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:536
void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:628
void setEndLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:468
ArrayRef< Expr * > getIntExprs() const
Definition: SemaOpenACC.h:372
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
Definition: SemaOpenACC.h:490
void setDeviceTypeDetails(llvm::SmallVector< DeviceTypeArgument > &&Archs)
Definition: SemaOpenACC.h:635
void setGangDetails(llvm::SmallVector< OpenACCGangKind > &&GKs, llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:527
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:270
ExprResult ActOnVar(OpenACCClauseKind CK, Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
ComputeConstructInfo & getActiveComputeConstructInfo()
Definition: SemaOpenACC.h:162
bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, ArrayRef< const OpenACCClause * > Clauses)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc, Expr *IntExpr)
Called when encountering an 'int-expr' for OpenACC, and manages conversions and diagnostics to 'int'.
void ActOnWhileStmt(SourceLocation WhileLoc)
SourceLocation LoopWorkerClauseLoc
If there is a current 'active' loop construct with a 'worker' clause on it (on any sort of construct)...
Definition: SemaOpenACC.h:179
OpenACCClause * ActOnClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCParsedClause &Clause)
Called after parsing an OpenACC Clause so that it can be checked.
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr)
Called to check the 'var' type is a variable of pointer type, necessary for 'deviceptr' and 'attach' ...
struct clang::SemaOpenACC::LoopGangOnKernelTy LoopGangClauseOnKernel
ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind, OpenACCReductionOperator ReductionOp, Expr *VarExpr)
Called while semantically analyzing the reduction clause, ensuring the var is the correct kind of ref...
ExprResult CheckCollapseLoopCount(Expr *LoopCount)
Checks the loop depth value for a collapse clause.
struct clang::SemaOpenACC::LoopWithoutSeqCheckingInfo LoopWithoutSeqInfo
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
DeclGroupRef ActOnEndDeclDirective()
Called after the directive has been completely parsed, including the declaration group or associated ...
OpenACCClause * CheckReductionClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, ArrayRef< Expr * > Vars, SourceLocation EndLoc)
std::pair< IdentifierInfo *, SourceLocation > DeviceTypeArgument
Definition: SemaOpenACC.h:196
SourceLocation LoopVectorClauseLoc
If there is a current 'active' loop construct with a 'vector' clause on it (on any sort of construct)...
Definition: SemaOpenACC.h:184
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
ExprResult CheckGangExpr(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DK, OpenACCGangKind GK, Expr *E)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
OpenACCClause * CheckGangClause(OpenACCDirectiveKind DirKind, ArrayRef< const OpenACCClause * > ExistingClauses, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc)
Checks and creates an Array Section used in an OpenACC construct/clause.
ExprResult CheckTileSizeExpr(Expr *SizeExpr)
Checks a single size expr for a tile clause.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:464
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
void setEnd(SourceLocation e)
Stmt - This represents one statement.
Definition: Stmt.h:84
bool isScalarType() const
Definition: Type.h:8614
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25
OpenACCReductionOperator
Definition: OpenACCKinds.h:509
OpenACCClauseKind
Represents the kind of an OpenACC clause.
Definition: OpenACCKinds.h:178
@ 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'.
@ 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.
@ 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'.
OpenACCDefaultClauseKind
Definition: OpenACCKinds.h:476
OpenACCGangKind
Definition: OpenACCKinds.h:568
If there is a current 'active' loop construct with a 'gang' clause on a 'kernel' construct,...
Definition: SemaOpenACC.h:170
If there is a current 'active' loop construct that does NOT have a 'seq' clause on it,...
Definition: SemaOpenACC.h:190