clang 22.0.0git
StmtOpenACC.h
Go to the documentation of this file.
1//===- StmtOpenACC.h - Classes for OpenACC directives ----------*- 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/// \file
9/// This file defines OpenACC AST classes for statement-level contructs.
10///
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_STMTOPENACC_H
14#define LLVM_CLANG_AST_STMTOPENACC_H
15
17#include "clang/AST/Stmt.h"
20#include "llvm/ADT/STLExtras.h"
21#include <memory>
22
23namespace clang {
24/// This is the base class for an OpenACC statement-level construct, other
25/// construct types are expected to inherit from this.
26class OpenACCConstructStmt : public Stmt {
27 friend class ASTStmtWriter;
28 friend class ASTStmtReader;
29 /// The directive kind. Each implementation of this interface should handle
30 /// specific kinds.
32 /// The location of the directive statement, from the '#' to the last token of
33 /// the directive.
34 SourceRange Range;
35 /// The location of the directive name.
36 SourceLocation DirectiveLoc;
37
38 /// The list of clauses. This is stored here as an ArrayRef, as this is the
39 /// most convienient place to access the list, however the list itself should
40 /// be stored in leaf nodes, likely in trailing-storage.
42
43protected:
45 SourceLocation Start, SourceLocation DirectiveLoc,
47 : Stmt(SC), Kind(K), Range(Start, End), DirectiveLoc(DirectiveLoc) {}
48
49 // Used only for initialization, the leaf class can initialize this to
50 // trailing storage.
52 assert(Clauses.empty() && "Cannot change clause list");
53 Clauses = NewClauses;
54 }
55
56public:
57 OpenACCDirectiveKind getDirectiveKind() const { return Kind; }
58
59 static bool classof(const Stmt *S) {
60 return S->getStmtClass() >= firstOpenACCConstructStmtConstant &&
61 S->getStmtClass() <= lastOpenACCConstructStmtConstant;
62 }
63
64 SourceLocation getBeginLoc() const { return Range.getBegin(); }
65 SourceLocation getEndLoc() const { return Range.getEnd(); }
66 SourceLocation getDirectiveLoc() const { return DirectiveLoc; }
67 ArrayRef<const OpenACCClause *> clauses() const { return Clauses; }
68
72
74 return const_cast<OpenACCConstructStmt *>(this)->children();
75 }
76};
77
78/// This is a base class for any OpenACC statement-level constructs that have an
79/// associated statement. This class is not intended to be instantiated, but is
80/// a convenient place to hold the associated statement.
82 friend class ASTStmtWriter;
83 friend class ASTStmtReader;
84 template <typename Derived> friend class RecursiveASTVisitor;
85 Stmt *AssociatedStmt = nullptr;
86
87protected:
89 SourceLocation Start,
90 SourceLocation DirectiveLoc,
91 SourceLocation End, Stmt *AssocStmt)
92 : OpenACCConstructStmt(SC, K, Start, DirectiveLoc, End),
93 AssociatedStmt(AssocStmt) {}
94
95 void setAssociatedStmt(Stmt *S) { AssociatedStmt = S; }
96 Stmt *getAssociatedStmt() { return AssociatedStmt; }
97 const Stmt *getAssociatedStmt() const {
98 return const_cast<OpenACCAssociatedStmtConstruct *>(this)
100 }
101
102public:
103 static bool classof(const Stmt *T) {
104 return false;
105 }
106
108 if (getAssociatedStmt())
109 return child_range(&AssociatedStmt, &AssociatedStmt + 1);
111 }
112
114 return const_cast<OpenACCAssociatedStmtConstruct *>(this)->children();
115 }
116};
117
118/// This class represents a compute construct, representing a 'Kind' of
119/// `parallel', 'serial', or 'kernel'. These constructs are associated with a
120/// 'structured block', defined as:
121///
122/// in C or C++, an executable statement, possibly compound, with a single
123/// entry at the top and a single exit at the bottom
124///
125/// At the moment there is no real motivation to have a different AST node for
126/// those three, as they are semantically identical, and have only minor
127/// differences in the permitted list of clauses, which can be differentiated by
128/// the 'Kind'.
129class OpenACCComputeConstruct final
131 private llvm::TrailingObjects<OpenACCComputeConstruct,
132 const OpenACCClause *> {
133 friend class ASTStmtWriter;
134 friend class ASTStmtReader;
135 friend class ASTContext;
136 friend TrailingObjects;
137 OpenACCComputeConstruct(unsigned NumClauses)
139 OpenACCComputeConstructClass, OpenACCDirectiveKind::Invalid,
140 SourceLocation{}, SourceLocation{}, SourceLocation{},
141 /*AssociatedStmt=*/nullptr) {
142 // We cannot send the TrailingObjects storage to the base class (which holds
143 // a reference to the data) until it is constructed, so we have to set it
144 // separately here.
145 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
146 setClauseList(getTrailingObjects(NumClauses));
147 }
148
150 SourceLocation DirectiveLoc, SourceLocation End,
152 Stmt *StructuredBlock)
153 : OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass, K, Start,
154 DirectiveLoc, End, StructuredBlock) {
156 "Only parallel, serial, and kernels constructs should be "
157 "represented by this type");
158
159 // Initialize the trailing storage.
160 llvm::uninitialized_copy(Clauses, getTrailingObjects());
161
162 setClauseList(getTrailingObjects(Clauses.size()));
163 }
164
165 void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
166
167public:
168 static bool classof(const Stmt *T) {
169 return T->getStmtClass() == OpenACCComputeConstructClass;
170 }
171
173 unsigned NumClauses);
176 SourceLocation DirectiveLoc, SourceLocation EndLoc,
177 ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock);
178
179 Stmt *getStructuredBlock() { return getAssociatedStmt(); }
180 const Stmt *getStructuredBlock() const {
181 return const_cast<OpenACCComputeConstruct *>(this)->getStructuredBlock();
182 }
183};
184/// This class represents a 'loop' construct. The 'loop' construct applies to a
185/// 'for' loop (or range-for loop), and is optionally associated with a Compute
186/// Construct.
187class OpenACCLoopConstruct final
189 private llvm::TrailingObjects<OpenACCLoopConstruct,
190 const OpenACCClause *> {
191 // The compute/combined construct kind this loop is associated with, or
192 // invalid if this is an orphaned loop construct.
193 OpenACCDirectiveKind ParentComputeConstructKind =
194 OpenACCDirectiveKind::Invalid;
195
196 friend class ASTStmtWriter;
197 friend class ASTStmtReader;
198 friend class ASTContext;
202 friend TrailingObjects;
203
204 OpenACCLoopConstruct(unsigned NumClauses);
205
206 OpenACCLoopConstruct(OpenACCDirectiveKind ParentKind, SourceLocation Start,
207 SourceLocation DirLoc, SourceLocation End,
208 ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop);
209
210public:
211 static bool classof(const Stmt *T) {
212 return T->getStmtClass() == OpenACCLoopConstructClass;
213 }
214
216 unsigned NumClauses);
217
218 static OpenACCLoopConstruct *
219 Create(const ASTContext &C, OpenACCDirectiveKind ParentKind,
220 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc,
221 ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop);
222
223 Stmt *getLoop() { return getAssociatedStmt(); }
224 const Stmt *getLoop() const {
225 return const_cast<OpenACCLoopConstruct *>(this)->getLoop();
226 }
227
228 /// OpenACC 3.3 2.9:
229 /// An orphaned loop construct is a loop construct that is not lexically
230 /// enclosed within a compute construct. The parent compute construct of a
231 /// loop construct is the nearest compute construct that lexically contains
232 /// the loop construct.
234 return ParentComputeConstructKind == OpenACCDirectiveKind::Invalid;
235 }
236
237 OpenACCDirectiveKind getParentComputeConstructKind() const {
238 return ParentComputeConstructKind;
239 }
240};
241
242// This class represents a 'combined' construct, which has a bunch of rules
243// shared with both loop and compute constructs.
244class OpenACCCombinedConstruct final
246 private llvm::TrailingObjects<OpenACCCombinedConstruct,
247 const OpenACCClause *> {
248 friend TrailingObjects;
249 OpenACCCombinedConstruct(unsigned NumClauses)
251 OpenACCCombinedConstructClass, OpenACCDirectiveKind::Invalid,
252 SourceLocation{}, SourceLocation{}, SourceLocation{},
253 /*AssociatedStmt=*/nullptr) {
254 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
255 setClauseList(getTrailingObjects(NumClauses));
256 }
257
258 OpenACCCombinedConstruct(OpenACCDirectiveKind K, SourceLocation Start,
259 SourceLocation DirectiveLoc, SourceLocation End,
261 Stmt *StructuredBlock)
262 : OpenACCAssociatedStmtConstruct(OpenACCCombinedConstructClass, K, Start,
263 DirectiveLoc, End, StructuredBlock) {
264 assert(isOpenACCCombinedDirectiveKind(K) &&
265 "Only parallel loop, serial loop, and kernels loop constructs "
266 "should be represented by this type");
267
268 llvm::uninitialized_copy(Clauses, getTrailingObjects());
269 setClauseList(getTrailingObjects(Clauses.size()));
270 }
271 void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
272
273public:
274 static bool classof(const Stmt *T) {
275 return T->getStmtClass() == OpenACCCombinedConstructClass;
276 }
277
279 unsigned NumClauses);
281 Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation Start,
282 SourceLocation DirectiveLoc, SourceLocation End,
283 ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock);
284 Stmt *getLoop() { return getAssociatedStmt(); }
285 const Stmt *getLoop() const {
286 return const_cast<OpenACCCombinedConstruct *>(this)->getLoop();
287 }
288};
289
290// This class represents a 'data' construct, which has an associated statement
291// and clauses, but is otherwise pretty simple.
292class OpenACCDataConstruct final
294 private llvm::TrailingObjects<OpenACCDataConstruct,
295 const OpenACCClause *> {
296 friend TrailingObjects;
297 OpenACCDataConstruct(unsigned NumClauses)
299 OpenACCDataConstructClass, OpenACCDirectiveKind::Data,
300 SourceLocation{}, SourceLocation{}, SourceLocation{},
301 /*AssociatedStmt=*/nullptr) {
302 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
303 setClauseList(getTrailingObjects(NumClauses));
304 }
305
306 OpenACCDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
307 SourceLocation End,
309 Stmt *StructuredBlock)
310 : OpenACCAssociatedStmtConstruct(OpenACCDataConstructClass,
311 OpenACCDirectiveKind::Data, Start,
312 DirectiveLoc, End, StructuredBlock) {
313 llvm::uninitialized_copy(Clauses, getTrailingObjects());
314 setClauseList(getTrailingObjects(Clauses.size()));
315 }
316 void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
317
318public:
319 static bool classof(const Stmt *T) {
320 return T->getStmtClass() == OpenACCDataConstructClass;
321 }
322
324 unsigned NumClauses);
325 static OpenACCDataConstruct *Create(const ASTContext &C, SourceLocation Start,
326 SourceLocation DirectiveLoc,
327 SourceLocation End,
329 Stmt *StructuredBlock);
330 Stmt *getStructuredBlock() { return getAssociatedStmt(); }
331 const Stmt *getStructuredBlock() const {
332 return const_cast<OpenACCDataConstruct *>(this)->getStructuredBlock();
333 }
334};
335// This class represents a 'enter data' construct, which JUST has clauses.
336class OpenACCEnterDataConstruct final
337 : public OpenACCConstructStmt,
338 private llvm::TrailingObjects<OpenACCEnterDataConstruct,
339 const OpenACCClause *> {
340 friend TrailingObjects;
341 OpenACCEnterDataConstruct(unsigned NumClauses)
342 : OpenACCConstructStmt(OpenACCEnterDataConstructClass,
343 OpenACCDirectiveKind::EnterData, SourceLocation{},
344 SourceLocation{}, SourceLocation{}) {
345 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
346 setClauseList(getTrailingObjects(NumClauses));
347 }
348 OpenACCEnterDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
349 SourceLocation End,
351 : OpenACCConstructStmt(OpenACCEnterDataConstructClass,
352 OpenACCDirectiveKind::EnterData, Start,
353 DirectiveLoc, End) {
354 llvm::uninitialized_copy(Clauses, getTrailingObjects());
355 setClauseList(getTrailingObjects(Clauses.size()));
356 }
357
358public:
359 static bool classof(const Stmt *T) {
360 return T->getStmtClass() == OpenACCEnterDataConstructClass;
361 }
363 unsigned NumClauses);
365 Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
366 SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
367};
368// This class represents a 'exit data' construct, which JUST has clauses.
369class OpenACCExitDataConstruct final
370 : public OpenACCConstructStmt,
371 private llvm::TrailingObjects<OpenACCExitDataConstruct,
372 const OpenACCClause *> {
373 friend TrailingObjects;
374 OpenACCExitDataConstruct(unsigned NumClauses)
375 : OpenACCConstructStmt(OpenACCExitDataConstructClass,
376 OpenACCDirectiveKind::ExitData, SourceLocation{},
377 SourceLocation{}, SourceLocation{}) {
378 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
379 setClauseList(getTrailingObjects(NumClauses));
380 }
381 OpenACCExitDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
382 SourceLocation End,
384 : OpenACCConstructStmt(OpenACCExitDataConstructClass,
385 OpenACCDirectiveKind::ExitData, Start,
386 DirectiveLoc, End) {
387 llvm::uninitialized_copy(Clauses, getTrailingObjects());
388 setClauseList(getTrailingObjects(Clauses.size()));
389 }
390
391public:
392 static bool classof(const Stmt *T) {
393 return T->getStmtClass() == OpenACCExitDataConstructClass;
394 }
396 unsigned NumClauses);
398 Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
399 SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
400};
401// This class represents a 'host_data' construct, which has an associated
402// statement and clauses, but is otherwise pretty simple.
403class OpenACCHostDataConstruct final
405 private llvm::TrailingObjects<OpenACCHostDataConstruct,
406 const OpenACCClause *> {
407 friend TrailingObjects;
408 OpenACCHostDataConstruct(unsigned NumClauses)
410 OpenACCHostDataConstructClass, OpenACCDirectiveKind::HostData,
411 SourceLocation{}, SourceLocation{}, SourceLocation{},
412 /*AssociatedStmt=*/nullptr) {
413 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
414 setClauseList(getTrailingObjects(NumClauses));
415 }
416 OpenACCHostDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
417 SourceLocation End,
419 Stmt *StructuredBlock)
420 : OpenACCAssociatedStmtConstruct(OpenACCHostDataConstructClass,
421 OpenACCDirectiveKind::HostData, Start,
422 DirectiveLoc, End, StructuredBlock) {
423 llvm::uninitialized_copy(Clauses, getTrailingObjects());
424 setClauseList(getTrailingObjects(Clauses.size()));
425 }
426 void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
427
428public:
429 static bool classof(const Stmt *T) {
430 return T->getStmtClass() == OpenACCHostDataConstructClass;
431 }
433 unsigned NumClauses);
435 Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
436 SourceLocation End, ArrayRef<const OpenACCClause *> Clauses,
437 Stmt *StructuredBlock);
438 Stmt *getStructuredBlock() { return getAssociatedStmt(); }
439 const Stmt *getStructuredBlock() const {
440 return const_cast<OpenACCHostDataConstruct *>(this)->getStructuredBlock();
441 }
442};
443
444// This class represents a 'wait' construct, which has some expressions plus a
445// clause list.
446class OpenACCWaitConstruct final
447 : public OpenACCConstructStmt,
448 private llvm::TrailingObjects<OpenACCWaitConstruct, Expr *,
449 OpenACCClause *> {
450 // FIXME: We should be storing a `const OpenACCClause *` to be consistent with
451 // the rest of the constructs, but TrailingObjects doesn't allow for mixing
452 // constness in its implementation of `getTrailingObjects`.
453
454 friend TrailingObjects;
455 friend class ASTStmtWriter;
456 friend class ASTStmtReader;
457 // Locations of the left and right parens of the 'wait-argument'
458 // expression-list.
459 SourceLocation LParenLoc, RParenLoc;
460 // Location of the 'queues' keyword, if present.
461 SourceLocation QueuesLoc;
462
463 // Number of the expressions being represented. Index '0' is always the
464 // 'devnum' expression, even if it not present.
465 unsigned NumExprs = 0;
466
467 OpenACCWaitConstruct(unsigned NumExprs, unsigned NumClauses)
468 : OpenACCConstructStmt(OpenACCWaitConstructClass,
469 OpenACCDirectiveKind::Wait, SourceLocation{},
470 SourceLocation{}, SourceLocation{}),
471 NumExprs(NumExprs) {
472 assert(NumExprs >= 1 &&
473 "NumExprs should always be >= 1 because the 'devnum' "
474 "expr is represented by a null if necessary");
475 std::uninitialized_value_construct_n(getExprPtr(), NumExprs);
476 std::uninitialized_value_construct_n(getTrailingObjects<OpenACCClause *>(),
477 NumClauses);
478 setClauseList(MutableArrayRef(const_cast<const OpenACCClause **>(
479 getTrailingObjects<OpenACCClause *>()),
480 NumClauses));
481 }
482
483 OpenACCWaitConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
484 SourceLocation LParenLoc, Expr *DevNumExpr,
485 SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
486 SourceLocation RParenLoc, SourceLocation End,
488 : OpenACCConstructStmt(OpenACCWaitConstructClass,
489 OpenACCDirectiveKind::Wait, Start, DirectiveLoc,
490 End),
491 LParenLoc(LParenLoc), RParenLoc(RParenLoc), QueuesLoc(QueuesLoc),
492 NumExprs(QueueIdExprs.size() + 1) {
493 assert(NumExprs >= 1 &&
494 "NumExprs should always be >= 1 because the 'devnum' "
495 "expr is represented by a null if necessary");
496
497 llvm::uninitialized_copy(ArrayRef(DevNumExpr), getExprPtr());
498 llvm::uninitialized_copy(QueueIdExprs, getExprPtr() + 1);
499 std::uninitialized_copy(const_cast<OpenACCClause **>(Clauses.begin()),
500 const_cast<OpenACCClause **>(Clauses.end()),
501 getTrailingObjects<OpenACCClause *>());
502 setClauseList(MutableArrayRef(const_cast<const OpenACCClause **>(
503 getTrailingObjects<OpenACCClause *>()),
504 Clauses.size()));
505 }
506
507 size_t numTrailingObjects(OverloadToken<Expr *>) const { return NumExprs; }
508 size_t numTrailingObjects(OverloadToken<const OpenACCClause *>) const {
509 return clauses().size();
510 }
511
512 Expr **getExprPtr() const {
513 return const_cast<Expr**>(getTrailingObjects<Expr *>());
514 }
515
516 ArrayRef<Expr *> getExprs() const { return {getExprPtr(), NumExprs}; }
517
518 ArrayRef<Expr *> getExprs() { return {getExprPtr(), NumExprs}; }
519
520public:
521 static bool classof(const Stmt *T) {
522 return T->getStmtClass() == OpenACCWaitConstructClass;
523 }
524
525 static OpenACCWaitConstruct *
526 CreateEmpty(const ASTContext &C, unsigned NumExprs, unsigned NumClauses);
527
528 static OpenACCWaitConstruct *
529 Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
530 SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc,
531 ArrayRef<Expr *> QueueIdExprs, SourceLocation RParenLoc,
532 SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
533
534 SourceLocation getLParenLoc() const { return LParenLoc; }
535 SourceLocation getRParenLoc() const { return RParenLoc; }
536 bool hasQueuesTag() const { return !QueuesLoc.isInvalid(); }
537 SourceLocation getQueuesLoc() const { return QueuesLoc; }
538
539 bool hasDevNumExpr() const { return getExprs()[0]; }
540 Expr *getDevNumExpr() const { return getExprs()[0]; }
541 ArrayRef<Expr *> getQueueIdExprs() { return getExprs().drop_front(); }
542 ArrayRef<Expr *> getQueueIdExprs() const { return getExprs().drop_front(); }
543
544 child_range children() {
545 Stmt **Begin = reinterpret_cast<Stmt **>(getExprPtr());
546 return child_range(Begin, Begin + NumExprs);
547 }
548
549 const_child_range children() const {
550 Stmt *const *Begin =
551 reinterpret_cast<Stmt *const *>(getExprPtr());
552 return const_child_range(Begin, Begin + NumExprs);
553 }
554};
555
556class OpenACCCacheConstruct final
557 : public OpenACCConstructStmt,
558 private llvm::TrailingObjects<OpenACCCacheConstruct, Expr *> {
559 friend TrailingObjects;
560 friend class ASTStmtWriter;
561 friend class ASTStmtReader;
562 // Locations of the left and right parens of the 'var-list'
563 // expression-list.
564 SourceRange ParensLoc;
565 SourceLocation ReadOnlyLoc;
566
567 unsigned NumVars = 0;
568
569 OpenACCCacheConstruct(unsigned NumVars)
570 : OpenACCConstructStmt(OpenACCCacheConstructClass,
571 OpenACCDirectiveKind::Cache, SourceLocation{},
572 SourceLocation{}, SourceLocation{}),
573 NumVars(NumVars) {
574 std::uninitialized_value_construct_n(getTrailingObjects(), NumVars);
575 }
576 OpenACCCacheConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
577 SourceLocation LParenLoc, SourceLocation ReadOnlyLoc,
578 ArrayRef<Expr *> VarList, SourceLocation RParenLoc,
579 SourceLocation End)
580 : OpenACCConstructStmt(OpenACCCacheConstructClass,
581 OpenACCDirectiveKind::Cache, Start, DirectiveLoc,
582 End),
583 ParensLoc(LParenLoc, RParenLoc), ReadOnlyLoc(ReadOnlyLoc),
584 NumVars(VarList.size()) {
585
586 llvm::uninitialized_copy(VarList, getTrailingObjects());
587 }
588
589public:
590 ArrayRef<Expr *> getVarList() const { return getTrailingObjects(NumVars); }
591
592 MutableArrayRef<Expr *> getVarList() { return getTrailingObjects(NumVars); }
593
594 static bool classof(const Stmt *T) {
595 return T->getStmtClass() == OpenACCCacheConstructClass;
596 }
597
599 unsigned NumVars);
600 static OpenACCCacheConstruct *
601 Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
602 SourceLocation LParenLoc, SourceLocation ReadOnlyLoc,
603 ArrayRef<Expr *> VarList, SourceLocation RParenLoc,
604 SourceLocation End);
605
606 SourceLocation getLParenLoc() const { return ParensLoc.getBegin(); }
607 SourceLocation getRParenLoc() const { return ParensLoc.getEnd(); }
608 bool hasReadOnly() const { return !ReadOnlyLoc.isInvalid(); }
609 SourceLocation getReadOnlyLoc() const { return ReadOnlyLoc; }
610
611 child_range children() {
612 Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects());
613 return child_range(Begin, Begin + NumVars);
614 }
615
616 const_child_range children() const {
617 Stmt *const *Begin = reinterpret_cast<Stmt *const *>(getTrailingObjects());
618 return const_child_range(Begin, Begin + NumVars);
619 }
620};
621
622// This class represents an 'init' construct, which has just a clause list.
623class OpenACCInitConstruct final
624 : public OpenACCConstructStmt,
625 private llvm::TrailingObjects<OpenACCInitConstruct,
626 const OpenACCClause *> {
627 friend TrailingObjects;
628 OpenACCInitConstruct(unsigned NumClauses)
629 : OpenACCConstructStmt(OpenACCInitConstructClass,
630 OpenACCDirectiveKind::Init, SourceLocation{},
631 SourceLocation{}, SourceLocation{}) {
632 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
633 setClauseList(getTrailingObjects(NumClauses));
634 }
635 OpenACCInitConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
636 SourceLocation End,
638 : OpenACCConstructStmt(OpenACCInitConstructClass,
639 OpenACCDirectiveKind::Init, Start, DirectiveLoc,
640 End) {
641 llvm::uninitialized_copy(Clauses, getTrailingObjects());
642 setClauseList(getTrailingObjects(Clauses.size()));
643 }
644
645public:
646 static bool classof(const Stmt *T) {
647 return T->getStmtClass() == OpenACCInitConstructClass;
648 }
650 unsigned NumClauses);
651 static OpenACCInitConstruct *Create(const ASTContext &C, SourceLocation Start,
652 SourceLocation DirectiveLoc,
653 SourceLocation End,
655};
656
657// This class represents a 'shutdown' construct, which has just a clause list.
658class OpenACCShutdownConstruct final
659 : public OpenACCConstructStmt,
660 private llvm::TrailingObjects<OpenACCShutdownConstruct,
661 const OpenACCClause *> {
662 friend TrailingObjects;
663 OpenACCShutdownConstruct(unsigned NumClauses)
664 : OpenACCConstructStmt(OpenACCShutdownConstructClass,
665 OpenACCDirectiveKind::Shutdown, SourceLocation{},
666 SourceLocation{}, SourceLocation{}) {
667 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
668 setClauseList(getTrailingObjects(NumClauses));
669 }
670 OpenACCShutdownConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
671 SourceLocation End,
673 : OpenACCConstructStmt(OpenACCShutdownConstructClass,
674 OpenACCDirectiveKind::Shutdown, Start,
675 DirectiveLoc, End) {
676 llvm::uninitialized_copy(Clauses, getTrailingObjects());
677 setClauseList(getTrailingObjects(Clauses.size()));
678 }
679
680public:
681 static bool classof(const Stmt *T) {
682 return T->getStmtClass() == OpenACCShutdownConstructClass;
683 }
685 unsigned NumClauses);
687 Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
688 SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
689};
690
691// This class represents a 'set' construct, which has just a clause list.
692class OpenACCSetConstruct final
693 : public OpenACCConstructStmt,
694 private llvm::TrailingObjects<OpenACCSetConstruct,
695 const OpenACCClause *> {
696 friend TrailingObjects;
697 OpenACCSetConstruct(unsigned NumClauses)
698 : OpenACCConstructStmt(OpenACCSetConstructClass,
699 OpenACCDirectiveKind::Set, SourceLocation{},
700 SourceLocation{}, SourceLocation{}) {
701 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
702 setClauseList(getTrailingObjects(NumClauses));
703 }
704
705 OpenACCSetConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
706 SourceLocation End,
708 : OpenACCConstructStmt(OpenACCSetConstructClass,
709 OpenACCDirectiveKind::Set, Start, DirectiveLoc,
710 End) {
711 llvm::uninitialized_copy(Clauses, getTrailingObjects());
712 setClauseList(getTrailingObjects(Clauses.size()));
713 }
714
715public:
716 static bool classof(const Stmt *T) {
717 return T->getStmtClass() == OpenACCSetConstructClass;
718 }
720 unsigned NumClauses);
721 static OpenACCSetConstruct *Create(const ASTContext &C, SourceLocation Start,
722 SourceLocation DirectiveLoc,
723 SourceLocation End,
725};
726// This class represents an 'update' construct, which has just a clause list.
727class OpenACCUpdateConstruct final
728 : public OpenACCConstructStmt,
729 private llvm::TrailingObjects<OpenACCUpdateConstruct,
730 const OpenACCClause *> {
731 friend TrailingObjects;
732 OpenACCUpdateConstruct(unsigned NumClauses)
733 : OpenACCConstructStmt(OpenACCUpdateConstructClass,
734 OpenACCDirectiveKind::Update, SourceLocation{},
735 SourceLocation{}, SourceLocation{}) {
736 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
737 setClauseList(getTrailingObjects(NumClauses));
738 }
739
740 OpenACCUpdateConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
741 SourceLocation End,
743 : OpenACCConstructStmt(OpenACCUpdateConstructClass,
744 OpenACCDirectiveKind::Update, Start, DirectiveLoc,
745 End) {
746 llvm::uninitialized_copy(Clauses, getTrailingObjects());
747 setClauseList(getTrailingObjects(Clauses.size()));
748 }
749
750public:
751 static bool classof(const Stmt *T) {
752 return T->getStmtClass() == OpenACCUpdateConstructClass;
753 }
755 unsigned NumClauses);
757 Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
758 SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
759};
760
761// This class represents the 'atomic' construct, which has an associated
762// statement, but no clauses.
763class OpenACCAtomicConstruct final
765 private llvm::TrailingObjects<OpenACCAtomicConstruct,
766 const OpenACCClause *> {
767
768 friend class ASTStmtReader;
769 friend TrailingObjects;
770 OpenACCAtomicKind AtomicKind = OpenACCAtomicKind::None;
771
772 OpenACCAtomicConstruct(unsigned NumClauses)
774 OpenACCAtomicConstructClass, OpenACCDirectiveKind::Atomic,
775 SourceLocation{}, SourceLocation{}, SourceLocation{},
776 /*AssociatedStmt=*/nullptr) {
777 std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses);
778 setClauseList(getTrailingObjects(NumClauses));
779 }
780
781 OpenACCAtomicConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
782 OpenACCAtomicKind AtKind, SourceLocation End,
784 Stmt *AssociatedStmt)
785 : OpenACCAssociatedStmtConstruct(OpenACCAtomicConstructClass,
786 OpenACCDirectiveKind::Atomic, Start,
787 DirectiveLoc, End, AssociatedStmt),
788 AtomicKind(AtKind) {
789 // Initialize the trailing storage.
790 llvm::uninitialized_copy(Clauses, getTrailingObjects());
791
792 setClauseList(getTrailingObjects(Clauses.size()));
793 }
794
795 void setAssociatedStmt(Stmt *S) {
796 OpenACCAssociatedStmtConstruct::setAssociatedStmt(S);
797 }
798
799public:
800 static bool classof(const Stmt *T) {
801 return T->getStmtClass() == OpenACCAtomicConstructClass;
802 }
803
805 unsigned NumClauses);
807 Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
808 OpenACCAtomicKind AtKind, SourceLocation End,
809 ArrayRef<const OpenACCClause *> Clauses, Stmt *AssociatedStmt);
810
811 OpenACCAtomicKind getAtomicKind() const { return AtomicKind; }
812 const Stmt *getAssociatedStmt() const {
813 return OpenACCAssociatedStmtConstruct::getAssociatedStmt();
814 }
816 return OpenACCAssociatedStmtConstruct::getAssociatedStmt();
817 }
818};
819
820} // namespace clang
821#endif // LLVM_CLANG_AST_STMTOPENACC_H
Defines some OpenACC-specific enums and functions.
Defines the clang::SourceLocation class and associated facilities.
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expressions Exprs)
Creates directive with a list of Clauses and 'x', 'v' and 'expr' parts of the atomic construct (see S...
static OMPAtomicDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell)
Creates an empty directive with the place for NumClauses clauses.
TypePropertyCache< Private > Cache
Definition Type.cpp:4792
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
static bool classof(const Stmt *T)
const Stmt * getAssociatedStmt() const
friend class ASTStmtReader
OpenACCAtomicKind getAtomicKind() const
bool hasReadOnly() const
child_range children()
SourceLocation getLParenLoc() const
MutableArrayRef< Expr * > getVarList()
const_child_range children() const
ArrayRef< Expr * > getVarList() const
friend class ASTStmtWriter
friend class ASTStmtReader
SourceLocation getReadOnlyLoc() const
SourceLocation getRParenLoc() const
static bool classof(const Stmt *T)
static bool classof(const Stmt *T)
const Stmt * getLoop() const
static bool classof(const Stmt *T)
const Stmt * getStructuredBlock() const
Stmt * getStructuredBlock()
static bool classof(const Stmt *T)
static bool classof(const Stmt *T)
static bool classof(const Stmt *T)
const Stmt * getStructuredBlock() const
static bool classof(const Stmt *T)
This class represents a 'loop' construct. The 'loop' construct applies to a 'for' loop (or range-for ...
bool isOrphanedLoopConstruct() const
OpenACC 3.3 2.9: An orphaned loop construct is a loop construct that is not lexically enclosed within...
friend class OpenACCCombinedConstruct
const Stmt * getLoop() const
OpenACCDirectiveKind getParentComputeConstructKind() const
friend class OpenACCComputeConstruct
friend class ASTContext
friend class OpenACCAssociatedStmtConstruct
friend class ASTStmtWriter
friend class ASTStmtReader
static bool classof(const Stmt *T)
static bool classof(const Stmt *T)
static bool classof(const Stmt *T)
static bool classof(const Stmt *T)
bool hasQueuesTag() const
ArrayRef< Expr * > getQueueIdExprs()
SourceLocation getQueuesLoc() const
SourceLocation getRParenLoc() const
child_range children()
static bool classof(const Stmt *T)
bool hasDevNumExpr() const
const_child_range children() const
friend class ASTStmtWriter
ArrayRef< Expr * > getQueueIdExprs() const
friend class ASTStmtReader
SourceLocation getLParenLoc() const
Expr * getDevNumExpr() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
This is a base class for any OpenACC statement-level constructs that have an associated statement.
Definition StmtOpenACC.h:81
const_child_range children() const
const Stmt * getAssociatedStmt() const
Definition StmtOpenACC.h:97
OpenACCAssociatedStmtConstruct(StmtClass SC, OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, Stmt *AssocStmt)
Definition StmtOpenACC.h:88
static bool classof(const Stmt *T)
SourceLocation getEndLoc() const
Definition StmtOpenACC.h:65
SourceLocation getBeginLoc() const
Definition StmtOpenACC.h:64
OpenACCDirectiveKind getDirectiveKind() const
Definition StmtOpenACC.h:57
void setClauseList(MutableArrayRef< const OpenACCClause * > NewClauses)
Definition StmtOpenACC.h:51
ArrayRef< const OpenACCClause * > clauses() const
Definition StmtOpenACC.h:67
const_child_range children() const
Definition StmtOpenACC.h:73
SourceLocation getDirectiveLoc() const
Definition StmtOpenACC.h:66
static bool classof(const Stmt *S)
Definition StmtOpenACC.h:59
OpenACCConstructStmt(StmtClass SC, OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End)
Definition StmtOpenACC.h:44
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition Stmt.h:85
StmtIterator child_iterator
Child Iterators: All subclasses must implement 'children' to permit easy iteration over the substatem...
Definition Stmt.h:1558
StmtClass getStmtClass() const
Definition Stmt.h:1472
Stmt(StmtClass SC, EmptyShell)
Construct an empty statement.
Definition Stmt.h:1454
llvm::iterator_range< child_iterator > child_range
Definition Stmt.h:1561
llvm::iterator_range< const_child_iterator > const_child_range
Definition Stmt.h:1562
The JSON file list parser is used to communicate input to InstallAPI.
OpenACCDirectiveKind
bool isOpenACCComputeDirectiveKind(OpenACCDirectiveKind K)
void setStructuredBlock(Stmt *S)
Stmt * getStructuredBlock()
static OpenACCComputeConstruct * CreateEmpty(const ASTContext &C, unsigned NumClauses)
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
static bool classof(const Stmt *T)
const FunctionProtoType * T
setClauseList(getTrailingObjects(NumClauses))