clang 24.0.0git
OpenACCClause.h
Go to the documentation of this file.
1//===- OpenACCClause.h - Classes for OpenACC clauses ------------*- C++ -*-===//
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//
9// \file
10// This file defines OpenACC AST classes for clauses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_OPENACCCLAUSE_H
15#define LLVM_CLANG_AST_OPENACCCLAUSE_H
16
20#include "llvm/ADT/STLExtras.h"
21
22#include <utility>
23#include <variant>
24
25namespace clang {
26/// This is the base type for all OpenACC Clauses.
29 SourceRange Location;
30
31protected:
33 SourceLocation EndLoc)
34 : Kind(K), Location(BeginLoc, EndLoc) {
35 assert(!BeginLoc.isInvalid() && !EndLoc.isInvalid() &&
36 "Begin and end location must be valid for OpenACCClause");
37 }
38
39public:
40 OpenACCClauseKind getClauseKind() const { return Kind; }
41 SourceLocation getBeginLoc() const { return Location.getBegin(); }
42 SourceLocation getEndLoc() const { return Location.getEnd(); }
43 SourceRange getSourceRange() const { return Location; }
44
45 static bool classof(const OpenACCClause *) { return true; }
46
49 using child_range = llvm::iterator_range<child_iterator>;
50 using const_child_range = llvm::iterator_range<const_child_iterator>;
51
54 return const_cast<OpenACCClause *>(this)->children();
55 }
56
57 virtual ~OpenACCClause() = default;
58};
59
60// Represents the 'auto' clause.
62protected:
65
66public:
67 static bool classof(const OpenACCClause *C) {
68 return C->getClauseKind() == OpenACCClauseKind::Auto;
69 }
70
71 static OpenACCAutoClause *
72 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
73
80};
81
82// Represents the 'finalize' clause.
84protected:
87
88public:
89 static bool classof(const OpenACCClause *C) {
90 return C->getClauseKind() == OpenACCClauseKind::Finalize;
91 }
92
94 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
95
102};
103
104// Represents the 'if_present' clause.
106protected:
109
110public:
111 static bool classof(const OpenACCClause *C) {
112 return C->getClauseKind() == OpenACCClauseKind::IfPresent;
113 }
114
116 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
117
124};
125
126// Represents the 'independent' clause.
128protected:
131
132public:
133 static bool classof(const OpenACCClause *C) {
134 return C->getClauseKind() == OpenACCClauseKind::Independent;
135 }
136
138 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
139
146};
147// Represents the 'seq' clause.
149protected:
151 : OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {}
152
153public:
154 static bool classof(const OpenACCClause *C) {
155 return C->getClauseKind() == OpenACCClauseKind::Seq;
156 }
157
158 static OpenACCSeqClause *
159 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
160
167};
168// Represents the 'nohost' clause.
170protected:
173
174public:
175 static bool classof(const OpenACCClause *C) {
176 return C->getClauseKind() == OpenACCClauseKind::NoHost;
177 }
178 static OpenACCNoHostClause *
179 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
180
187};
188
189/// Represents a clause that has a list of parameters.
191 /// Location of the '('.
192 SourceLocation LParenLoc;
193
194protected:
196 SourceLocation LParenLoc, SourceLocation EndLoc)
197 : OpenACCClause(K, BeginLoc, EndLoc), LParenLoc(LParenLoc) {}
198
199public:
200 static bool classof(const OpenACCClause *C);
201
202 SourceLocation getLParenLoc() const { return LParenLoc; }
203
210};
211
212class OpenACCBindClause final : public OpenACCClauseWithParams {
213 std::variant<const StringLiteral *, const IdentifierInfo *> Argument;
214
215 OpenACCBindClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
216 const clang::StringLiteral *SL, SourceLocation EndLoc)
218 EndLoc),
219 Argument(SL) {}
220 OpenACCBindClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
221 const IdentifierInfo *ID, SourceLocation EndLoc)
223 EndLoc),
224 Argument(ID) {}
225
226public:
227 static bool classof(const OpenACCClause *C) {
228 return C->getClauseKind() == OpenACCClauseKind::Bind;
229 }
230 static OpenACCBindClause *Create(const ASTContext &C, SourceLocation BeginLoc,
231 SourceLocation LParenLoc,
232 const IdentifierInfo *ID,
233 SourceLocation EndLoc);
234 static OpenACCBindClause *Create(const ASTContext &C, SourceLocation BeginLoc,
235 SourceLocation LParenLoc,
236 const StringLiteral *SL,
237 SourceLocation EndLoc);
238
239 bool isStringArgument() const {
240 return std::holds_alternative<const StringLiteral *>(Argument);
241 }
242
244 return std::get<const StringLiteral *>(Argument);
245 }
246
247 bool isIdentifierArgument() const {
248 return std::holds_alternative<const IdentifierInfo *>(Argument);
249 }
250
252 return std::get<const IdentifierInfo *>(Argument);
253 }
254};
255
256bool operator==(const OpenACCBindClause &LHS, const OpenACCBindClause &RHS);
257inline bool operator!=(const OpenACCBindClause &LHS,
258 const OpenACCBindClause &RHS) {
259 return !(LHS == RHS);
260}
261
263/// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or
264/// an identifier. The 'asterisk' means 'the rest'.
265class OpenACCDeviceTypeClause final
267 private llvm::TrailingObjects<OpenACCDeviceTypeClause,
268 DeviceTypeArgument> {
269 friend TrailingObjects;
270 // Data stored in trailing objects as IdentifierInfo* /SourceLocation pairs. A
271 // nullptr IdentifierInfo* represents an asterisk.
272 unsigned NumArchs;
273 OpenACCDeviceTypeClause(OpenACCClauseKind K, SourceLocation BeginLoc,
274 SourceLocation LParenLoc,
276 SourceLocation EndLoc)
277 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
278 NumArchs(Archs.size()) {
279 assert(
281 "Invalid clause kind for device-type");
282
283 assert(!llvm::any_of(Archs, [](const DeviceTypeArgument &Arg) {
284 return Arg.getLoc().isInvalid();
285 }) && "Invalid SourceLocation for an argument");
286
287 assert((Archs.size() == 1 ||
288 !llvm::any_of(Archs,
289 [](const DeviceTypeArgument &Arg) {
290 return Arg.getIdentifierInfo() == nullptr;
291 })) &&
292 "Only a single asterisk version is permitted, and must be the "
293 "only one");
294
295 llvm::uninitialized_copy(Archs, getTrailingObjects());
296 }
297
298public:
299 static bool classof(const OpenACCClause *C) {
300 return C->getClauseKind() == OpenACCClauseKind::DType ||
301 C->getClauseKind() == OpenACCClauseKind::DeviceType;
302 }
303 bool hasAsterisk() const {
304 return getArchitectures().size() > 0 &&
305 getArchitectures()[0].getIdentifierInfo() == nullptr;
306 }
307
309 return getTrailingObjects(NumArchs);
310 }
311
315 SourceLocation EndLoc);
316};
317
318/// A 'default' clause, has the optional 'none' or 'present' argument.
320 OpenACCDefaultClauseKind DefaultClauseKind;
321
322protected:
324 SourceLocation LParenLoc, SourceLocation EndLoc)
325 : OpenACCClauseWithParams(OpenACCClauseKind::Default, BeginLoc, LParenLoc,
326 EndLoc),
327 DefaultClauseKind(K) {
328 assert((DefaultClauseKind == OpenACCDefaultClauseKind::None ||
329 DefaultClauseKind == OpenACCDefaultClauseKind::Present) &&
330 "Invalid Clause Kind");
331 }
332
333public:
334 static bool classof(const OpenACCClause *C) {
335 return C->getClauseKind() == OpenACCClauseKind::Default;
336 }
338 return DefaultClauseKind;
339 }
340
343 SourceLocation BeginLoc,
344 SourceLocation LParenLoc,
345 SourceLocation EndLoc);
346};
347
348/// Represents one of the handful of classes that has an optional/required
349/// 'condition' expression as an argument.
351 Expr *ConditionExpr = nullptr;
352
353protected:
355 SourceLocation LParenLoc, Expr *ConditionExpr,
356 SourceLocation EndLoc)
357 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
358 ConditionExpr(ConditionExpr) {}
359
360public:
361 static bool classof(const OpenACCClause *C);
362
363 bool hasConditionExpr() const { return ConditionExpr; }
364 const Expr *getConditionExpr() const { return ConditionExpr; }
365 Expr *getConditionExpr() { return ConditionExpr; }
366
368 if (ConditionExpr)
369 return child_range(reinterpret_cast<Stmt **>(&ConditionExpr),
370 reinterpret_cast<Stmt **>(&ConditionExpr + 1));
372 }
373
375 if (ConditionExpr)
376 return const_child_range(
377 reinterpret_cast<Stmt *const *>(&ConditionExpr),
378 reinterpret_cast<Stmt *const *>(&ConditionExpr + 1));
380 }
381};
382
383/// An 'if' clause, which has a required condition expression.
385protected:
387 Expr *ConditionExpr, SourceLocation EndLoc);
388
389public:
390 static bool classof(const OpenACCClause *C) {
391 return C->getClauseKind() == OpenACCClauseKind::If;
392 }
393 static OpenACCIfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
394 SourceLocation LParenLoc, Expr *ConditionExpr,
395 SourceLocation EndLoc);
396};
397
398/// A 'self' clause, which has an optional condition expression, or, in the
399/// event of an 'update' directive, contains a 'VarList'.
400class OpenACCSelfClause final
402 private llvm::TrailingObjects<OpenACCSelfClause, Expr *> {
403 friend TrailingObjects;
404 // Holds whether this HAS a condition expression. Lacks a value if this is NOT
405 // a condition-expr self clause.
406 std::optional<bool> HasConditionExpr;
407 // Holds the number of stored expressions. In the case of a condition-expr
408 // self clause, this is expected to be ONE (and there to be 1 trailing
409 // object), whether or not that is null.
410 unsigned NumExprs;
411
412 OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
413 Expr *ConditionExpr, SourceLocation EndLoc);
414 OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
415 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
416
417 // Intentionally internal, meant to be an implementation detail of everything
418 // else. All non-internal uses should go through getConditionExpr/getVarList.
419 ArrayRef<Expr *> getExprs() const { return getTrailingObjects(NumExprs); }
420
421public:
422 static bool classof(const OpenACCClause *C) {
423 return C->getClauseKind() == OpenACCClauseKind::Self;
424 }
425
426 bool isConditionExprClause() const { return HasConditionExpr.has_value(); }
427 bool isVarListClause() const { return !isConditionExprClause(); }
428 bool isEmptySelfClause() const {
429 return (isConditionExprClause() && !hasConditionExpr()) ||
430 (!isConditionExprClause() && getVarList().empty());
431 }
432
433 bool hasConditionExpr() const {
434 assert(HasConditionExpr.has_value() &&
435 "VarList Self Clause asked about condition expression");
436 return *HasConditionExpr;
437 }
438
439 const Expr *getConditionExpr() const {
440 assert(HasConditionExpr.has_value() &&
441 "VarList Self Clause asked about condition expression");
442 assert(getExprs().size() == 1 &&
443 "ConditionExpr Self Clause with too many Exprs");
444 return getExprs()[0];
445 }
446
448 assert(HasConditionExpr.has_value() &&
449 "VarList Self Clause asked about condition expression");
450 assert(getExprs().size() == 1 &&
451 "ConditionExpr Self Clause with too many Exprs");
452 return getExprs()[0];
453 }
454
456 assert(!HasConditionExpr.has_value() &&
457 "Condition Expr self clause asked about var list");
458 return getExprs();
459 }
460
462 return child_range(
463 reinterpret_cast<Stmt **>(getTrailingObjects()),
464 reinterpret_cast<Stmt **>(getTrailingObjects() + NumExprs));
465 }
466
468 return const_cast<OpenACCSelfClause *>(this)->children();
469 }
470
471 static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
472 SourceLocation LParenLoc,
473 Expr *ConditionExpr, SourceLocation EndLoc);
474 static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
475 SourceLocation LParenLoc,
476 ArrayRef<Expr *> ConditionExpr,
477 SourceLocation EndLoc);
478};
479
480/// Represents a clause that has one or more expressions associated with it.
483
484protected:
486 SourceLocation LParenLoc, SourceLocation EndLoc)
487 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {}
488
489 /// Used only for initialization, the leaf class can initialize this to
490 /// trailing storage.
492 assert(Exprs.empty() && "Cannot change Exprs list");
493 Exprs = NewExprs;
494 }
495
496 /// Used only for initialization, the leaf class can initialize this to
497 /// trailing storage, and initialize the data in the trailing storage as well.
499 assert(NewStorage.size() == Exprs.size());
500 llvm::uninitialized_copy(Exprs, NewStorage.begin());
501 setExprs(NewStorage);
502 }
503
504 /// Gets the entire list of expressions, but leave it to the
505 /// individual clauses to expose this how they'd like.
506 ArrayRef<Expr *> getExprs() const { return Exprs; }
507
508public:
509 static bool classof(const OpenACCClause *C);
511 return child_range(reinterpret_cast<Stmt **>(Exprs.begin()),
512 reinterpret_cast<Stmt **>(Exprs.end()));
513 }
514
516 return const_cast<OpenACCClauseWithExprs *>(this)->children();
517 }
518};
519
520// Represents the 'devnum' and expressions lists for the 'wait' clause.
521class OpenACCWaitClause final
522 : public OpenACCClauseWithExprs,
523 private llvm::TrailingObjects<OpenACCWaitClause, Expr *> {
524 friend TrailingObjects;
525 SourceLocation QueuesLoc;
526 OpenACCWaitClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
527 Expr *DevNumExpr, SourceLocation QueuesLoc,
528 ArrayRef<Expr *> QueueIdExprs, SourceLocation EndLoc)
529 : OpenACCClauseWithExprs(OpenACCClauseKind::Wait, BeginLoc, LParenLoc,
530 EndLoc),
531 QueuesLoc(QueuesLoc) {
532 // The first element of the trailing storage is always the devnum expr,
533 // whether it is used or not.
534 auto *Exprs = getTrailingObjects();
535 llvm::uninitialized_copy(ArrayRef(DevNumExpr), Exprs);
536 llvm::uninitialized_copy(QueueIdExprs, Exprs + 1);
537 setExprs(getTrailingObjects(QueueIdExprs.size() + 1));
538 }
539
540public:
541 static bool classof(const OpenACCClause *C) {
542 return C->getClauseKind() == OpenACCClauseKind::Wait;
543 }
544 static OpenACCWaitClause *Create(const ASTContext &C, SourceLocation BeginLoc,
545 SourceLocation LParenLoc, Expr *DevNumExpr,
546 SourceLocation QueuesLoc,
547 ArrayRef<Expr *> QueueIdExprs,
548 SourceLocation EndLoc);
549
550 bool hasQueuesTag() const { return !QueuesLoc.isInvalid(); }
551 SourceLocation getQueuesLoc() const { return QueuesLoc; }
552 bool hasDevNumExpr() const { return getExprs()[0]; }
553 Expr *getDevNumExpr() const { return getExprs()[0]; }
555 return OpenACCClauseWithExprs::getExprs().drop_front();
556 }
557 // If this is a plain `wait` (no parens) this returns 'false'. Else Sema/Parse
558 // ensures we have at least one QueueId expression.
559 bool hasExprs() const { return getLParenLoc().isValid(); }
560};
561
562class OpenACCNumGangsClause final
563 : public OpenACCClauseWithExprs,
564 private llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> {
565 friend TrailingObjects;
566
567 OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
568 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc)
570 EndLoc) {
571 setExprs(getTrailingObjects(IntExprs.size()), IntExprs);
572 }
573
574public:
575 static bool classof(const OpenACCClause *C) {
576 return C->getClauseKind() == OpenACCClauseKind::NumGangs;
577 }
578 static OpenACCNumGangsClause *
579 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
580 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
581
585};
586
587class OpenACCTileClause final
588 : public OpenACCClauseWithExprs,
589 private llvm::TrailingObjects<OpenACCTileClause, Expr *> {
590 friend TrailingObjects;
591 OpenACCTileClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
592 ArrayRef<Expr *> SizeExprs, SourceLocation EndLoc)
593 : OpenACCClauseWithExprs(OpenACCClauseKind::Tile, BeginLoc, LParenLoc,
594 EndLoc) {
595 setExprs(getTrailingObjects(SizeExprs.size()), SizeExprs);
596 }
597
598public:
599 static bool classof(const OpenACCClause *C) {
600 return C->getClauseKind() == OpenACCClauseKind::Tile;
601 }
602 static OpenACCTileClause *Create(const ASTContext &C, SourceLocation BeginLoc,
603 SourceLocation LParenLoc,
604 ArrayRef<Expr *> SizeExprs,
605 SourceLocation EndLoc);
606
610};
611
612/// Represents one of a handful of clauses that have a single integer
613/// expression.
615 Expr *IntExpr;
616
617protected:
619 SourceLocation LParenLoc, Expr *IntExpr,
620 SourceLocation EndLoc)
621 : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc),
622 IntExpr(IntExpr) {
623 if (IntExpr)
624 setExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
625 }
626
627public:
628 static bool classof(const OpenACCClause *C);
629 bool hasIntExpr() const { return !getExprs().empty(); }
630 const Expr *getIntExpr() const {
631 return hasIntExpr() ? getExprs()[0] : nullptr;
632 }
633
634 Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; };
635};
636
638 : public OpenACCClauseWithExprs,
639 private llvm::TrailingObjects<OpenACCGangClause, Expr *, OpenACCGangKind> {
640 friend TrailingObjects;
641protected:
644 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
645
646 OpenACCGangKind getGangKind(unsigned I) const {
647 return getTrailingObjects<OpenACCGangKind>()[I];
648 }
649
650public:
651 static bool classof(const OpenACCClause *C) {
652 return C->getClauseKind() == OpenACCClauseKind::Gang;
653 }
654
655 size_t numTrailingObjects(OverloadToken<Expr *>) const {
656 return getNumExprs();
657 }
658
659 unsigned getNumExprs() const { return getExprs().size(); }
660 std::pair<OpenACCGangKind, const Expr *> getExpr(unsigned I) const {
661 return {getGangKind(I), getExprs()[I]};
662 }
663
665 for (unsigned I = 0; I < getNumExprs(); ++I) {
666 if (getGangKind(I) == GK)
667 return true;
668 }
669 return false;
670 }
671
672 static OpenACCGangClause *
673 Create(const ASTContext &Ctx, SourceLocation BeginLoc,
674 SourceLocation LParenLoc, ArrayRef<OpenACCGangKind> GangKinds,
675 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
676};
677
679protected:
681 Expr *IntExpr, SourceLocation EndLoc);
682
683public:
684 static bool classof(const OpenACCClause *C) {
685 return C->getClauseKind() == OpenACCClauseKind::Worker;
686 }
687
688 static OpenACCWorkerClause *Create(const ASTContext &Ctx,
689 SourceLocation BeginLoc,
690 SourceLocation LParenLoc, Expr *IntExpr,
691 SourceLocation EndLoc);
692};
693
695protected:
697 Expr *IntExpr, SourceLocation EndLoc);
698
699public:
700 static bool classof(const OpenACCClause *C) {
701 return C->getClauseKind() == OpenACCClauseKind::Vector;
702 }
703
704 static OpenACCVectorClause *Create(const ASTContext &Ctx,
705 SourceLocation BeginLoc,
706 SourceLocation LParenLoc, Expr *IntExpr,
707 SourceLocation EndLoc);
708};
709
710class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
711 OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
712 Expr *IntExpr, SourceLocation EndLoc);
713
714public:
715 static bool classof(const OpenACCClause *C) {
716 return C->getClauseKind() == OpenACCClauseKind::NumWorkers;
717 }
719 SourceLocation BeginLoc,
720 SourceLocation LParenLoc,
721 Expr *IntExpr, SourceLocation EndLoc);
722};
723
724class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr {
725 OpenACCVectorLengthClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
726 Expr *IntExpr, SourceLocation EndLoc);
727
728public:
729 static bool classof(const OpenACCClause *C) {
730 return C->getClauseKind() == OpenACCClauseKind::VectorLength;
731 }
733 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
734 Expr *IntExpr, SourceLocation EndLoc);
735};
736
737class OpenACCAsyncClause : public OpenACCClauseWithSingleIntExpr {
738 OpenACCAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
739 Expr *IntExpr, SourceLocation EndLoc);
740
741public:
742 static bool classof(const OpenACCClause *C) {
743 return C->getClauseKind() == OpenACCClauseKind::Async;
744 }
745 static OpenACCAsyncClause *Create(const ASTContext &C,
746 SourceLocation BeginLoc,
747 SourceLocation LParenLoc, Expr *IntExpr,
748 SourceLocation EndLoc);
749};
750
751class OpenACCDeviceNumClause : public OpenACCClauseWithSingleIntExpr {
752 OpenACCDeviceNumClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
753 Expr *IntExpr, SourceLocation EndLoc);
754
755public:
756 static bool classof(const OpenACCClause *C) {
757 return C->getClauseKind() == OpenACCClauseKind::DeviceNum;
758 }
760 SourceLocation BeginLoc,
761 SourceLocation LParenLoc, Expr *IntExpr,
762 SourceLocation EndLoc);
763};
764
765class OpenACCDefaultAsyncClause : public OpenACCClauseWithSingleIntExpr {
766 OpenACCDefaultAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
767 Expr *IntExpr, SourceLocation EndLoc);
768
769public:
770 static bool classof(const OpenACCClause *C) {
771 return C->getClauseKind() == OpenACCClauseKind::DefaultAsync;
772 }
774 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
775 Expr *IntExpr, SourceLocation EndLoc);
776};
777
778/// Represents a 'collapse' clause on a 'loop' construct. This clause takes an
779/// integer constant expression 'N' that represents how deep to collapse the
780/// construct. It also takes an optional 'force' tag that permits intervening
781/// code in the loops.
782class OpenACCCollapseClause : public OpenACCClauseWithSingleIntExpr {
783 bool HasForce = false;
784
785 OpenACCCollapseClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
786 bool HasForce, Expr *LoopCount, SourceLocation EndLoc);
787
788public:
789 const Expr *getLoopCount() const { return getIntExpr(); }
790 Expr *getLoopCount() { return getIntExpr(); }
791
792 bool hasForce() const { return HasForce; }
793
794 static bool classof(const OpenACCClause *C) {
795 return C->getClauseKind() == OpenACCClauseKind::Collapse;
796 }
797
799 SourceLocation BeginLoc,
800 SourceLocation LParenLoc, bool HasForce,
801 Expr *LoopCount, SourceLocation EndLoc);
802};
803
804/// Represents a clause with one or more 'var' objects, represented as an expr,
805/// as its arguments. Var-list is expected to be stored in trailing storage.
806/// For now, we're just storing the original expression in its entirety, unlike
807/// OMP which has to do a bunch of work to create a private.
809protected:
811 SourceLocation LParenLoc, SourceLocation EndLoc)
812 : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {}
813
814public:
815 static bool classof(const OpenACCClause *C);
817};
818
819// Represents all the data needed for recipe generation. The declaration and
820// init are stored separately, because in the case of subscripts, we do the
821// alloca at the level of the base, and the init at the element level.
824
826
827 bool isSet() const { return AllocaDecl; }
828
830 return OpenACCPrivateRecipe(/*AllocaDecl=*/nullptr);
831 }
832};
833
834class OpenACCPrivateClause final
836 private llvm::TrailingObjects<OpenACCPrivateClause, Expr *,
837 OpenACCPrivateRecipe> {
838 friend TrailingObjects;
839
840 OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
841 ArrayRef<Expr *> VarList,
843 SourceLocation EndLoc)
845 LParenLoc, EndLoc) {
846 assert(VarList.size() == InitRecipes.size());
847 setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList);
848 llvm::uninitialized_copy(InitRecipes,
849 getTrailingObjects<OpenACCPrivateRecipe>());
850 }
851
852public:
853 static bool classof(const OpenACCClause *C) {
854 return C->getClauseKind() == OpenACCClauseKind::Private;
855 }
856 // Gets a list of 'made up' `VarDecl` objects that can be used by codegen to
857 // ensure that we properly initialize each of these variables.
860 getTrailingObjects<OpenACCPrivateRecipe>(), getExprs().size()};
861 }
862
863 static OpenACCPrivateClause *
864 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
866 SourceLocation EndLoc);
867
868 size_t numTrailingObjects(OverloadToken<Expr *>) const {
869 return getExprs().size();
870 }
871};
872
873// A 'pair' to stand in for the recipe. RecipeDecl is the main declaration, and
874// InitFromTemporary is the 'temp' declaration we put in to be 'copied from'.
880 assert(!InitFromTemporary || InitFromTemporary->getInit() == nullptr);
881 }
882
883 bool isSet() const { return AllocaDecl; }
884
886 return OpenACCFirstPrivateRecipe(/*AllocaDecl=*/nullptr,
887 /*InitFromTemporary=*/nullptr);
888 }
889};
890
891class OpenACCFirstPrivateClause final
893 private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *,
894 OpenACCFirstPrivateRecipe> {
895 friend TrailingObjects;
896
897 OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
898 ArrayRef<Expr *> VarList,
900 SourceLocation EndLoc)
902 LParenLoc, EndLoc) {
903 assert(VarList.size() == InitRecipes.size());
904 setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList);
905 llvm::uninitialized_copy(InitRecipes,
906 getTrailingObjects<OpenACCFirstPrivateRecipe>());
907 }
908
909public:
910 static bool classof(const OpenACCClause *C) {
911 return C->getClauseKind() == OpenACCClauseKind::FirstPrivate;
912 }
913
914 // Gets a list of 'made up' `VarDecl` objects that can be used by codegen to
915 // ensure that we properly initialize each of these variables.
918 getTrailingObjects<OpenACCFirstPrivateRecipe>(), getExprs().size()};
919 }
920
922 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
923 ArrayRef<Expr *> VarList,
925 SourceLocation EndLoc);
926
927 size_t numTrailingObjects(OverloadToken<Expr *>) const {
928 return getExprs().size();
929 }
930};
931
932class OpenACCDevicePtrClause final
934 private llvm::TrailingObjects<OpenACCDevicePtrClause, Expr *> {
935 friend TrailingObjects;
936
937 OpenACCDevicePtrClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
938 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
940 LParenLoc, EndLoc) {
941 setExprs(getTrailingObjects(VarList.size()), VarList);
942 }
943
944public:
945 static bool classof(const OpenACCClause *C) {
946 return C->getClauseKind() == OpenACCClauseKind::DevicePtr;
947 }
949 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
950 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
951};
952
953class OpenACCAttachClause final
955 private llvm::TrailingObjects<OpenACCAttachClause, Expr *> {
956 friend TrailingObjects;
957
958 OpenACCAttachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
959 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
961 EndLoc) {
962 setExprs(getTrailingObjects(VarList.size()), VarList);
963 }
964
965public:
966 static bool classof(const OpenACCClause *C) {
967 return C->getClauseKind() == OpenACCClauseKind::Attach;
968 }
969 static OpenACCAttachClause *
970 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
971 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
972};
973
974class OpenACCDetachClause final
976 private llvm::TrailingObjects<OpenACCDetachClause, Expr *> {
977 friend TrailingObjects;
978
979 OpenACCDetachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
980 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
982 EndLoc) {
983 setExprs(getTrailingObjects(VarList.size()), VarList);
984 }
985
986public:
987 static bool classof(const OpenACCClause *C) {
988 return C->getClauseKind() == OpenACCClauseKind::Detach;
989 }
990 static OpenACCDetachClause *
991 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
992 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
993};
994
995class OpenACCDeleteClause final
997 private llvm::TrailingObjects<OpenACCDeleteClause, Expr *> {
998 friend TrailingObjects;
999
1000 OpenACCDeleteClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1001 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1003 EndLoc) {
1004 setExprs(getTrailingObjects(VarList.size()), VarList);
1005 }
1006
1007public:
1008 static bool classof(const OpenACCClause *C) {
1009 return C->getClauseKind() == OpenACCClauseKind::Delete;
1010 }
1011 static OpenACCDeleteClause *
1012 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1013 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1014};
1015
1016class OpenACCUseDeviceClause final
1017 : public OpenACCClauseWithVarList,
1018 private llvm::TrailingObjects<OpenACCUseDeviceClause, Expr *> {
1019 friend TrailingObjects;
1020
1021 OpenACCUseDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1022 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1024 LParenLoc, EndLoc) {
1025 setExprs(getTrailingObjects(VarList.size()), VarList);
1026 }
1027
1028public:
1029 static bool classof(const OpenACCClause *C) {
1030 return C->getClauseKind() == OpenACCClauseKind::UseDevice;
1031 }
1032 static OpenACCUseDeviceClause *
1033 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1034 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1035};
1036
1037class OpenACCNoCreateClause final
1038 : public OpenACCClauseWithVarList,
1039 private llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {
1040 friend TrailingObjects;
1041
1042 OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1043 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1045 LParenLoc, EndLoc) {
1046 setExprs(getTrailingObjects(VarList.size()), VarList);
1047 }
1048
1049public:
1050 static bool classof(const OpenACCClause *C) {
1051 return C->getClauseKind() == OpenACCClauseKind::NoCreate;
1052 }
1053 static OpenACCNoCreateClause *
1054 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1055 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1056};
1057
1058class OpenACCPresentClause final
1059 : public OpenACCClauseWithVarList,
1060 private llvm::TrailingObjects<OpenACCPresentClause, Expr *> {
1061 friend TrailingObjects;
1062
1063 OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1064 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1066 LParenLoc, EndLoc) {
1067 setExprs(getTrailingObjects(VarList.size()), VarList);
1068 }
1069
1070public:
1071 static bool classof(const OpenACCClause *C) {
1072 return C->getClauseKind() == OpenACCClauseKind::Present;
1073 }
1074 static OpenACCPresentClause *
1075 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1076 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1077};
1078class OpenACCHostClause final
1079 : public OpenACCClauseWithVarList,
1080 private llvm::TrailingObjects<OpenACCHostClause, Expr *> {
1081 friend TrailingObjects;
1082
1083 OpenACCHostClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1084 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1086 EndLoc) {
1087 setExprs(getTrailingObjects(VarList.size()), VarList);
1088 }
1089
1090public:
1091 static bool classof(const OpenACCClause *C) {
1092 return C->getClauseKind() == OpenACCClauseKind::Host;
1093 }
1094 static OpenACCHostClause *Create(const ASTContext &C, SourceLocation BeginLoc,
1095 SourceLocation LParenLoc,
1096 ArrayRef<Expr *> VarList,
1097 SourceLocation EndLoc);
1098};
1099
1100class OpenACCDeviceClause final
1101 : public OpenACCClauseWithVarList,
1102 private llvm::TrailingObjects<OpenACCDeviceClause, Expr *> {
1103 friend TrailingObjects;
1104
1105 OpenACCDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1106 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1108 EndLoc) {
1109 setExprs(getTrailingObjects(VarList.size()), VarList);
1110 }
1111
1112public:
1113 static bool classof(const OpenACCClause *C) {
1114 return C->getClauseKind() == OpenACCClauseKind::Device;
1115 }
1116 static OpenACCDeviceClause *
1117 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1118 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1119};
1120
1121class OpenACCCopyClause final
1122 : public OpenACCClauseWithVarList,
1123 private llvm::TrailingObjects<OpenACCCopyClause, Expr *> {
1124 friend TrailingObjects;
1125 OpenACCModifierKind Modifiers;
1126
1127 OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1128 SourceLocation LParenLoc, OpenACCModifierKind Mods,
1129 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1130 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1131 Modifiers(Mods) {
1132 assert((Spelling == OpenACCClauseKind::Copy ||
1133 Spelling == OpenACCClauseKind::PCopy ||
1134 Spelling == OpenACCClauseKind::PresentOrCopy) &&
1135 "Invalid clause kind for copy-clause");
1136 setExprs(getTrailingObjects(VarList.size()), VarList);
1137 }
1138
1139public:
1140 static bool classof(const OpenACCClause *C) {
1141 return C->getClauseKind() == OpenACCClauseKind::Copy ||
1142 C->getClauseKind() == OpenACCClauseKind::PCopy ||
1143 C->getClauseKind() == OpenACCClauseKind::PresentOrCopy;
1144 }
1145 static OpenACCCopyClause *
1146 Create(const ASTContext &C, OpenACCClauseKind Spelling,
1147 SourceLocation BeginLoc, SourceLocation LParenLoc,
1149 SourceLocation EndLoc);
1150
1151 OpenACCModifierKind getModifierList() const { return Modifiers; }
1152};
1153
1154class OpenACCCopyInClause final
1155 : public OpenACCClauseWithVarList,
1156 private llvm::TrailingObjects<OpenACCCopyInClause, Expr *> {
1157 friend TrailingObjects;
1158 OpenACCModifierKind Modifiers;
1159
1160 OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1161 SourceLocation LParenLoc, OpenACCModifierKind Mods,
1162 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1163 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1164 Modifiers(Mods) {
1165 assert((Spelling == OpenACCClauseKind::CopyIn ||
1166 Spelling == OpenACCClauseKind::PCopyIn ||
1168 "Invalid clause kind for copyin-clause");
1169 setExprs(getTrailingObjects(VarList.size()), VarList);
1170 }
1171
1172public:
1173 static bool classof(const OpenACCClause *C) {
1174 return C->getClauseKind() == OpenACCClauseKind::CopyIn ||
1175 C->getClauseKind() == OpenACCClauseKind::PCopyIn ||
1176 C->getClauseKind() == OpenACCClauseKind::PresentOrCopyIn;
1177 }
1178 OpenACCModifierKind getModifierList() const { return Modifiers; }
1179 static OpenACCCopyInClause *
1180 Create(const ASTContext &C, OpenACCClauseKind Spelling,
1181 SourceLocation BeginLoc, SourceLocation LParenLoc,
1183 SourceLocation EndLoc);
1184};
1185
1186class OpenACCCopyOutClause final
1187 : public OpenACCClauseWithVarList,
1188 private llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> {
1189 friend TrailingObjects;
1190 OpenACCModifierKind Modifiers;
1191
1192 OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1193 SourceLocation LParenLoc, OpenACCModifierKind Mods,
1194 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1195 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1196 Modifiers(Mods) {
1197 assert((Spelling == OpenACCClauseKind::CopyOut ||
1198 Spelling == OpenACCClauseKind::PCopyOut ||
1200 "Invalid clause kind for copyout-clause");
1201 setExprs(getTrailingObjects(VarList.size()), VarList);
1202 }
1203
1204public:
1205 static bool classof(const OpenACCClause *C) {
1206 return C->getClauseKind() == OpenACCClauseKind::CopyOut ||
1207 C->getClauseKind() == OpenACCClauseKind::PCopyOut ||
1208 C->getClauseKind() == OpenACCClauseKind::PresentOrCopyOut;
1209 }
1210 OpenACCModifierKind getModifierList() const { return Modifiers; }
1211 static OpenACCCopyOutClause *
1212 Create(const ASTContext &C, OpenACCClauseKind Spelling,
1213 SourceLocation BeginLoc, SourceLocation LParenLoc,
1215 SourceLocation EndLoc);
1216};
1217
1218class OpenACCCreateClause final
1219 : public OpenACCClauseWithVarList,
1220 private llvm::TrailingObjects<OpenACCCreateClause, Expr *> {
1221 friend TrailingObjects;
1222 OpenACCModifierKind Modifiers;
1223
1224 OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1225 SourceLocation LParenLoc, OpenACCModifierKind Mods,
1226 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1227 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1228 Modifiers(Mods) {
1229 assert((Spelling == OpenACCClauseKind::Create ||
1230 Spelling == OpenACCClauseKind::PCreate ||
1232 "Invalid clause kind for create-clause");
1233 setExprs(getTrailingObjects(VarList.size()), VarList);
1234 }
1235
1236public:
1237 static bool classof(const OpenACCClause *C) {
1238 return C->getClauseKind() == OpenACCClauseKind::Create ||
1239 C->getClauseKind() == OpenACCClauseKind::PCreate ||
1240 C->getClauseKind() == OpenACCClauseKind::PresentOrCreate;
1241 }
1242 OpenACCModifierKind getModifierList() const { return Modifiers; }
1243 static OpenACCCreateClause *
1244 Create(const ASTContext &C, OpenACCClauseKind Spelling,
1245 SourceLocation BeginLoc, SourceLocation LParenLoc,
1247 SourceLocation EndLoc);
1248};
1249
1250// A structure to stand in for the recipe on a reduction. RecipeDecl is the
1251// 'main' declaration used for initializaiton, which is fixed.
1252struct OpenACCReductionRecipe {
1254
1255 // A combiner recipe is represented by an operation expression. However, in
1256 // order to generate these properly, we have to make up a LHS and a RHS
1257 // expression for the purposes of generation.
1263
1264 // Contains a collection of the recipe elements we need for the combiner:
1265 // -For Scalars, there will be 1 element, just the combiner for that scalar.
1266 // -For a struct with a valid operator, this will be 1 element, just that
1267 // call.
1268 // -For a struct without the operator, this will be 1 element per field, which
1269 // should be the combiner for that element.
1270 // -For an array of any of the above, it will be the above for the element.
1271 // Note: These are necessarily stored in either Trailing Storage (when in the
1272 // AST), or in a separate collection when being semantically analyzed.
1274
1275 bool isSet() const { return AllocaDecl; }
1276
1277private:
1279 OpenACCReductionRecipe(VarDecl *A, llvm::ArrayRef<CombinerRecipe> Combiners)
1280 : AllocaDecl(A), CombinerRecipes(Combiners) {}
1281};
1282
1283// A version of the above that is used for semantic analysis, at a time before
1284// the OpenACCReductionClause node has been created. This one has storage for
1285// the CombinerRecipe, since Trailing storage for it doesn't exist yet.
1299
1300class OpenACCReductionClause final
1301 : public OpenACCClauseWithVarList,
1302 private llvm::TrailingObjects<OpenACCReductionClause, Expr *,
1303 OpenACCReductionRecipe,
1304 OpenACCReductionRecipe::CombinerRecipe> {
1305 friend TrailingObjects;
1307
1308 OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1309 OpenACCReductionOperator Operator,
1310 ArrayRef<Expr *> VarList,
1312 SourceLocation EndLoc)
1314 LParenLoc, EndLoc),
1315 Op(Operator) {
1316 assert(VarList.size() == Recipes.size());
1317 setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList);
1318
1319 // Since we're using trailing storage on this node to store the 'combiner'
1320 // recipes of the Reduction Recipes (which have a 1:M relationship), we need
1321 // to ensure we get the ArrayRef of each of our combiner 'correct'.
1323 getTrailingObjects<OpenACCReductionRecipe::CombinerRecipe>();
1324 for (const auto &[Idx, R] : llvm::enumerate(Recipes)) {
1325
1326 // ArrayRef to the 'correct' data location in trailing storage.
1328 NewCombiners{CurCombinerLoc, R.CombinerRecipes.size()};
1329 CurCombinerLoc += R.CombinerRecipes.size();
1330
1331 llvm::uninitialized_copy(R.CombinerRecipes, NewCombiners.begin());
1332
1333 // Placement new into the correct location in trailng storage.
1334 new (&getTrailingObjects<OpenACCReductionRecipe>()[Idx])
1335 OpenACCReductionRecipe(R.AllocaDecl, NewCombiners);
1336 }
1337 }
1338
1339public:
1340 static bool classof(const OpenACCClause *C) {
1341 return C->getClauseKind() == OpenACCClauseKind::Reduction;
1342 }
1343
1346 getTrailingObjects<OpenACCReductionRecipe>(), getExprs().size()};
1347 }
1348
1349 static OpenACCReductionClause *
1350 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1353 SourceLocation EndLoc);
1354
1356
1357 size_t numTrailingObjects(OverloadToken<Expr *>) const {
1358 return getExprs().size();
1359 }
1360 size_t numTrailingObjects(OverloadToken<OpenACCReductionRecipe>) const {
1361 return getExprs().size();
1362 }
1363};
1364
1365class OpenACCLinkClause final
1366 : public OpenACCClauseWithVarList,
1367 private llvm::TrailingObjects<OpenACCLinkClause, Expr *> {
1368 friend TrailingObjects;
1369
1370 OpenACCLinkClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1371 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1373 EndLoc) {
1374 setExprs(getTrailingObjects(VarList.size()), VarList);
1375 }
1376
1377public:
1378 static bool classof(const OpenACCClause *C) {
1379 return C->getClauseKind() == OpenACCClauseKind::Link;
1380 }
1381
1382 static OpenACCLinkClause *Create(const ASTContext &C, SourceLocation BeginLoc,
1383 SourceLocation LParenLoc,
1384 ArrayRef<Expr *> VarList,
1385 SourceLocation EndLoc);
1386};
1387
1388class OpenACCDeviceResidentClause final
1389 : public OpenACCClauseWithVarList,
1390 private llvm::TrailingObjects<OpenACCDeviceResidentClause, Expr *> {
1391 friend TrailingObjects;
1392
1393 OpenACCDeviceResidentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1394 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1396 LParenLoc, EndLoc) {
1397 setExprs(getTrailingObjects(VarList.size()), VarList);
1398 }
1399
1400public:
1401 static bool classof(const OpenACCClause *C) {
1402 return C->getClauseKind() == OpenACCClauseKind::DeviceResident;
1403 }
1404
1406 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1407 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1408};
1409
1410template <class Impl> class OpenACCClauseVisitor {
1411 Impl &getDerived() { return static_cast<Impl &>(*this); }
1412
1413public:
1415 for (const OpenACCClause *Clause : List)
1416 Visit(Clause);
1417 }
1418
1419 void Visit(const OpenACCClause *C) {
1420 if (!C)
1421 return;
1422
1423 switch (C->getClauseKind()) {
1424#define VISIT_CLAUSE(CLAUSE_NAME) \
1425 case OpenACCClauseKind::CLAUSE_NAME: \
1426 getDerived().Visit##CLAUSE_NAME##Clause( \
1427 *cast<OpenACC##CLAUSE_NAME##Clause>(C)); \
1428 return;
1429#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \
1430 case OpenACCClauseKind::ALIAS_NAME: \
1431 getDerived().Visit##CLAUSE_NAME##Clause( \
1432 *cast<OpenACC##CLAUSE_NAME##Clause>(C)); \
1433 return;
1434#include "clang/Basic/OpenACCClauses.def"
1435
1436 default:
1437 llvm_unreachable("Clause visitor not yet implemented");
1438 }
1439 llvm_unreachable("Invalid Clause kind");
1440 }
1441
1442#define VISIT_CLAUSE(CLAUSE_NAME) \
1443 void Visit##CLAUSE_NAME##Clause( \
1444 const OpenACC##CLAUSE_NAME##Clause &Clause) { \
1445 return getDerived().VisitClause(Clause); \
1446 }
1447
1448#include "clang/Basic/OpenACCClauses.def"
1449};
1450
1452 : public OpenACCClauseVisitor<OpenACCClausePrinter> {
1453 raw_ostream &OS;
1454 const PrintingPolicy &Policy;
1455
1456 void printExpr(const Expr *E);
1457
1458public:
1460 for (const OpenACCClause *Clause : List) {
1461 Visit(Clause);
1462
1463 if (Clause != List.back())
1464 OS << ' ';
1465 }
1466 }
1467 OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
1468 : OS(OS), Policy(Policy) {}
1469
1470#define VISIT_CLAUSE(CLAUSE_NAME) \
1471 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
1472#include "clang/Basic/OpenACCClauses.def"
1473};
1474
1475} // namespace clang
1476
1477#endif // LLVM_CLANG_AST_OPENACCCLAUSE_H
Defines the clang::ASTContext interface.
Defines some OpenACC-specific enums and functions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
This represents one expression.
Definition Expr.h:114
One of these records is kept for each identifier that is lexed.
A simple pair of identifier info and location.
SourceLocation getLoc() const
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
const_child_range children() const
OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc)
static bool classof(const OpenACCClause *C)
const IdentifierInfo * getIdentifierArgument() const
const StringLiteral * getStringArgument() const
static bool classof(const OpenACCClause *C)
bool isIdentifierArgument() const
OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
void VisitClauseList(ArrayRef< const OpenACCClause * > List)
void Visit(const OpenACCClause *C)
void VisitClauseList(ArrayRef< const OpenACCClause * > List)
static bool classof(const OpenACCClause *C)
const Expr * getConditionExpr() const
OpenACCClauseWithCondition(OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
const_child_range children() const
void setExprs(MutableArrayRef< Expr * > NewStorage, ArrayRef< Expr * > Exprs)
Used only for initialization, the leaf class can initialize this to trailing storage,...
static bool classof(const OpenACCClause *C)
OpenACCClauseWithExprs(OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
ArrayRef< Expr * > getExprs() const
Gets the entire list of expressions, but leave it to the individual clauses to expose this how they'd...
const_child_range children() const
void setExprs(MutableArrayRef< Expr * > NewExprs)
Used only for initialization, the leaf class can initialize this to trailing storage.
SourceLocation getLParenLoc() const
static bool classof(const OpenACCClause *C)
OpenACCClauseWithParams(OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
const_child_range children() const
OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static bool classof(const OpenACCClause *C)
OpenACCClauseWithVarList(OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
static bool classof(const OpenACCClause *C)
ArrayRef< Expr * > getVarList() const
This is the base type for all OpenACC Clauses.
StmtIterator child_iterator
OpenACCClauseKind getClauseKind() const
SourceLocation getBeginLoc() const
SourceRange getSourceRange() const
const_child_range children() const
static bool classof(const OpenACCClause *)
llvm::iterator_range< child_iterator > child_range
ConstStmtIterator const_child_iterator
OpenACCClause(OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation EndLoc)
virtual ~OpenACCClause()=default
llvm::iterator_range< const_child_iterator > const_child_range
SourceLocation getEndLoc() const
Represents a 'collapse' clause on a 'loop' construct.
const Expr * getLoopCount() const
static bool classof(const OpenACCClause *C)
OpenACCModifierKind getModifierList() const
static bool classof(const OpenACCClause *C)
OpenACCModifierKind getModifierList() const
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
OpenACCModifierKind getModifierList() const
static bool classof(const OpenACCClause *C)
OpenACCModifierKind getModifierList() const
static bool classof(const OpenACCClause *C)
A 'default' clause, has the optional 'none' or 'present' argument.
OpenACCDefaultClause(OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OpenACCDefaultClauseKind getDefaultClauseKind() const
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or an identifier.
ArrayRef< DeviceTypeArgument > getArchitectures() const
static bool classof(const OpenACCClause *C)
OpenACCFinalizeClause(SourceLocation BeginLoc, SourceLocation EndLoc)
static bool classof(const OpenACCClause *C)
const_child_range children() const
size_t numTrailingObjects(OverloadToken< Expr * >) const
ArrayRef< OpenACCFirstPrivateRecipe > getInitRecipes() const
static bool classof(const OpenACCClause *C)
OpenACCGangKind getGangKind(unsigned I) const
bool hasExprOfKind(OpenACCGangKind GK) const
OpenACCGangClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
size_t numTrailingObjects(OverloadToken< Expr * >) const
static bool classof(const OpenACCClause *C)
unsigned getNumExprs() const
std::pair< OpenACCGangKind, const Expr * > getExpr(unsigned I) const
static bool classof(const OpenACCClause *C)
An 'if' clause, which has a required condition expression.
OpenACCIfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
const_child_range children() const
OpenACCIfPresentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
static bool classof(const OpenACCClause *C)
const_child_range children() const
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
OpenACCNoHostClause(SourceLocation BeginLoc, SourceLocation EndLoc)
static bool classof(const OpenACCClause *C)
const_child_range children() const
ArrayRef< Expr * > getIntExprs() const
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
size_t numTrailingObjects(OverloadToken< Expr * >) const
ArrayRef< OpenACCPrivateRecipe > getInitRecipes() const
ArrayRef< OpenACCReductionRecipe > getRecipes() const
size_t numTrailingObjects(OverloadToken< OpenACCReductionRecipe >) const
size_t numTrailingObjects(OverloadToken< Expr * >) const
static bool classof(const OpenACCClause *C)
OpenACCReductionOperator getReductionOp() const
A 'self' clause, which has an optional condition expression, or, in the event of an 'update' directiv...
const Expr * getConditionExpr() const
bool isConditionExprClause() const
const_child_range children() const
static bool classof(const OpenACCClause *C)
ArrayRef< Expr * > getVarList() const
static bool classof(const OpenACCClause *C)
const_child_range children() const
OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc)
ArrayRef< Expr * > getSizeExprs() const
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
Expr * getDevNumExpr() const
ArrayRef< Expr * > getQueueIdExprs() const
SourceLocation getQueuesLoc() const
static bool classof(const OpenACCClause *C)
static bool classof(const OpenACCClause *C)
OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition Stmt.h:85
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1844
Represents a variable declaration or definition.
Definition Decl.h:934
Top level wrappers for InstallAPI frontend operations.
OpenACCReductionOperator
OpenACCModifierKind
OpenACCClauseKind
Represents the kind of an OpenACC clause.
@ Auto
'auto' clause, allowed on 'loop' directives.
@ 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.
@ NoHost
'nohost' clause, allowed on 'routine' directives.
@ 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',...
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
@ 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.
@ Independent
'independent' clause, allowed on 'loop' directives.
@ NumWorkers
'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs...
@ IfPresent
'if_present' clause, allowed on 'host_data' and 'update' directives.
@ 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'.
@ Finalize
'finalize' clause, allowed on 'exit data' directive.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition CallGraph.h:218
OpenACCDefaultClauseKind
IdentifierLoc DeviceTypeArgument
@ Default
Set to the current date and time.
const FunctionProtoType * T
bool operator!=(CanQual< T > x, CanQual< U > y)
static OpenACCFirstPrivateRecipe Empty()
OpenACCFirstPrivateRecipe(VarDecl *A, VarDecl *T)
static OpenACCPrivateRecipe Empty()
OpenACCReductionRecipeWithStorage(VarDecl *A, llvm::ArrayRef< OpenACCReductionRecipe::CombinerRecipe > Combiners)
llvm::SmallVector< OpenACCReductionRecipe::CombinerRecipe, 1 > CombinerRecipes
static OpenACCReductionRecipeWithStorage Empty()
llvm::ArrayRef< CombinerRecipe > CombinerRecipes
Describes how types, statements, expressions, and declarations should be printed.