clang 22.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 friend class ASTReaderStmt;
321 friend class ASTWriterStmt;
322
323 OpenACCDefaultClauseKind DefaultClauseKind;
324
325protected:
327 SourceLocation LParenLoc, SourceLocation EndLoc)
328 : OpenACCClauseWithParams(OpenACCClauseKind::Default, BeginLoc, LParenLoc,
329 EndLoc),
330 DefaultClauseKind(K) {
331 assert((DefaultClauseKind == OpenACCDefaultClauseKind::None ||
332 DefaultClauseKind == OpenACCDefaultClauseKind::Present) &&
333 "Invalid Clause Kind");
334 }
335
336public:
337 static bool classof(const OpenACCClause *C) {
338 return C->getClauseKind() == OpenACCClauseKind::Default;
339 }
341 return DefaultClauseKind;
342 }
343
346 SourceLocation BeginLoc,
347 SourceLocation LParenLoc,
348 SourceLocation EndLoc);
349};
350
351/// Represents one of the handful of classes that has an optional/required
352/// 'condition' expression as an argument.
354 Expr *ConditionExpr = nullptr;
355
356protected:
358 SourceLocation LParenLoc, Expr *ConditionExpr,
359 SourceLocation EndLoc)
360 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
361 ConditionExpr(ConditionExpr) {}
362
363public:
364 static bool classof(const OpenACCClause *C);
365
366 bool hasConditionExpr() const { return ConditionExpr; }
367 const Expr *getConditionExpr() const { return ConditionExpr; }
368 Expr *getConditionExpr() { return ConditionExpr; }
369
371 if (ConditionExpr)
372 return child_range(reinterpret_cast<Stmt **>(&ConditionExpr),
373 reinterpret_cast<Stmt **>(&ConditionExpr + 1));
375 }
376
378 if (ConditionExpr)
379 return const_child_range(
380 reinterpret_cast<Stmt *const *>(&ConditionExpr),
381 reinterpret_cast<Stmt *const *>(&ConditionExpr + 1));
383 }
384};
385
386/// An 'if' clause, which has a required condition expression.
388protected:
390 Expr *ConditionExpr, SourceLocation EndLoc);
391
392public:
393 static bool classof(const OpenACCClause *C) {
394 return C->getClauseKind() == OpenACCClauseKind::If;
395 }
396 static OpenACCIfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
397 SourceLocation LParenLoc, Expr *ConditionExpr,
398 SourceLocation EndLoc);
399};
400
401/// A 'self' clause, which has an optional condition expression, or, in the
402/// event of an 'update' directive, contains a 'VarList'.
403class OpenACCSelfClause final
405 private llvm::TrailingObjects<OpenACCSelfClause, Expr *> {
406 friend TrailingObjects;
407 // Holds whether this HAS a condition expression. Lacks a value if this is NOT
408 // a condition-expr self clause.
409 std::optional<bool> HasConditionExpr;
410 // Holds the number of stored expressions. In the case of a condition-expr
411 // self clause, this is expected to be ONE (and there to be 1 trailing
412 // object), whether or not that is null.
413 unsigned NumExprs;
414
415 OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
416 Expr *ConditionExpr, SourceLocation EndLoc);
417 OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
418 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
419
420 // Intentionally internal, meant to be an implementation detail of everything
421 // else. All non-internal uses should go through getConditionExpr/getVarList.
422 ArrayRef<Expr *> getExprs() const { return getTrailingObjects(NumExprs); }
423
424public:
425 static bool classof(const OpenACCClause *C) {
426 return C->getClauseKind() == OpenACCClauseKind::Self;
427 }
428
429 bool isConditionExprClause() const { return HasConditionExpr.has_value(); }
430 bool isVarListClause() const { return !isConditionExprClause(); }
431 bool isEmptySelfClause() const {
432 return (isConditionExprClause() && !hasConditionExpr()) ||
433 (!isConditionExprClause() && getVarList().empty());
434 }
435
436 bool hasConditionExpr() const {
437 assert(HasConditionExpr.has_value() &&
438 "VarList Self Clause asked about condition expression");
439 return *HasConditionExpr;
440 }
441
442 const Expr *getConditionExpr() const {
443 assert(HasConditionExpr.has_value() &&
444 "VarList Self Clause asked about condition expression");
445 assert(getExprs().size() == 1 &&
446 "ConditionExpr Self Clause with too many Exprs");
447 return getExprs()[0];
448 }
449
451 assert(HasConditionExpr.has_value() &&
452 "VarList Self Clause asked about condition expression");
453 assert(getExprs().size() == 1 &&
454 "ConditionExpr Self Clause with too many Exprs");
455 return getExprs()[0];
456 }
457
459 assert(!HasConditionExpr.has_value() &&
460 "Condition Expr self clause asked about var list");
461 return getExprs();
462 }
464 assert(!HasConditionExpr.has_value() &&
465 "Condition Expr self clause asked about var list");
466 return getExprs();
467 }
468
470 return child_range(
471 reinterpret_cast<Stmt **>(getTrailingObjects()),
472 reinterpret_cast<Stmt **>(getTrailingObjects() + NumExprs));
473 }
474
476 return const_cast<OpenACCSelfClause *>(this)->children();
477 }
478
479 static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
480 SourceLocation LParenLoc,
481 Expr *ConditionExpr, SourceLocation EndLoc);
482 static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
483 SourceLocation LParenLoc,
484 ArrayRef<Expr *> ConditionExpr,
485 SourceLocation EndLoc);
486};
487
488/// Represents a clause that has one or more expressions associated with it.
491
492protected:
494 SourceLocation LParenLoc, SourceLocation EndLoc)
495 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {}
496
497 /// Used only for initialization, the leaf class can initialize this to
498 /// trailing storage.
500 assert(Exprs.empty() && "Cannot change Exprs list");
501 Exprs = NewExprs;
502 }
503
504 /// Used only for initialization, the leaf class can initialize this to
505 /// trailing storage, and initialize the data in the trailing storage as well.
507 assert(NewStorage.size() == Exprs.size());
508 llvm::uninitialized_copy(Exprs, NewStorage.begin());
509 setExprs(NewStorage);
510 }
511
512 /// Gets the entire list of expressions, but leave it to the
513 /// individual clauses to expose this how they'd like.
514 ArrayRef<Expr *> getExprs() const { return Exprs; }
515
516public:
517 static bool classof(const OpenACCClause *C);
519 return child_range(reinterpret_cast<Stmt **>(Exprs.begin()),
520 reinterpret_cast<Stmt **>(Exprs.end()));
521 }
522
524 return const_cast<OpenACCClauseWithExprs *>(this)->children();
525 }
526};
527
528// Represents the 'devnum' and expressions lists for the 'wait' clause.
529class OpenACCWaitClause final
530 : public OpenACCClauseWithExprs,
531 private llvm::TrailingObjects<OpenACCWaitClause, Expr *> {
532 friend TrailingObjects;
533 SourceLocation QueuesLoc;
534 OpenACCWaitClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
535 Expr *DevNumExpr, SourceLocation QueuesLoc,
536 ArrayRef<Expr *> QueueIdExprs, SourceLocation EndLoc)
537 : OpenACCClauseWithExprs(OpenACCClauseKind::Wait, BeginLoc, LParenLoc,
538 EndLoc),
539 QueuesLoc(QueuesLoc) {
540 // The first element of the trailing storage is always the devnum expr,
541 // whether it is used or not.
542 auto *Exprs = getTrailingObjects();
543 llvm::uninitialized_copy(ArrayRef(DevNumExpr), Exprs);
544 llvm::uninitialized_copy(QueueIdExprs, Exprs + 1);
545 setExprs(getTrailingObjects(QueueIdExprs.size() + 1));
546 }
547
548public:
549 static bool classof(const OpenACCClause *C) {
550 return C->getClauseKind() == OpenACCClauseKind::Wait;
551 }
552 static OpenACCWaitClause *Create(const ASTContext &C, SourceLocation BeginLoc,
553 SourceLocation LParenLoc, Expr *DevNumExpr,
554 SourceLocation QueuesLoc,
555 ArrayRef<Expr *> QueueIdExprs,
556 SourceLocation EndLoc);
557
558 bool hasQueuesTag() const { return !QueuesLoc.isInvalid(); }
559 SourceLocation getQueuesLoc() const { return QueuesLoc; }
560 bool hasDevNumExpr() const { return getExprs()[0]; }
561 Expr *getDevNumExpr() const { return getExprs()[0]; }
566 return OpenACCClauseWithExprs::getExprs().drop_front();
567 }
568 // If this is a plain `wait` (no parens) this returns 'false'. Else Sema/Parse
569 // ensures we have at least one QueueId expression.
570 bool hasExprs() const { return getLParenLoc().isValid(); }
571};
572
573class OpenACCNumGangsClause final
574 : public OpenACCClauseWithExprs,
575 private llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> {
576 friend TrailingObjects;
577
578 OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
579 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc)
581 EndLoc) {
582 setExprs(getTrailingObjects(IntExprs.size()), IntExprs);
583 }
584
585public:
586 static bool classof(const OpenACCClause *C) {
587 return C->getClauseKind() == OpenACCClauseKind::NumGangs;
588 }
589 static OpenACCNumGangsClause *
590 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
591 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
592
594
598};
599
600class OpenACCTileClause final
601 : public OpenACCClauseWithExprs,
602 private llvm::TrailingObjects<OpenACCTileClause, Expr *> {
603 friend TrailingObjects;
604 OpenACCTileClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
605 ArrayRef<Expr *> SizeExprs, SourceLocation EndLoc)
606 : OpenACCClauseWithExprs(OpenACCClauseKind::Tile, BeginLoc, LParenLoc,
607 EndLoc) {
608 setExprs(getTrailingObjects(SizeExprs.size()), SizeExprs);
609 }
610
611public:
612 static bool classof(const OpenACCClause *C) {
613 return C->getClauseKind() == OpenACCClauseKind::Tile;
614 }
615 static OpenACCTileClause *Create(const ASTContext &C, SourceLocation BeginLoc,
616 SourceLocation LParenLoc,
617 ArrayRef<Expr *> SizeExprs,
618 SourceLocation EndLoc);
620
624};
625
626/// Represents one of a handful of clauses that have a single integer
627/// expression.
629 Expr *IntExpr;
630
631protected:
633 SourceLocation LParenLoc, Expr *IntExpr,
634 SourceLocation EndLoc)
635 : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc),
636 IntExpr(IntExpr) {
637 if (IntExpr)
638 setExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
639 }
640
641public:
642 static bool classof(const OpenACCClause *C);
643 bool hasIntExpr() const { return !getExprs().empty(); }
644 const Expr *getIntExpr() const {
645 return hasIntExpr() ? getExprs()[0] : nullptr;
646 }
647
648 Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; };
649};
650
652 : public OpenACCClauseWithExprs,
653 private llvm::TrailingObjects<OpenACCGangClause, Expr *, OpenACCGangKind> {
654 friend TrailingObjects;
655protected:
658 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
659
660 OpenACCGangKind getGangKind(unsigned I) const {
661 return getTrailingObjects<OpenACCGangKind>()[I];
662 }
663
664public:
665 static bool classof(const OpenACCClause *C) {
666 return C->getClauseKind() == OpenACCClauseKind::Gang;
667 }
668
669 size_t numTrailingObjects(OverloadToken<Expr *>) const {
670 return getNumExprs();
671 }
672
673 unsigned getNumExprs() const { return getExprs().size(); }
674 std::pair<OpenACCGangKind, const Expr *> getExpr(unsigned I) const {
675 return {getGangKind(I), getExprs()[I]};
676 }
677
679 for (unsigned I = 0; I < getNumExprs(); ++I) {
680 if (getGangKind(I) == GK)
681 return true;
682 }
683 return false;
684 }
685
686 static OpenACCGangClause *
687 Create(const ASTContext &Ctx, SourceLocation BeginLoc,
688 SourceLocation LParenLoc, ArrayRef<OpenACCGangKind> GangKinds,
689 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
690};
691
693protected:
695 Expr *IntExpr, SourceLocation EndLoc);
696
697public:
698 static bool classof(const OpenACCClause *C) {
699 return C->getClauseKind() == OpenACCClauseKind::Worker;
700 }
701
702 static OpenACCWorkerClause *Create(const ASTContext &Ctx,
703 SourceLocation BeginLoc,
704 SourceLocation LParenLoc, Expr *IntExpr,
705 SourceLocation EndLoc);
706};
707
709protected:
711 Expr *IntExpr, SourceLocation EndLoc);
712
713public:
714 static bool classof(const OpenACCClause *C) {
715 return C->getClauseKind() == OpenACCClauseKind::Vector;
716 }
717
718 static OpenACCVectorClause *Create(const ASTContext &Ctx,
719 SourceLocation BeginLoc,
720 SourceLocation LParenLoc, Expr *IntExpr,
721 SourceLocation EndLoc);
722};
723
724class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
725 OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
726 Expr *IntExpr, SourceLocation EndLoc);
727
728public:
729 static bool classof(const OpenACCClause *C) {
730 return C->getClauseKind() == OpenACCClauseKind::NumWorkers;
731 }
733 SourceLocation BeginLoc,
734 SourceLocation LParenLoc,
735 Expr *IntExpr, SourceLocation EndLoc);
736};
737
738class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr {
739 OpenACCVectorLengthClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
740 Expr *IntExpr, SourceLocation EndLoc);
741
742public:
743 static bool classof(const OpenACCClause *C) {
744 return C->getClauseKind() == OpenACCClauseKind::VectorLength;
745 }
747 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
748 Expr *IntExpr, SourceLocation EndLoc);
749};
750
751class OpenACCAsyncClause : public OpenACCClauseWithSingleIntExpr {
752 OpenACCAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
753 Expr *IntExpr, SourceLocation EndLoc);
754
755public:
756 static bool classof(const OpenACCClause *C) {
757 return C->getClauseKind() == OpenACCClauseKind::Async;
758 }
759 static OpenACCAsyncClause *Create(const ASTContext &C,
760 SourceLocation BeginLoc,
761 SourceLocation LParenLoc, Expr *IntExpr,
762 SourceLocation EndLoc);
763};
764
765class OpenACCDeviceNumClause : public OpenACCClauseWithSingleIntExpr {
766 OpenACCDeviceNumClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
767 Expr *IntExpr, SourceLocation EndLoc);
768
769public:
770 static bool classof(const OpenACCClause *C) {
771 return C->getClauseKind() == OpenACCClauseKind::DeviceNum;
772 }
774 SourceLocation BeginLoc,
775 SourceLocation LParenLoc, Expr *IntExpr,
776 SourceLocation EndLoc);
777};
778
779class OpenACCDefaultAsyncClause : public OpenACCClauseWithSingleIntExpr {
780 OpenACCDefaultAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
781 Expr *IntExpr, SourceLocation EndLoc);
782
783public:
784 static bool classof(const OpenACCClause *C) {
785 return C->getClauseKind() == OpenACCClauseKind::DefaultAsync;
786 }
788 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
789 Expr *IntExpr, SourceLocation EndLoc);
790};
791
792/// Represents a 'collapse' clause on a 'loop' construct. This clause takes an
793/// integer constant expression 'N' that represents how deep to collapse the
794/// construct. It also takes an optional 'force' tag that permits intervening
795/// code in the loops.
796class OpenACCCollapseClause : public OpenACCClauseWithSingleIntExpr {
797 bool HasForce = false;
798
799 OpenACCCollapseClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
800 bool HasForce, Expr *LoopCount, SourceLocation EndLoc);
801
802public:
803 const Expr *getLoopCount() const { return getIntExpr(); }
804 Expr *getLoopCount() { return getIntExpr(); }
805
806 bool hasForce() const { return HasForce; }
807
808 static bool classof(const OpenACCClause *C) {
809 return C->getClauseKind() == OpenACCClauseKind::Collapse;
810 }
811
813 SourceLocation BeginLoc,
814 SourceLocation LParenLoc, bool HasForce,
815 Expr *LoopCount, SourceLocation EndLoc);
816};
817
818/// Represents a clause with one or more 'var' objects, represented as an expr,
819/// as its arguments. Var-list is expected to be stored in trailing storage.
820/// For now, we're just storing the original expression in its entirety, unlike
821/// OMP which has to do a bunch of work to create a private.
823protected:
825 SourceLocation LParenLoc, SourceLocation EndLoc)
826 : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {}
827
828public:
829 static bool classof(const OpenACCClause *C);
832};
833
834// Represents all the data needed for recipe generation. The declaration and
835// init are stored separately, because in the case of subscripts, we do the
836// alloca at the level of the base, and the init at the element level.
839
841
842 bool isSet() const { return AllocaDecl; }
843
845 return OpenACCPrivateRecipe(/*AllocaDecl=*/nullptr);
846 }
847};
848
849class OpenACCPrivateClause final
851 private llvm::TrailingObjects<OpenACCPrivateClause, Expr *,
852 OpenACCPrivateRecipe> {
853 friend TrailingObjects;
854
855 OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
856 ArrayRef<Expr *> VarList,
858 SourceLocation EndLoc)
860 LParenLoc, EndLoc) {
861 assert(VarList.size() == InitRecipes.size());
862 setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList);
863 llvm::uninitialized_copy(InitRecipes,
864 getTrailingObjects<OpenACCPrivateRecipe>());
865 }
866
867public:
868 static bool classof(const OpenACCClause *C) {
869 return C->getClauseKind() == OpenACCClauseKind::Private;
870 }
871 // Gets a list of 'made up' `VarDecl` objects that can be used by codegen to
872 // ensure that we properly initialize each of these variables.
875 getTrailingObjects<OpenACCPrivateRecipe>(), getExprs().size()};
876 }
877
880 getTrailingObjects<OpenACCPrivateRecipe>(), getExprs().size()};
881 }
882
883 static OpenACCPrivateClause *
884 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
886 SourceLocation EndLoc);
887
888 size_t numTrailingObjects(OverloadToken<Expr *>) const {
889 return getExprs().size();
890 }
891};
892
893// A 'pair' to stand in for the recipe. RecipeDecl is the main declaration, and
894// InitFromTemporary is the 'temp' declaration we put in to be 'copied from'.
900 assert(!InitFromTemporary || InitFromTemporary->getInit() == nullptr);
901 }
902
903 bool isSet() const { return AllocaDecl; }
904
906 return OpenACCFirstPrivateRecipe(/*AllocaDecl=*/nullptr,
907 /*InitFromTemporary=*/nullptr);
908 }
909};
910
911class OpenACCFirstPrivateClause final
913 private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *,
914 OpenACCFirstPrivateRecipe> {
915 friend TrailingObjects;
916
917 OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
918 ArrayRef<Expr *> VarList,
920 SourceLocation EndLoc)
922 LParenLoc, EndLoc) {
923 assert(VarList.size() == InitRecipes.size());
924 setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList);
925 llvm::uninitialized_copy(InitRecipes,
926 getTrailingObjects<OpenACCFirstPrivateRecipe>());
927 }
928
929public:
930 static bool classof(const OpenACCClause *C) {
931 return C->getClauseKind() == OpenACCClauseKind::FirstPrivate;
932 }
933
934 // Gets a list of 'made up' `VarDecl` objects that can be used by codegen to
935 // ensure that we properly initialize each of these variables.
938 getTrailingObjects<OpenACCFirstPrivateRecipe>(), getExprs().size()};
939 }
940
943 getTrailingObjects<OpenACCFirstPrivateRecipe>(), getExprs().size()};
944 }
945
947 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
948 ArrayRef<Expr *> VarList,
950 SourceLocation EndLoc);
951
952 size_t numTrailingObjects(OverloadToken<Expr *>) const {
953 return getExprs().size();
954 }
955};
956
957class OpenACCDevicePtrClause final
959 private llvm::TrailingObjects<OpenACCDevicePtrClause, Expr *> {
960 friend TrailingObjects;
961
962 OpenACCDevicePtrClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
963 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
965 LParenLoc, EndLoc) {
966 setExprs(getTrailingObjects(VarList.size()), VarList);
967 }
968
969public:
970 static bool classof(const OpenACCClause *C) {
971 return C->getClauseKind() == OpenACCClauseKind::DevicePtr;
972 }
974 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
975 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
976};
977
978class OpenACCAttachClause final
980 private llvm::TrailingObjects<OpenACCAttachClause, Expr *> {
981 friend TrailingObjects;
982
983 OpenACCAttachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
984 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
986 EndLoc) {
987 setExprs(getTrailingObjects(VarList.size()), VarList);
988 }
989
990public:
991 static bool classof(const OpenACCClause *C) {
992 return C->getClauseKind() == OpenACCClauseKind::Attach;
993 }
994 static OpenACCAttachClause *
995 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
996 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
997};
998
999class OpenACCDetachClause final
1000 : public OpenACCClauseWithVarList,
1001 private llvm::TrailingObjects<OpenACCDetachClause, Expr *> {
1002 friend TrailingObjects;
1003
1004 OpenACCDetachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1005 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1007 EndLoc) {
1008 setExprs(getTrailingObjects(VarList.size()), VarList);
1009 }
1010
1011public:
1012 static bool classof(const OpenACCClause *C) {
1013 return C->getClauseKind() == OpenACCClauseKind::Detach;
1014 }
1015 static OpenACCDetachClause *
1016 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1017 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1018};
1019
1020class OpenACCDeleteClause final
1021 : public OpenACCClauseWithVarList,
1022 private llvm::TrailingObjects<OpenACCDeleteClause, Expr *> {
1023 friend TrailingObjects;
1024
1025 OpenACCDeleteClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1026 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1028 EndLoc) {
1029 setExprs(getTrailingObjects(VarList.size()), VarList);
1030 }
1031
1032public:
1033 static bool classof(const OpenACCClause *C) {
1034 return C->getClauseKind() == OpenACCClauseKind::Delete;
1035 }
1036 static OpenACCDeleteClause *
1037 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1038 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1039};
1040
1041class OpenACCUseDeviceClause final
1042 : public OpenACCClauseWithVarList,
1043 private llvm::TrailingObjects<OpenACCUseDeviceClause, Expr *> {
1044 friend TrailingObjects;
1045
1046 OpenACCUseDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1047 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1049 LParenLoc, EndLoc) {
1050 setExprs(getTrailingObjects(VarList.size()), VarList);
1051 }
1052
1053public:
1054 static bool classof(const OpenACCClause *C) {
1055 return C->getClauseKind() == OpenACCClauseKind::UseDevice;
1056 }
1057 static OpenACCUseDeviceClause *
1058 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1059 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1060};
1061
1062class OpenACCNoCreateClause final
1063 : public OpenACCClauseWithVarList,
1064 private llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {
1065 friend TrailingObjects;
1066
1067 OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1068 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1070 LParenLoc, EndLoc) {
1071 setExprs(getTrailingObjects(VarList.size()), VarList);
1072 }
1073
1074public:
1075 static bool classof(const OpenACCClause *C) {
1076 return C->getClauseKind() == OpenACCClauseKind::NoCreate;
1077 }
1078 static OpenACCNoCreateClause *
1079 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1080 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1081};
1082
1083class OpenACCPresentClause final
1084 : public OpenACCClauseWithVarList,
1085 private llvm::TrailingObjects<OpenACCPresentClause, Expr *> {
1086 friend TrailingObjects;
1087
1088 OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1089 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1091 LParenLoc, EndLoc) {
1092 setExprs(getTrailingObjects(VarList.size()), VarList);
1093 }
1094
1095public:
1096 static bool classof(const OpenACCClause *C) {
1097 return C->getClauseKind() == OpenACCClauseKind::Present;
1098 }
1099 static OpenACCPresentClause *
1100 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1101 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1102};
1103class OpenACCHostClause final
1104 : public OpenACCClauseWithVarList,
1105 private llvm::TrailingObjects<OpenACCHostClause, Expr *> {
1106 friend TrailingObjects;
1107
1108 OpenACCHostClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1109 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1111 EndLoc) {
1112 setExprs(getTrailingObjects(VarList.size()), VarList);
1113 }
1114
1115public:
1116 static bool classof(const OpenACCClause *C) {
1117 return C->getClauseKind() == OpenACCClauseKind::Host;
1118 }
1119 static OpenACCHostClause *Create(const ASTContext &C, SourceLocation BeginLoc,
1120 SourceLocation LParenLoc,
1121 ArrayRef<Expr *> VarList,
1122 SourceLocation EndLoc);
1123};
1124
1125class OpenACCDeviceClause final
1126 : public OpenACCClauseWithVarList,
1127 private llvm::TrailingObjects<OpenACCDeviceClause, Expr *> {
1128 friend TrailingObjects;
1129
1130 OpenACCDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1131 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1133 EndLoc) {
1134 setExprs(getTrailingObjects(VarList.size()), VarList);
1135 }
1136
1137public:
1138 static bool classof(const OpenACCClause *C) {
1139 return C->getClauseKind() == OpenACCClauseKind::Device;
1140 }
1141 static OpenACCDeviceClause *
1142 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1143 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1144};
1145
1146class OpenACCCopyClause final
1147 : public OpenACCClauseWithVarList,
1148 private llvm::TrailingObjects<OpenACCCopyClause, Expr *> {
1149 friend TrailingObjects;
1150 OpenACCModifierKind Modifiers;
1151
1152 OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1153 SourceLocation LParenLoc, OpenACCModifierKind Mods,
1154 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1155 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1156 Modifiers(Mods) {
1157 assert((Spelling == OpenACCClauseKind::Copy ||
1158 Spelling == OpenACCClauseKind::PCopy ||
1159 Spelling == OpenACCClauseKind::PresentOrCopy) &&
1160 "Invalid clause kind for copy-clause");
1161 setExprs(getTrailingObjects(VarList.size()), VarList);
1162 }
1163
1164public:
1165 static bool classof(const OpenACCClause *C) {
1166 return C->getClauseKind() == OpenACCClauseKind::Copy ||
1167 C->getClauseKind() == OpenACCClauseKind::PCopy ||
1168 C->getClauseKind() == OpenACCClauseKind::PresentOrCopy;
1169 }
1170 static OpenACCCopyClause *
1171 Create(const ASTContext &C, OpenACCClauseKind Spelling,
1172 SourceLocation BeginLoc, SourceLocation LParenLoc,
1174 SourceLocation EndLoc);
1175
1176 OpenACCModifierKind getModifierList() const { return Modifiers; }
1177};
1178
1179class OpenACCCopyInClause final
1180 : public OpenACCClauseWithVarList,
1181 private llvm::TrailingObjects<OpenACCCopyInClause, Expr *> {
1182 friend TrailingObjects;
1183 OpenACCModifierKind Modifiers;
1184
1185 OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1186 SourceLocation LParenLoc, OpenACCModifierKind Mods,
1187 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1188 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1189 Modifiers(Mods) {
1190 assert((Spelling == OpenACCClauseKind::CopyIn ||
1191 Spelling == OpenACCClauseKind::PCopyIn ||
1193 "Invalid clause kind for copyin-clause");
1194 setExprs(getTrailingObjects(VarList.size()), VarList);
1195 }
1196
1197public:
1198 static bool classof(const OpenACCClause *C) {
1199 return C->getClauseKind() == OpenACCClauseKind::CopyIn ||
1200 C->getClauseKind() == OpenACCClauseKind::PCopyIn ||
1201 C->getClauseKind() == OpenACCClauseKind::PresentOrCopyIn;
1202 }
1203 OpenACCModifierKind getModifierList() const { return Modifiers; }
1204 static OpenACCCopyInClause *
1205 Create(const ASTContext &C, OpenACCClauseKind Spelling,
1206 SourceLocation BeginLoc, SourceLocation LParenLoc,
1208 SourceLocation EndLoc);
1209};
1210
1211class OpenACCCopyOutClause final
1212 : public OpenACCClauseWithVarList,
1213 private llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> {
1214 friend TrailingObjects;
1215 OpenACCModifierKind Modifiers;
1216
1217 OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1218 SourceLocation LParenLoc, OpenACCModifierKind Mods,
1219 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1220 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1221 Modifiers(Mods) {
1222 assert((Spelling == OpenACCClauseKind::CopyOut ||
1223 Spelling == OpenACCClauseKind::PCopyOut ||
1225 "Invalid clause kind for copyout-clause");
1226 setExprs(getTrailingObjects(VarList.size()), VarList);
1227 }
1228
1229public:
1230 static bool classof(const OpenACCClause *C) {
1231 return C->getClauseKind() == OpenACCClauseKind::CopyOut ||
1232 C->getClauseKind() == OpenACCClauseKind::PCopyOut ||
1233 C->getClauseKind() == OpenACCClauseKind::PresentOrCopyOut;
1234 }
1235 OpenACCModifierKind getModifierList() const { return Modifiers; }
1236 static OpenACCCopyOutClause *
1237 Create(const ASTContext &C, OpenACCClauseKind Spelling,
1238 SourceLocation BeginLoc, SourceLocation LParenLoc,
1240 SourceLocation EndLoc);
1241};
1242
1243class OpenACCCreateClause final
1244 : public OpenACCClauseWithVarList,
1245 private llvm::TrailingObjects<OpenACCCreateClause, Expr *> {
1246 friend TrailingObjects;
1247 OpenACCModifierKind Modifiers;
1248
1249 OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1250 SourceLocation LParenLoc, OpenACCModifierKind Mods,
1251 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1252 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1253 Modifiers(Mods) {
1254 assert((Spelling == OpenACCClauseKind::Create ||
1255 Spelling == OpenACCClauseKind::PCreate ||
1257 "Invalid clause kind for create-clause");
1258 setExprs(getTrailingObjects(VarList.size()), VarList);
1259 }
1260
1261public:
1262 static bool classof(const OpenACCClause *C) {
1263 return C->getClauseKind() == OpenACCClauseKind::Create ||
1264 C->getClauseKind() == OpenACCClauseKind::PCreate ||
1265 C->getClauseKind() == OpenACCClauseKind::PresentOrCreate;
1266 }
1267 OpenACCModifierKind getModifierList() const { return Modifiers; }
1268 static OpenACCCreateClause *
1269 Create(const ASTContext &C, OpenACCClauseKind Spelling,
1270 SourceLocation BeginLoc, SourceLocation LParenLoc,
1272 SourceLocation EndLoc);
1273};
1274
1275// A structure to stand in for the recipe on a reduction. RecipeDecl is the
1276// 'main' declaration used for initializaiton, which is fixed.
1277struct OpenACCReductionRecipe {
1279
1280 // A combiner recipe is represented by an operation expression. However, in
1281 // order to generate these properly, we have to make up a LHS and a RHS
1282 // expression for the purposes of generation.
1288
1289 // Contains a collection of the recipe elements we need for the combiner:
1290 // -For Scalars, there will be 1 element, just the combiner for that scalar.
1291 // -For a struct with a valid operator, this will be 1 element, just that
1292 // call.
1293 // -For a struct without the operator, this will be 1 element per field, which
1294 // should be the combiner for that element.
1295 // -For an array of any of the above, it will be the above for the element.
1296 // Note: These are necessarily stored in either Trailing Storage (when in the
1297 // AST), or in a separate collection when being semantically analyzed.
1299
1300 bool isSet() const { return AllocaDecl; }
1301
1302private:
1304 OpenACCReductionRecipe(VarDecl *A, llvm::ArrayRef<CombinerRecipe> Combiners)
1305 : AllocaDecl(A), CombinerRecipes(Combiners) {}
1306};
1307
1308// A version of the above that is used for semantic analysis, at a time before
1309// the OpenACCReductionClause node has been created. This one has storage for
1310// the CombinerRecipe, since Trailing storage for it doesn't exist yet.
1324
1325class OpenACCReductionClause final
1326 : public OpenACCClauseWithVarList,
1327 private llvm::TrailingObjects<OpenACCReductionClause, Expr *,
1328 OpenACCReductionRecipe,
1329 OpenACCReductionRecipe::CombinerRecipe> {
1330 friend TrailingObjects;
1332
1333 OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1334 OpenACCReductionOperator Operator,
1335 ArrayRef<Expr *> VarList,
1337 SourceLocation EndLoc)
1339 LParenLoc, EndLoc),
1340 Op(Operator) {
1341 assert(VarList.size() == Recipes.size());
1342 setExprs(getTrailingObjects<Expr *>(VarList.size()), VarList);
1343
1344 // Since we're using trailing storage on this node to store the 'combiner'
1345 // recipes of the Reduction Recipes (which have a 1:M relationship), we need
1346 // to ensure we get the ArrayRef of each of our combiner 'correct'.
1348 getTrailingObjects<OpenACCReductionRecipe::CombinerRecipe>();
1349 for (const auto &[Idx, R] : llvm::enumerate(Recipes)) {
1350
1351 // ArrayRef to the 'correct' data location in trailing storage.
1353 NewCombiners{CurCombinerLoc, R.CombinerRecipes.size()};
1354 CurCombinerLoc += R.CombinerRecipes.size();
1355
1356 llvm::uninitialized_copy(R.CombinerRecipes, NewCombiners.begin());
1357
1358 // Placement new into the correct location in trailng storage.
1359 new (&getTrailingObjects<OpenACCReductionRecipe>()[Idx])
1360 OpenACCReductionRecipe(R.AllocaDecl, NewCombiners);
1361 }
1362 }
1363
1364public:
1365 static bool classof(const OpenACCClause *C) {
1366 return C->getClauseKind() == OpenACCClauseKind::Reduction;
1367 }
1368
1371 getTrailingObjects<OpenACCReductionRecipe>(), getExprs().size()};
1372 }
1373
1376 getTrailingObjects<OpenACCReductionRecipe>(), getExprs().size()};
1377 }
1378
1379 static OpenACCReductionClause *
1380 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1383 SourceLocation EndLoc);
1384
1386
1387 size_t numTrailingObjects(OverloadToken<Expr *>) const {
1388 return getExprs().size();
1389 }
1390 size_t numTrailingObjects(OverloadToken<OpenACCReductionRecipe>) const {
1391 return getExprs().size();
1392 }
1393};
1394
1395class OpenACCLinkClause final
1396 : public OpenACCClauseWithVarList,
1397 private llvm::TrailingObjects<OpenACCLinkClause, Expr *> {
1398 friend TrailingObjects;
1399
1400 OpenACCLinkClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1401 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1403 EndLoc) {
1404 setExprs(getTrailingObjects(VarList.size()), VarList);
1405 }
1406
1407public:
1408 static bool classof(const OpenACCClause *C) {
1409 return C->getClauseKind() == OpenACCClauseKind::Link;
1410 }
1411
1412 static OpenACCLinkClause *Create(const ASTContext &C, SourceLocation BeginLoc,
1413 SourceLocation LParenLoc,
1414 ArrayRef<Expr *> VarList,
1415 SourceLocation EndLoc);
1416};
1417
1418class OpenACCDeviceResidentClause final
1419 : public OpenACCClauseWithVarList,
1420 private llvm::TrailingObjects<OpenACCDeviceResidentClause, Expr *> {
1421 friend TrailingObjects;
1422
1423 OpenACCDeviceResidentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1424 ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1426 LParenLoc, EndLoc) {
1427 setExprs(getTrailingObjects(VarList.size()), VarList);
1428 }
1429
1430public:
1431 static bool classof(const OpenACCClause *C) {
1432 return C->getClauseKind() == OpenACCClauseKind::DeviceResident;
1433 }
1434
1436 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1437 ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1438};
1439
1440template <class Impl> class OpenACCClauseVisitor {
1441 Impl &getDerived() { return static_cast<Impl &>(*this); }
1442
1443public:
1445 for (const OpenACCClause *Clause : List)
1446 Visit(Clause);
1447 }
1448
1449 void Visit(const OpenACCClause *C) {
1450 if (!C)
1451 return;
1452
1453 switch (C->getClauseKind()) {
1454#define VISIT_CLAUSE(CLAUSE_NAME) \
1455 case OpenACCClauseKind::CLAUSE_NAME: \
1456 getDerived().Visit##CLAUSE_NAME##Clause( \
1457 *cast<OpenACC##CLAUSE_NAME##Clause>(C)); \
1458 return;
1459#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \
1460 case OpenACCClauseKind::ALIAS_NAME: \
1461 getDerived().Visit##CLAUSE_NAME##Clause( \
1462 *cast<OpenACC##CLAUSE_NAME##Clause>(C)); \
1463 return;
1464#include "clang/Basic/OpenACCClauses.def"
1465
1466 default:
1467 llvm_unreachable("Clause visitor not yet implemented");
1468 }
1469 llvm_unreachable("Invalid Clause kind");
1470 }
1471
1472#define VISIT_CLAUSE(CLAUSE_NAME) \
1473 void Visit##CLAUSE_NAME##Clause( \
1474 const OpenACC##CLAUSE_NAME##Clause &Clause) { \
1475 return getDerived().VisitClause(Clause); \
1476 }
1477
1478#include "clang/Basic/OpenACCClauses.def"
1479};
1480
1482 : public OpenACCClauseVisitor<OpenACCClausePrinter> {
1483 raw_ostream &OS;
1484 const PrintingPolicy &Policy;
1485
1486 void printExpr(const Expr *E);
1487
1488public:
1490 for (const OpenACCClause *Clause : List) {
1491 Visit(Clause);
1492
1493 if (Clause != List.back())
1494 OS << ' ';
1495 }
1496 }
1497 OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
1498 : OS(OS), Policy(Policy) {}
1499
1500#define VISIT_CLAUSE(CLAUSE_NAME) \
1501 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
1502#include "clang/Basic/OpenACCClauses.def"
1503};
1504
1505} // namespace clang
1506
1507#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:220
This represents one expression.
Definition Expr.h:112
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()
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
ArrayRef< OpenACCFirstPrivateRecipe > getInitRecipes()
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)
ArrayRef< Expr * > getIntExprs()
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< OpenACCPrivateRecipe > getInitRecipes()
ArrayRef< OpenACCReductionRecipe > getRecipes() const
size_t numTrailingObjects(OverloadToken< OpenACCReductionRecipe >) const
size_t numTrailingObjects(OverloadToken< Expr * >) const
ArrayRef< OpenACCReductionRecipe > getRecipes()
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()
ArrayRef< Expr * > getVarList() const
static bool classof(const OpenACCClause *C)
const_child_range children() const
OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc)
ArrayRef< Expr * > getSizeExprs()
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)
ArrayRef< Expr * > getQueueIdExprs()
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:1799
Represents a variable declaration or definition.
Definition Decl.h:926
The JSON file list parser is used to communicate input to InstallAPI.
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:204
OpenACCDefaultClauseKind
IdentifierLoc DeviceTypeArgument
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.