clang 19.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"
21#include "clang/Sema/SemaBase.h"
22#include <variant>
23
24namespace clang {
25class OpenACCClause;
26
27class SemaOpenACC : public SemaBase {
28public:
29 // Redeclaration of the version in OpenACCClause.h.
30 using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
31
32 /// A type to represent all the data for an OpenACC Clause that has been
33 /// parsed, but not yet created/semantically analyzed. This is effectively a
34 /// discriminated union on the 'Clause Kind', with all of the individual
35 /// clause details stored in a std::variant.
38 OpenACCClauseKind ClauseKind;
39 SourceRange ClauseRange;
40 SourceLocation LParenLoc;
41
42 struct DefaultDetails {
43 OpenACCDefaultClauseKind DefaultClauseKind;
44 };
45
46 struct ConditionDetails {
47 Expr *ConditionExpr;
48 };
49
50 struct IntExprDetails {
51 SmallVector<Expr *> IntExprs;
52 };
53
54 struct VarListDetails {
55 SmallVector<Expr *> VarList;
56 bool IsReadOnly;
57 bool IsZero;
58 };
59
60 struct WaitDetails {
61 Expr *DevNumExpr;
62 SourceLocation QueuesLoc;
63 SmallVector<Expr *> QueueIdExprs;
64 };
65
66 struct DeviceTypeDetails {
68 };
69
70 std::variant<std::monostate, DefaultDetails, ConditionDetails,
71 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails>
72 Details = std::monostate{};
73
74 public:
76 OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
77 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
78
79 OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }
80
81 OpenACCClauseKind getClauseKind() const { return ClauseKind; }
82
83 SourceLocation getBeginLoc() const { return ClauseRange.getBegin(); }
84
85 SourceLocation getLParenLoc() const { return LParenLoc; }
86
87 SourceLocation getEndLoc() const { return ClauseRange.getEnd(); }
88
90 assert(ClauseKind == OpenACCClauseKind::Default &&
91 "Parsed clause is not a default clause");
92 return std::get<DefaultDetails>(Details).DefaultClauseKind;
93 }
94
95 const Expr *getConditionExpr() const {
96 return const_cast<OpenACCParsedClause *>(this)->getConditionExpr();
97 }
98
100 assert((ClauseKind == OpenACCClauseKind::If ||
101 (ClauseKind == OpenACCClauseKind::Self &&
102 DirKind != OpenACCDirectiveKind::Update)) &&
103 "Parsed clause kind does not have a condition expr");
104
105 // 'self' has an optional ConditionExpr, so be tolerant of that. This will
106 // assert in variant otherwise.
107 if (ClauseKind == OpenACCClauseKind::Self &&
108 std::holds_alternative<std::monostate>(Details))
109 return nullptr;
110
111 return std::get<ConditionDetails>(Details).ConditionExpr;
112 }
113
114 unsigned getNumIntExprs() const {
115 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
116 ClauseKind == OpenACCClauseKind::NumWorkers ||
117 ClauseKind == OpenACCClauseKind::Async ||
118 ClauseKind == OpenACCClauseKind::VectorLength) &&
119 "Parsed clause kind does not have a int exprs");
120
121 // 'async' and 'wait' have an optional IntExpr, so be tolerant of that.
122 if ((ClauseKind == OpenACCClauseKind::Async ||
123 ClauseKind == OpenACCClauseKind::Wait) &&
124 std::holds_alternative<std::monostate>(Details))
125 return 0;
126 return std::get<IntExprDetails>(Details).IntExprs.size();
127 }
128
130 assert(ClauseKind == OpenACCClauseKind::Wait &&
131 "Parsed clause kind does not have a queues location");
132
133 if (std::holds_alternative<std::monostate>(Details))
134 return SourceLocation{};
135
136 return std::get<WaitDetails>(Details).QueuesLoc;
137 }
138
140 assert(ClauseKind == OpenACCClauseKind::Wait &&
141 "Parsed clause kind does not have a device number expr");
142
143 if (std::holds_alternative<std::monostate>(Details))
144 return nullptr;
145
146 return std::get<WaitDetails>(Details).DevNumExpr;
147 }
148
150 assert(ClauseKind == OpenACCClauseKind::Wait &&
151 "Parsed clause kind does not have a queue id expr list");
152
153 if (std::holds_alternative<std::monostate>(Details))
154 return ArrayRef<Expr *>{std::nullopt};
155
156 return std::get<WaitDetails>(Details).QueueIdExprs;
157 }
158
160 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
161 ClauseKind == OpenACCClauseKind::NumWorkers ||
162 ClauseKind == OpenACCClauseKind::Async ||
163 ClauseKind == OpenACCClauseKind::VectorLength) &&
164 "Parsed clause kind does not have a int exprs");
165
166 return std::get<IntExprDetails>(Details).IntExprs;
167 }
168
170 return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
171 }
172
174 assert((ClauseKind == OpenACCClauseKind::Private ||
175 ClauseKind == OpenACCClauseKind::NoCreate ||
176 ClauseKind == OpenACCClauseKind::Present ||
177 ClauseKind == OpenACCClauseKind::Copy ||
178 ClauseKind == OpenACCClauseKind::PCopy ||
179 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
180 ClauseKind == OpenACCClauseKind::CopyIn ||
181 ClauseKind == OpenACCClauseKind::PCopyIn ||
183 ClauseKind == OpenACCClauseKind::CopyOut ||
184 ClauseKind == OpenACCClauseKind::PCopyOut ||
186 ClauseKind == OpenACCClauseKind::Create ||
187 ClauseKind == OpenACCClauseKind::PCreate ||
189 ClauseKind == OpenACCClauseKind::Attach ||
190 ClauseKind == OpenACCClauseKind::DevicePtr ||
191 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
192 "Parsed clause kind does not have a var-list");
193 return std::get<VarListDetails>(Details).VarList;
194 }
195
197 return const_cast<OpenACCParsedClause *>(this)->getVarList();
198 }
199
200 bool isReadOnly() const {
201 assert((ClauseKind == OpenACCClauseKind::CopyIn ||
202 ClauseKind == OpenACCClauseKind::PCopyIn ||
203 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
204 "Only copyin accepts 'readonly:' tag");
205 return std::get<VarListDetails>(Details).IsReadOnly;
206 }
207
208 bool isZero() const {
209 assert((ClauseKind == OpenACCClauseKind::CopyOut ||
210 ClauseKind == OpenACCClauseKind::PCopyOut ||
212 ClauseKind == OpenACCClauseKind::Create ||
213 ClauseKind == OpenACCClauseKind::PCreate ||
214 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
215 "Only copyout/create accepts 'zero' tag");
216 return std::get<VarListDetails>(Details).IsZero;
217 }
218
220 assert((ClauseKind == OpenACCClauseKind::DeviceType ||
221 ClauseKind == OpenACCClauseKind::DType) &&
222 "Only 'device_type'/'dtype' has a device-type-arg list");
223 return std::get<DeviceTypeDetails>(Details).Archs;
224 }
225
226 void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
227 void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }
228
230 assert(ClauseKind == OpenACCClauseKind::Default &&
231 "Parsed clause is not a default clause");
232 Details = DefaultDetails{DefKind};
233 }
234
235 void setConditionDetails(Expr *ConditionExpr) {
236 assert((ClauseKind == OpenACCClauseKind::If ||
237 (ClauseKind == OpenACCClauseKind::Self &&
238 DirKind != OpenACCDirectiveKind::Update)) &&
239 "Parsed clause kind does not have a condition expr");
240 // In C++ we can count on this being a 'bool', but in C this gets left as
241 // some sort of scalar that codegen will have to take care of converting.
242 assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() ||
243 ConditionExpr->getType()->isScalarType()) &&
244 "Condition expression type not scalar/dependent");
245
246 Details = ConditionDetails{ConditionExpr};
247 }
248
250 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
251 ClauseKind == OpenACCClauseKind::NumWorkers ||
252 ClauseKind == OpenACCClauseKind::Async ||
253 ClauseKind == OpenACCClauseKind::VectorLength) &&
254 "Parsed clause kind does not have a int exprs");
255 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
256 }
258 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
259 ClauseKind == OpenACCClauseKind::NumWorkers ||
260 ClauseKind == OpenACCClauseKind::Async ||
261 ClauseKind == OpenACCClauseKind::VectorLength) &&
262 "Parsed clause kind does not have a int exprs");
263 Details = IntExprDetails{std::move(IntExprs)};
264 }
265
266 void setVarListDetails(ArrayRef<Expr *> VarList, bool IsReadOnly,
267 bool IsZero) {
268 assert((ClauseKind == OpenACCClauseKind::Private ||
269 ClauseKind == OpenACCClauseKind::NoCreate ||
270 ClauseKind == OpenACCClauseKind::Present ||
271 ClauseKind == OpenACCClauseKind::Copy ||
272 ClauseKind == OpenACCClauseKind::PCopy ||
273 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
274 ClauseKind == OpenACCClauseKind::CopyIn ||
275 ClauseKind == OpenACCClauseKind::PCopyIn ||
277 ClauseKind == OpenACCClauseKind::CopyOut ||
278 ClauseKind == OpenACCClauseKind::PCopyOut ||
280 ClauseKind == OpenACCClauseKind::Create ||
281 ClauseKind == OpenACCClauseKind::PCreate ||
283 ClauseKind == OpenACCClauseKind::Attach ||
284 ClauseKind == OpenACCClauseKind::DevicePtr ||
285 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
286 "Parsed clause kind does not have a var-list");
287 assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
288 ClauseKind == OpenACCClauseKind::PCopyIn ||
289 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
290 "readonly: tag only valid on copyin");
291 assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
292 ClauseKind == OpenACCClauseKind::PCopyOut ||
294 ClauseKind == OpenACCClauseKind::Create ||
295 ClauseKind == OpenACCClauseKind::PCreate ||
296 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
297 "zero: tag only valid on copyout/create");
298 Details =
299 VarListDetails{{VarList.begin(), VarList.end()}, IsReadOnly, IsZero};
300 }
301
302 void setVarListDetails(llvm::SmallVector<Expr *> &&VarList, bool IsReadOnly,
303 bool IsZero) {
304 assert((ClauseKind == OpenACCClauseKind::Private ||
305 ClauseKind == OpenACCClauseKind::NoCreate ||
306 ClauseKind == OpenACCClauseKind::Present ||
307 ClauseKind == OpenACCClauseKind::Copy ||
308 ClauseKind == OpenACCClauseKind::PCopy ||
309 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
310 ClauseKind == OpenACCClauseKind::CopyIn ||
311 ClauseKind == OpenACCClauseKind::PCopyIn ||
313 ClauseKind == OpenACCClauseKind::CopyOut ||
314 ClauseKind == OpenACCClauseKind::PCopyOut ||
316 ClauseKind == OpenACCClauseKind::Create ||
317 ClauseKind == OpenACCClauseKind::PCreate ||
319 ClauseKind == OpenACCClauseKind::Attach ||
320 ClauseKind == OpenACCClauseKind::DevicePtr ||
321 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
322 "Parsed clause kind does not have a var-list");
323 assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
324 ClauseKind == OpenACCClauseKind::PCopyIn ||
325 ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
326 "readonly: tag only valid on copyin");
327 assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
328 ClauseKind == OpenACCClauseKind::PCopyOut ||
330 ClauseKind == OpenACCClauseKind::Create ||
331 ClauseKind == OpenACCClauseKind::PCreate ||
332 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
333 "zero: tag only valid on copyout/create");
334 Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero};
335 }
336
337 void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc,
338 llvm::SmallVector<Expr *> &&IntExprs) {
339 assert(ClauseKind == OpenACCClauseKind::Wait &&
340 "Parsed clause kind does not have a wait-details");
341 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
342 }
343
345 assert((ClauseKind == OpenACCClauseKind::DeviceType ||
346 ClauseKind == OpenACCClauseKind::DType) &&
347 "Only 'device_type'/'dtype' has a device-type-arg list");
348 Details = DeviceTypeDetails{std::move(Archs)};
349 }
350 };
351
352 SemaOpenACC(Sema &S);
353
354 /// Called after parsing an OpenACC Clause so that it can be checked.
356 OpenACCParsedClause &Clause);
357
358 /// Called after the construct has been parsed, but clauses haven't been
359 /// parsed. This allows us to diagnose not-implemented, as well as set up any
360 /// state required for parsing the clauses.
362
363 /// Called after the directive, including its clauses, have been parsed and
364 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
365 /// happen before any associated declarations or statements have been parsed.
366 /// This function is only called when we are parsing a 'statement' context.
368
369 /// Called after the directive, including its clauses, have been parsed and
370 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
371 /// happen before any associated declarations or statements have been parsed.
372 /// This function is only called when we are parsing a 'Decl' context.
374 /// Called when we encounter an associated statement for our construct, this
375 /// should check legality of the statement as it appertains to this Construct.
377
378 /// Called after the directive has been completely parsed, including the
379 /// declaration group or associated statement.
381 SourceLocation StartLoc,
382 SourceLocation EndLoc,
384 StmtResult AssocStmt);
385
386 /// Called after the directive has been completely parsed, including the
387 /// declaration group or associated statement.
389
390 /// Called when encountering an 'int-expr' for OpenACC, and manages
391 /// conversions and diagnostics to 'int'.
393 SourceLocation Loc, Expr *IntExpr);
394
395 /// Called when encountering a 'var' for OpenACC, ensures it is actually a
396 /// declaration reference to a variable of the correct type.
397 ExprResult ActOnVar(Expr *VarExpr);
398
399 /// Called to check the 'var' type is a variable of pointer type, necessary
400 /// for 'deviceptr' and 'attach' clauses. Returns true on success.
401 bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr);
402
403 /// Checks and creates an Array Section used in an OpenACC construct/clause.
405 Expr *LowerBound,
406 SourceLocation ColonLocFirst, Expr *Length,
407 SourceLocation RBLoc);
408};
409
410} // namespace clang
411
412#endif // LLVM_CLANG_SEMA_SEMAOPENACC_H
Defines some OpenACC-specific enums and functions.
SourceLocation Loc
Definition: SemaObjC.cpp:755
Defines the clang::SourceLocation class and associated facilities.
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
A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...
Definition: SemaOpenACC.h:36
ArrayRef< Expr * > getQueueIdExprs() const
Definition: SemaOpenACC.h:149
OpenACCDirectiveKind getDirectiveKind() const
Definition: SemaOpenACC.h:79
OpenACCParsedClause(OpenACCDirectiveKind DirKind, OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
Definition: SemaOpenACC.h:75
SourceLocation getEndLoc() const
Definition: SemaOpenACC.h:87
void setLParenLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:226
void setConditionDetails(Expr *ConditionExpr)
Definition: SemaOpenACC.h:235
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:81
const Expr * getConditionExpr() const
Definition: SemaOpenACC.h:95
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:85
ArrayRef< DeviceTypeArgument > getDeviceTypeArchitectures() const
Definition: SemaOpenACC.h:219
void setIntExprDetails(llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:257
ArrayRef< Expr * > getVarList() const
Definition: SemaOpenACC.h:196
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:83
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
Definition: SemaOpenACC.h:229
SourceLocation getQueuesLoc() const
Definition: SemaOpenACC.h:129
void setVarListDetails(llvm::SmallVector< Expr * > &&VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:302
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:266
void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:337
void setEndLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:227
ArrayRef< Expr * > getIntExprs() const
Definition: SemaOpenACC.h:169
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
Definition: SemaOpenACC.h:249
void setDeviceTypeDetails(llvm::SmallVector< DeviceTypeArgument > &&Archs)
Definition: SemaOpenACC.h:344
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:89
ExprResult ActOnVar(Expr *VarExpr)
Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...
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'.
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
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' ...
bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...
DeclGroupRef ActOnEndDeclDirective()
Called after the directive has been completely parsed, including the declaration group or associated ...
void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc)
Called after the construct has been parsed, but clauses haven't been parsed.
std::pair< IdentifierInfo *, SourceLocation > DeviceTypeArgument
Definition: SemaOpenACC.h:30
StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt)
Called when we encounter an associated statement for our construct, this should check legality of the...
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.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:451
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)
bool isScalarType() const
Definition: Type.h:8004
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCClauseKind
Represents the kind of an OpenACC clause.
Definition: OpenACCKinds.h:164
@ 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'.
@ PresentOrCopy
'copy' clause alias 'present_or_copy'. Preserved for diagnostic purposes.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
@ Copy
'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.
@ 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',...
@ 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.
@ NoCreate
'no_create' clause, allowed on allowed on Compute and Combined constructs, plus 'data'.
@ PresentOrCopyOut
'copyout' clause alias 'present_or_copyout'.
@ 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...
@ PCopy
'copy' clause alias 'pcopy'. Preserved for diagnostic purposes.
@ 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',...
@ NumWorkers
'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs...
@ PresentOrCopyIn
'copyin' clause alias 'present_or_copyin'.
OpenACCDefaultClauseKind
Definition: OpenACCKinds.h:462
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25