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
232public:
233 // Needed from the visitor, so should be public.
234 bool DiagnoseAllowedOnceClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
235 SourceLocation ClauseLoc,
237 bool DiagnoseExclusiveClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
238 SourceLocation ClauseLoc,
240
241 OpenACCPrivateRecipe CreatePrivateInitRecipe(const Expr *VarExpr);
242 OpenACCFirstPrivateRecipe CreateFirstPrivateInitRecipe(const Expr *VarExpr);
243 OpenACCReductionRecipe
244 CreateReductionInitRecipe(OpenACCReductionOperator ReductionOperator,
245 const Expr *VarExpr);
246
247public:
248 ComputeConstructInfo &getActiveComputeConstructInfo() {
249 return ActiveComputeConstructInfo;
250 }
251
252 /// If there is a current 'active' loop construct with a 'gang' clause on a
253 /// 'kernel' construct, this will have the source location for it, and the
254 /// 'kernel kind'. This permits us to implement the restriction of no further
255 /// 'gang' clauses.
260
261 /// If there is a current 'active' loop construct with a 'worker' clause on it
262 /// (on any sort of construct), this has the source location for it. This
263 /// permits us to implement the restriction of no further 'gang' or 'worker'
264 /// clauses.
266 /// If there is a current 'active' loop construct with a 'vector' 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', 'vector', or
269 /// 'worker' clauses.
271 /// If there is a current 'active' loop construct that does NOT have a 'seq'
272 /// clause on it, this has that source location and loop Directive 'kind'.
273 /// This permits us to implement the 'loop' restrictions on the loop variable.
274 /// This can be extended via 'collapse', so we need to keep this around for a
275 /// while.
280
281 // Redeclaration of the version in OpenACCClause.h.
283
284 /// A type to represent all the data for an OpenACC Clause that has been
285 /// parsed, but not yet created/semantically analyzed. This is effectively a
286 /// discriminated union on the 'Clause Kind', with all of the individual
287 /// clause details stored in a std::variant.
289 OpenACCDirectiveKind DirKind;
290 OpenACCClauseKind ClauseKind;
291 SourceRange ClauseRange;
292 SourceLocation LParenLoc;
293
294 struct DefaultDetails {
295 OpenACCDefaultClauseKind DefaultClauseKind;
296 };
297
298 struct ConditionDetails {
299 Expr *ConditionExpr;
300 };
301
302 struct IntExprDetails {
303 SmallVector<Expr *> IntExprs;
304 };
305
306 struct VarListDetails {
307 SmallVector<Expr *> VarList;
308 OpenACCModifierKind ModifierKind;
309 };
310
311 struct WaitDetails {
312 Expr *DevNumExpr;
313 SourceLocation QueuesLoc;
314 SmallVector<Expr *> QueueIdExprs;
315 };
316
317 struct DeviceTypeDetails {
319 };
320 struct ReductionDetails {
322 SmallVector<Expr *> VarList;
323 };
324
325 struct CollapseDetails {
326 bool IsForce;
327 Expr *LoopCount;
328 };
329
330 struct GangDetails {
332 SmallVector<Expr *> IntExprs;
333 };
334 struct BindDetails {
335 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
336 Argument;
337 };
338
339 std::variant<std::monostate, DefaultDetails, ConditionDetails,
340 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails,
341 ReductionDetails, CollapseDetails, GangDetails, BindDetails>
342 Details = std::monostate{};
343
344 public:
346 OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
347 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}
348
349 OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }
350
351 OpenACCClauseKind getClauseKind() const { return ClauseKind; }
352
353 SourceLocation getBeginLoc() const { return ClauseRange.getBegin(); }
354
355 SourceLocation getLParenLoc() const { return LParenLoc; }
356
357 SourceLocation getEndLoc() const { return ClauseRange.getEnd(); }
358
360 assert(ClauseKind == OpenACCClauseKind::Default &&
361 "Parsed clause is not a default clause");
362 return std::get<DefaultDetails>(Details).DefaultClauseKind;
363 }
364
365 const Expr *getConditionExpr() const {
366 return const_cast<OpenACCParsedClause *>(this)->getConditionExpr();
367 }
368
370 assert((ClauseKind == OpenACCClauseKind::If ||
371 (ClauseKind == OpenACCClauseKind::Self &&
372 DirKind != OpenACCDirectiveKind::Update)) &&
373 "Parsed clause kind does not have a condition expr");
374
375 // 'self' has an optional ConditionExpr, so be tolerant of that. This will
376 // assert in variant otherwise.
377 if (ClauseKind == OpenACCClauseKind::Self &&
378 std::holds_alternative<std::monostate>(Details))
379 return nullptr;
380
381 return std::get<ConditionDetails>(Details).ConditionExpr;
382 }
383
384 unsigned getNumIntExprs() const {
385 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
386 ClauseKind == OpenACCClauseKind::NumWorkers ||
387 ClauseKind == OpenACCClauseKind::Async ||
388 ClauseKind == OpenACCClauseKind::DeviceNum ||
389 ClauseKind == OpenACCClauseKind::DefaultAsync ||
390 ClauseKind == OpenACCClauseKind::Tile ||
391 ClauseKind == OpenACCClauseKind::Worker ||
392 ClauseKind == OpenACCClauseKind::Vector ||
393 ClauseKind == OpenACCClauseKind::VectorLength) &&
394 "Parsed clause kind does not have a int exprs");
395
396 // 'async', 'worker', 'vector', and 'wait' have an optional IntExpr, so be
397 // tolerant of that.
398 if ((ClauseKind == OpenACCClauseKind::Async ||
399 ClauseKind == OpenACCClauseKind::Worker ||
400 ClauseKind == OpenACCClauseKind::Vector ||
401 ClauseKind == OpenACCClauseKind::Wait) &&
402 std::holds_alternative<std::monostate>(Details))
403 return 0;
404 return std::get<IntExprDetails>(Details).IntExprs.size();
405 }
406
408 assert(ClauseKind == OpenACCClauseKind::Wait &&
409 "Parsed clause kind does not have a queues location");
410
411 if (std::holds_alternative<std::monostate>(Details))
412 return SourceLocation{};
413
414 return std::get<WaitDetails>(Details).QueuesLoc;
415 }
416
418 assert(ClauseKind == OpenACCClauseKind::Wait &&
419 "Parsed clause kind does not have a device number expr");
420
421 if (std::holds_alternative<std::monostate>(Details))
422 return nullptr;
423
424 return std::get<WaitDetails>(Details).DevNumExpr;
425 }
426
428 assert(ClauseKind == OpenACCClauseKind::Wait &&
429 "Parsed clause kind does not have a queue id expr list");
430
431 if (std::holds_alternative<std::monostate>(Details))
432 return ArrayRef<Expr *>();
433
434 return std::get<WaitDetails>(Details).QueueIdExprs;
435 }
436
438 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
439 ClauseKind == OpenACCClauseKind::NumWorkers ||
440 ClauseKind == OpenACCClauseKind::Async ||
441 ClauseKind == OpenACCClauseKind::DeviceNum ||
442 ClauseKind == OpenACCClauseKind::DefaultAsync ||
443 ClauseKind == OpenACCClauseKind::Tile ||
444 ClauseKind == OpenACCClauseKind::Gang ||
445 ClauseKind == OpenACCClauseKind::Worker ||
446 ClauseKind == OpenACCClauseKind::Vector ||
447 ClauseKind == OpenACCClauseKind::VectorLength) &&
448 "Parsed clause kind does not have a int exprs");
449
450 if (ClauseKind == OpenACCClauseKind::Gang) {
451 // There might not be any gang int exprs, as this is an optional
452 // argument.
453 if (std::holds_alternative<std::monostate>(Details))
454 return {};
455 return std::get<GangDetails>(Details).IntExprs;
456 }
457
458 return std::get<IntExprDetails>(Details).IntExprs;
459 }
460
462 return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
463 }
464
466 return std::get<ReductionDetails>(Details).Op;
467 }
468
470 assert(ClauseKind == OpenACCClauseKind::Gang &&
471 "Parsed clause kind does not have gang kind");
472 // The args on gang are optional, so this might not actually hold
473 // anything.
474 if (std::holds_alternative<std::monostate>(Details))
475 return {};
476 return std::get<GangDetails>(Details).GangKinds;
477 }
478
480 assert((ClauseKind == OpenACCClauseKind::Private ||
481 ClauseKind == OpenACCClauseKind::NoCreate ||
482 ClauseKind == OpenACCClauseKind::Present ||
483 ClauseKind == OpenACCClauseKind::Copy ||
484 ClauseKind == OpenACCClauseKind::PCopy ||
485 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
486 ClauseKind == OpenACCClauseKind::CopyIn ||
487 ClauseKind == OpenACCClauseKind::PCopyIn ||
489 ClauseKind == OpenACCClauseKind::CopyOut ||
490 ClauseKind == OpenACCClauseKind::PCopyOut ||
492 ClauseKind == OpenACCClauseKind::Create ||
493 ClauseKind == OpenACCClauseKind::PCreate ||
495 ClauseKind == OpenACCClauseKind::Attach ||
496 ClauseKind == OpenACCClauseKind::Delete ||
497 ClauseKind == OpenACCClauseKind::UseDevice ||
498 ClauseKind == OpenACCClauseKind::Detach ||
499 ClauseKind == OpenACCClauseKind::DevicePtr ||
500 ClauseKind == OpenACCClauseKind::Reduction ||
501 ClauseKind == OpenACCClauseKind::Host ||
502 ClauseKind == OpenACCClauseKind::Device ||
503 ClauseKind == OpenACCClauseKind::DeviceResident ||
504 ClauseKind == OpenACCClauseKind::Link ||
505 (ClauseKind == OpenACCClauseKind::Self &&
506 DirKind == OpenACCDirectiveKind::Update) ||
507 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
508 "Parsed clause kind does not have a var-list");
509
510 if (ClauseKind == OpenACCClauseKind::Reduction)
511 return std::get<ReductionDetails>(Details).VarList;
512
513 return std::get<VarListDetails>(Details).VarList;
514 }
515
517 return const_cast<OpenACCParsedClause *>(this)->getVarList();
518 }
519
521 return std::get<VarListDetails>(Details).ModifierKind;
522 }
523
524 bool isForce() const {
525 assert(ClauseKind == OpenACCClauseKind::Collapse &&
526 "Only 'collapse' has a force tag");
527 return std::get<CollapseDetails>(Details).IsForce;
528 }
529
531 assert(ClauseKind == OpenACCClauseKind::Collapse &&
532 "Only 'collapse' has a loop count");
533 return std::get<CollapseDetails>(Details).LoopCount;
534 }
535
537 assert((ClauseKind == OpenACCClauseKind::DeviceType ||
538 ClauseKind == OpenACCClauseKind::DType) &&
539 "Only 'device_type'/'dtype' has a device-type-arg list");
540 return std::get<DeviceTypeDetails>(Details).Archs;
541 }
542
543 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
545 assert(ClauseKind == OpenACCClauseKind::Bind &&
546 "Only 'bind' has bind details");
547 return std::get<BindDetails>(Details).Argument;
548 }
549
550 void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
551 void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }
552
554 assert(ClauseKind == OpenACCClauseKind::Default &&
555 "Parsed clause is not a default clause");
556 Details = DefaultDetails{DefKind};
557 }
558
559 void setConditionDetails(Expr *ConditionExpr) {
560 assert((ClauseKind == OpenACCClauseKind::If ||
561 (ClauseKind == OpenACCClauseKind::Self &&
562 DirKind != OpenACCDirectiveKind::Update)) &&
563 "Parsed clause kind does not have a condition expr");
564 // In C++ we can count on this being a 'bool', but in C this gets left as
565 // some sort of scalar that codegen will have to take care of converting.
566 assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() ||
567 ConditionExpr->getType()->isScalarType()) &&
568 "Condition expression type not scalar/dependent");
569
570 Details = ConditionDetails{ConditionExpr};
571 }
572
574 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
575 ClauseKind == OpenACCClauseKind::NumWorkers ||
576 ClauseKind == OpenACCClauseKind::Async ||
577 ClauseKind == OpenACCClauseKind::DeviceNum ||
578 ClauseKind == OpenACCClauseKind::DefaultAsync ||
579 ClauseKind == OpenACCClauseKind::Tile ||
580 ClauseKind == OpenACCClauseKind::Worker ||
581 ClauseKind == OpenACCClauseKind::Vector ||
582 ClauseKind == OpenACCClauseKind::VectorLength) &&
583 "Parsed clause kind does not have a int exprs");
584 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
585 }
587 assert((ClauseKind == OpenACCClauseKind::NumGangs ||
588 ClauseKind == OpenACCClauseKind::NumWorkers ||
589 ClauseKind == OpenACCClauseKind::Async ||
590 ClauseKind == OpenACCClauseKind::DeviceNum ||
591 ClauseKind == OpenACCClauseKind::DefaultAsync ||
592 ClauseKind == OpenACCClauseKind::Tile ||
593 ClauseKind == OpenACCClauseKind::Worker ||
594 ClauseKind == OpenACCClauseKind::Vector ||
595 ClauseKind == OpenACCClauseKind::VectorLength) &&
596 "Parsed clause kind does not have a int exprs");
597 Details = IntExprDetails{std::move(IntExprs)};
598 }
599
601 ArrayRef<Expr *> IntExprs) {
602 assert(ClauseKind == OpenACCClauseKind::Gang &&
603 "Parsed Clause kind does not have gang details");
604 assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?");
605
606 Details = GangDetails{{GKs.begin(), GKs.end()},
607 {IntExprs.begin(), IntExprs.end()}};
608 }
609
611 llvm::SmallVector<Expr *> &&IntExprs) {
612 assert(ClauseKind == OpenACCClauseKind::Gang &&
613 "Parsed Clause kind does not have gang details");
614 assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?");
615
616 Details = GangDetails{std::move(GKs), std::move(IntExprs)};
617 }
618
620 OpenACCModifierKind ModKind) {
621 assert((ClauseKind == OpenACCClauseKind::Private ||
622 ClauseKind == OpenACCClauseKind::NoCreate ||
623 ClauseKind == OpenACCClauseKind::Present ||
624 ClauseKind == OpenACCClauseKind::Copy ||
625 ClauseKind == OpenACCClauseKind::PCopy ||
626 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
627 ClauseKind == OpenACCClauseKind::CopyIn ||
628 ClauseKind == OpenACCClauseKind::PCopyIn ||
630 ClauseKind == OpenACCClauseKind::CopyOut ||
631 ClauseKind == OpenACCClauseKind::PCopyOut ||
633 ClauseKind == OpenACCClauseKind::Create ||
634 ClauseKind == OpenACCClauseKind::PCreate ||
636 ClauseKind == OpenACCClauseKind::Attach ||
637 ClauseKind == OpenACCClauseKind::Delete ||
638 ClauseKind == OpenACCClauseKind::UseDevice ||
639 ClauseKind == OpenACCClauseKind::Detach ||
640 ClauseKind == OpenACCClauseKind::DevicePtr ||
641 ClauseKind == OpenACCClauseKind::Host ||
642 ClauseKind == OpenACCClauseKind::Device ||
643 ClauseKind == OpenACCClauseKind::DeviceResident ||
644 ClauseKind == OpenACCClauseKind::Link ||
645 (ClauseKind == OpenACCClauseKind::Self &&
646 DirKind == OpenACCDirectiveKind::Update) ||
647 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
648 "Parsed clause kind does not have a var-list");
649 assert((ModKind == OpenACCModifierKind::Invalid ||
650 ClauseKind == OpenACCClauseKind::Copy ||
651 ClauseKind == OpenACCClauseKind::PCopy ||
652 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
653 ClauseKind == OpenACCClauseKind::CopyIn ||
654 ClauseKind == OpenACCClauseKind::PCopyIn ||
656 ClauseKind == OpenACCClauseKind::CopyOut ||
657 ClauseKind == OpenACCClauseKind::PCopyOut ||
659 ClauseKind == OpenACCClauseKind::Create ||
660 ClauseKind == OpenACCClauseKind::PCreate ||
661 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
662 "Modifier Kind only valid on copy, copyin, copyout, create");
663 Details = VarListDetails{{VarList.begin(), VarList.end()}, ModKind};
664 }
665
667 OpenACCModifierKind ModKind) {
668 assert((ClauseKind == OpenACCClauseKind::Private ||
669 ClauseKind == OpenACCClauseKind::NoCreate ||
670 ClauseKind == OpenACCClauseKind::Present ||
671 ClauseKind == OpenACCClauseKind::Copy ||
672 ClauseKind == OpenACCClauseKind::PCopy ||
673 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
674 ClauseKind == OpenACCClauseKind::CopyIn ||
675 ClauseKind == OpenACCClauseKind::PCopyIn ||
677 ClauseKind == OpenACCClauseKind::CopyOut ||
678 ClauseKind == OpenACCClauseKind::PCopyOut ||
680 ClauseKind == OpenACCClauseKind::Create ||
681 ClauseKind == OpenACCClauseKind::PCreate ||
683 ClauseKind == OpenACCClauseKind::Attach ||
684 ClauseKind == OpenACCClauseKind::Delete ||
685 ClauseKind == OpenACCClauseKind::UseDevice ||
686 ClauseKind == OpenACCClauseKind::Detach ||
687 ClauseKind == OpenACCClauseKind::DevicePtr ||
688 ClauseKind == OpenACCClauseKind::Host ||
689 ClauseKind == OpenACCClauseKind::Device ||
690 ClauseKind == OpenACCClauseKind::DeviceResident ||
691 ClauseKind == OpenACCClauseKind::Link ||
692 (ClauseKind == OpenACCClauseKind::Self &&
693 DirKind == OpenACCDirectiveKind::Update) ||
694 ClauseKind == OpenACCClauseKind::FirstPrivate) &&
695 "Parsed clause kind does not have a var-list");
696 assert((ModKind == OpenACCModifierKind::Invalid ||
697 ClauseKind == OpenACCClauseKind::Copy ||
698 ClauseKind == OpenACCClauseKind::PCopy ||
699 ClauseKind == OpenACCClauseKind::PresentOrCopy ||
700 ClauseKind == OpenACCClauseKind::CopyIn ||
701 ClauseKind == OpenACCClauseKind::PCopyIn ||
703 ClauseKind == OpenACCClauseKind::CopyOut ||
704 ClauseKind == OpenACCClauseKind::PCopyOut ||
706 ClauseKind == OpenACCClauseKind::Create ||
707 ClauseKind == OpenACCClauseKind::PCreate ||
708 ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
709 "Modifier Kind only valid on copy, copyin, copyout, create");
710 Details = VarListDetails{std::move(VarList), ModKind};
711 }
712
714 llvm::SmallVector<Expr *> &&VarList) {
715 assert(ClauseKind == OpenACCClauseKind::Reduction &&
716 "reduction details only valid on reduction");
717 Details = ReductionDetails{Op, std::move(VarList)};
718 }
719
720 void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc,
721 llvm::SmallVector<Expr *> &&IntExprs) {
722 assert(ClauseKind == OpenACCClauseKind::Wait &&
723 "Parsed clause kind does not have a wait-details");
724 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)};
725 }
726
728 assert((ClauseKind == OpenACCClauseKind::DeviceType ||
729 ClauseKind == OpenACCClauseKind::DType) &&
730 "Only 'device_type'/'dtype' has a device-type-arg list");
731 Details = DeviceTypeDetails{std::move(Archs)};
732 }
733
734 void setCollapseDetails(bool IsForce, Expr *LoopCount) {
735 assert(ClauseKind == OpenACCClauseKind::Collapse &&
736 "Only 'collapse' has collapse details");
737 Details = CollapseDetails{IsForce, LoopCount};
738 }
739
741 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
742 Arg) {
743 assert(ClauseKind == OpenACCClauseKind::Bind &&
744 "Only 'bind' has bind details");
745 Details = BindDetails{Arg};
746 }
747 };
748
749 SemaOpenACC(Sema &S);
750
751 // Called when we encounter a 'while' statement, before looking at its 'body'.
752 void ActOnWhileStmt(SourceLocation WhileLoc);
753 // Called when we encounter a 'do' statement, before looking at its 'body'.
754 void ActOnDoStmt(SourceLocation DoLoc);
755 // Called when we encounter a 'for' statement, before looking at its 'body',
756 // for the 'range-for'. 'ActOnForStmtEnd' is used after the body.
757 void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor,
758 const Stmt *RangeFor);
759 void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *RangeFor);
760 // Called when we encounter a 'for' statement, before looking at its 'body'.
761 // 'ActOnForStmtEnd' is used after the body.
762 void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First,
763 const Stmt *Second, const Stmt *Third);
764 void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst,
765 const Stmt *First, const Stmt *OldSecond,
766 const Stmt *Second, const Stmt *OldThird,
767 const Stmt *Third);
768 // Called when we encounter a 'for' statement, after we've consumed/checked
769 // the body. This is necessary for a number of checks on the contents of the
770 // 'for' statement.
771 void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body);
772
773 /// Called after parsing an OpenACC Clause so that it can be checked.
774 OpenACCClause *ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
775 OpenACCParsedClause &Clause);
776
777 /// Called after the construct has been parsed, but clauses haven't been
778 /// parsed. This allows us to diagnose not-implemented, as well as set up any
779 /// state required for parsing the clauses.
780 void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc);
781
782 /// Called after the directive, including its clauses, have been parsed and
783 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
784 /// happen before any associated declarations or statements have been parsed.
785 /// This function is only called when we are parsing a 'statement' context.
786 bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
788
789 /// Called after the directive, including its clauses, have been parsed and
790 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
791 /// happen before any associated declarations or statements have been parsed.
792 /// This function is only called when we are parsing a 'Decl' context.
793 bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
795 /// Called when we encounter an associated statement for our construct, this
796 /// should check legality of the statement as it appertains to this Construct.
797 StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc,
799 OpenACCAtomicKind AtKind,
801 StmtResult AssocStmt);
802
806 StmtResult AssocStmt) {
807 return ActOnAssociatedStmt(DirectiveLoc, K, OpenACCAtomicKind::None,
808 Clauses, AssocStmt);
809 }
810 /// Called to check the form of the `atomic` construct which has some fairly
811 /// sizable restrictions.
812 StmtResult CheckAtomicAssociatedStmt(SourceLocation AtomicDirLoc,
813 OpenACCAtomicKind AtKind,
814 StmtResult AssocStmt);
815
816 /// Called after the directive has been completely parsed, including the
817 /// declaration group or associated statement.
818 /// DirLoc: Location of the actual directive keyword.
819 /// LParenLoc: Location of the left paren, if it exists (not on all
820 /// constructs).
821 /// MiscLoc: First misc location, if necessary (not all constructs).
822 /// Exprs: List of expressions on the construct itself, if necessary (not all
823 /// constructs).
824 /// FuncRef: used only for Routine, this is the function being referenced.
825 /// AK: The atomic kind of the directive, if necessary (atomic only)
826 /// RParenLoc: Location of the right paren, if it exists (not on all
827 /// constructs).
828 /// EndLoc: The last source location of the driective.
829 /// Clauses: The list of clauses for the directive, if present.
830 /// AssocStmt: The associated statement for this construct, if necessary.
831 StmtResult ActOnEndStmtDirective(
833 SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
834 OpenACCAtomicKind AK, SourceLocation RParenLoc, SourceLocation EndLoc,
835 ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt);
836
837 /// Called after the directive has been completely parsed, including the
838 /// declaration group or associated statement.
840 ActOnEndDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
841 SourceLocation DirLoc, SourceLocation LParenLoc,
842 SourceLocation RParenLoc, SourceLocation EndLoc,
844
845 // Helper functions for ActOnEndRoutine*Directive, which does all the checking
846 // given the proper list of declarations.
847 void CheckRoutineDecl(SourceLocation DirLoc,
849 Decl *NextParsedDecl);
850 OpenACCRoutineDecl *CheckRoutineDecl(SourceLocation StartLoc,
851 SourceLocation DirLoc,
852 SourceLocation LParenLoc, Expr *FuncRef,
853 SourceLocation RParenLoc,
855 SourceLocation EndLoc);
856 OpenACCRoutineDeclAttr *
857 mergeRoutineDeclAttr(const OpenACCRoutineDeclAttr &Old);
859 ActOnEndRoutineDeclDirective(SourceLocation StartLoc, SourceLocation DirLoc,
860 SourceLocation LParenLoc, Expr *ReferencedFunc,
861 SourceLocation RParenLoc,
863 SourceLocation EndLoc, DeclGroupPtrTy NextDecl);
865 ActOnEndRoutineStmtDirective(SourceLocation StartLoc, SourceLocation DirLoc,
866 SourceLocation LParenLoc, Expr *ReferencedFunc,
867 SourceLocation RParenLoc,
869 SourceLocation EndLoc, Stmt *NextStmt);
870
871 /// Called when encountering an 'int-expr' for OpenACC, and manages
872 /// conversions and diagnostics to 'int'.
874 SourceLocation Loc, Expr *IntExpr);
875
876 /// Called right before a 'var' is parsed, so we can set the state for parsing
877 /// a 'cache' var.
878 void ActOnStartParseVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK);
879 /// Called only if the parse of a 'var' was invalid, else 'ActOnVar' should be
880 /// called.
881 void ActOnInvalidParseVar();
882 /// Called when encountering a 'var' for OpenACC, ensures it is actually a
883 /// declaration reference to a variable of the correct type.
885 Expr *VarExpr);
886 /// Helper function called by ActonVar that is used to check a 'cache' var.
887 ExprResult ActOnCacheVar(Expr *VarExpr);
888 /// Function called when a variable declarator is created, which lets us
889 /// implement the 'routine' 'function static variables' restriction.
890 void ActOnVariableDeclarator(VarDecl *VD);
891 /// Called when a function decl is created, which lets us implement the
892 /// 'routine' 'doesn't match next thing' warning.
893 void ActOnFunctionDeclarator(FunctionDecl *FD);
894 /// Called when a variable is initialized, so we can implement the 'routine
895 /// 'doesn't match the next thing' warning for lambda init.
896 void ActOnVariableInit(VarDecl *VD, QualType InitType);
897
898 // Called after 'ActOnVar' specifically for a 'link' clause, which has to do
899 // some minor additional checks.
900 llvm::SmallVector<Expr *> CheckLinkClauseVarList(ArrayRef<Expr *> VarExpr);
901
902 // Checking for the arguments specific to the declare-clause that need to be
903 // checked during both phases of template translation.
904 bool CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause,
906
907 ExprResult ActOnRoutineName(Expr *RoutineName);
908
909 /// Called while semantically analyzing the reduction clause, ensuring the var
910 /// is the correct kind of reference.
911 ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
912 OpenACCReductionOperator ReductionOp,
913 Expr *VarExpr);
914
915 /// Called to check the 'var' type is a variable of pointer type, necessary
916 /// for 'deviceptr' and 'attach' clauses. Returns true on success.
917 bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr);
918
919 /// Checks and creates an Array Section used in an OpenACC construct/clause.
920 ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
921 Expr *LowerBound,
922 SourceLocation ColonLocFirst, Expr *Length,
923 SourceLocation RBLoc);
924 /// Checks the loop depth value for a collapse clause.
925 ExprResult CheckCollapseLoopCount(Expr *LoopCount);
926 /// Checks a single size expr for a tile clause.
927 ExprResult CheckTileSizeExpr(Expr *SizeExpr);
928
929 // Check a single expression on a gang clause.
930 ExprResult CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses,
932 Expr *E);
933
934 // Called when a declaration is referenced, so that we can make sure certain
935 // clauses don't do the 'wrong' thing/have incorrect references.
936 void CheckDeclReference(SourceLocation Loc, Expr *E, Decl *D);
937
938 // Does the checking for a 'gang' clause that needs to be done in dependent
939 // and not dependent cases.
941 CheckGangClause(OpenACCDirectiveKind DirKind,
942 ArrayRef<const OpenACCClause *> ExistingClauses,
943 SourceLocation BeginLoc, SourceLocation LParenLoc,
945 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
946 // Does the checking for a 'reduction ' clause that needs to be done in
947 // dependent and not dependent cases.
948 OpenACCClause *CheckReductionClause(
949 ArrayRef<const OpenACCClause *> ExistingClauses,
950 OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc,
951 SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp,
953 SourceLocation EndLoc);
954
955 ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc);
956 ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc);
957
958 /// Helper type to restore the state of various 'loop' constructs when we run
959 /// into a loop (for, etc) inside the construct.
961 SemaOpenACC &SemaRef;
962 LoopCheckingInfo OldLoopInfo;
963 CollapseCheckingInfo OldCollapseInfo;
964 TileCheckingInfo OldTileInfo;
965 bool PreserveDepth;
966
967 public:
968 LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth = true)
969 : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
970 OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
971 PreserveDepth(PreserveDepth) {}
973 // The associated-statement level of this should NOT preserve this, as it
974 // is a new construct, but other loop uses need to preserve the depth so
975 // it makes it to the 'top level' for diagnostics.
976 bool CollapseDepthSatisified =
977 PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
978 : OldCollapseInfo.CollapseDepthSatisfied;
979 bool TileDepthSatisfied = PreserveDepth
980 ? SemaRef.TileInfo.TileDepthSatisfied
981 : OldTileInfo.TileDepthSatisfied;
982 bool CurLevelHasLoopAlready =
983 PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
984 : OldLoopInfo.CurLevelHasLoopAlready;
985
986 SemaRef.LoopInfo = OldLoopInfo;
987 SemaRef.CollapseInfo = OldCollapseInfo;
988 SemaRef.TileInfo = OldTileInfo;
989
990 SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
991 SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
992 SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
993 }
994 };
995
996 /// Helper type for the registration/assignment of constructs that need to
997 /// 'know' about their parent constructs and hold a reference to them, such as
998 /// Loop needing its parent construct.
1000 SemaOpenACC &SemaRef;
1001 ComputeConstructInfo OldActiveComputeConstructInfo;
1002 OpenACCDirectiveKind DirKind;
1003 LoopGangOnKernelTy OldLoopGangClauseOnKernel;
1004 SourceLocation OldLoopWorkerClauseLoc;
1005 SourceLocation OldLoopVectorClauseLoc;
1006 LoopWithoutSeqCheckingInfo OldLoopWithoutSeqInfo;
1007 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses;
1008 LoopInConstructRAII LoopRAII;
1009
1010 public:
1015 ArrayRef<const OpenACCClause *> UnInstClauses,
1018 ArrayRef<const OpenACCClause *> UnInstClauses,
1021 };
1022};
1023
1024} // namespace clang
1025
1026#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:1999
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
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition SemaBase.cpp:61
SemaBase(Sema &S)
Definition SemaBase.cpp:7
Sema & SemaRef
Definition SemaBase.h:40
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:8980
Represents a variable declaration or definition.
Definition Decl.h:925
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:865
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,...