xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/OpenACCClause.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/StmtIterator.h"
19 #include "clang/Basic/OpenACCKinds.h"
20 #include "llvm/ADT/STLExtras.h"
21 
22 #include <utility>
23 #include <variant>
24 
25 namespace clang {
26 /// This is the base type for all OpenACC Clauses.
27 class OpenACCClause {
28   OpenACCClauseKind Kind;
29   SourceRange Location;
30 
31 protected:
OpenACCClause(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation EndLoc)32   OpenACCClause(OpenACCClauseKind K, SourceLocation BeginLoc,
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 
39 public:
getClauseKind()40   OpenACCClauseKind getClauseKind() const { return Kind; }
getBeginLoc()41   SourceLocation getBeginLoc() const { return Location.getBegin(); }
getEndLoc()42   SourceLocation getEndLoc() const { return Location.getEnd(); }
getSourceRange()43   SourceRange getSourceRange() const { return Location; }
44 
classof(const OpenACCClause *)45   static bool classof(const OpenACCClause *) { return true; }
46 
47   using child_iterator = StmtIterator;
48   using const_child_iterator = ConstStmtIterator;
49   using child_range = llvm::iterator_range<child_iterator>;
50   using const_child_range = llvm::iterator_range<const_child_iterator>;
51 
52   child_range children();
children()53   const_child_range children() const {
54     auto Children = const_cast<OpenACCClause *>(this)->children();
55     return const_child_range(Children.begin(), Children.end());
56   }
57 
58   virtual ~OpenACCClause() = default;
59 };
60 
61 // Represents the 'auto' clause.
62 class OpenACCAutoClause : public OpenACCClause {
63 protected:
OpenACCAutoClause(SourceLocation BeginLoc,SourceLocation EndLoc)64   OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc)
65       : OpenACCClause(OpenACCClauseKind::Auto, BeginLoc, EndLoc) {}
66 
67 public:
classof(const OpenACCClause * C)68   static bool classof(const OpenACCClause *C) {
69     return C->getClauseKind() == OpenACCClauseKind::Auto;
70   }
71 
72   static OpenACCAutoClause *
73   Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
74 
children()75   child_range children() {
76     return child_range(child_iterator(), child_iterator());
77   }
children()78   const_child_range children() const {
79     return const_child_range(const_child_iterator(), const_child_iterator());
80   }
81 };
82 
83 // Represents the 'finalize' clause.
84 class OpenACCFinalizeClause : public OpenACCClause {
85 protected:
OpenACCFinalizeClause(SourceLocation BeginLoc,SourceLocation EndLoc)86   OpenACCFinalizeClause(SourceLocation BeginLoc, SourceLocation EndLoc)
87       : OpenACCClause(OpenACCClauseKind::Finalize, BeginLoc, EndLoc) {}
88 
89 public:
classof(const OpenACCClause * C)90   static bool classof(const OpenACCClause *C) {
91     return C->getClauseKind() == OpenACCClauseKind::Finalize;
92   }
93 
94   static OpenACCFinalizeClause *
95   Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
96 
children()97   child_range children() {
98     return child_range(child_iterator(), child_iterator());
99   }
children()100   const_child_range children() const {
101     return const_child_range(const_child_iterator(), const_child_iterator());
102   }
103 };
104 
105 // Represents the 'if_present' clause.
106 class OpenACCIfPresentClause : public OpenACCClause {
107 protected:
OpenACCIfPresentClause(SourceLocation BeginLoc,SourceLocation EndLoc)108   OpenACCIfPresentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
109       : OpenACCClause(OpenACCClauseKind::IfPresent, BeginLoc, EndLoc) {}
110 
111 public:
classof(const OpenACCClause * C)112   static bool classof(const OpenACCClause *C) {
113     return C->getClauseKind() == OpenACCClauseKind::IfPresent;
114   }
115 
116   static OpenACCIfPresentClause *
117   Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
118 
children()119   child_range children() {
120     return child_range(child_iterator(), child_iterator());
121   }
children()122   const_child_range children() const {
123     return const_child_range(const_child_iterator(), const_child_iterator());
124   }
125 };
126 
127 // Represents the 'independent' clause.
128 class OpenACCIndependentClause : public OpenACCClause {
129 protected:
OpenACCIndependentClause(SourceLocation BeginLoc,SourceLocation EndLoc)130   OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
131       : OpenACCClause(OpenACCClauseKind::Independent, BeginLoc, EndLoc) {}
132 
133 public:
classof(const OpenACCClause * C)134   static bool classof(const OpenACCClause *C) {
135     return C->getClauseKind() == OpenACCClauseKind::Independent;
136   }
137 
138   static OpenACCIndependentClause *
139   Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
140 
children()141   child_range children() {
142     return child_range(child_iterator(), child_iterator());
143   }
children()144   const_child_range children() const {
145     return const_child_range(const_child_iterator(), const_child_iterator());
146   }
147 };
148 // Represents the 'seq' clause.
149 class OpenACCSeqClause : public OpenACCClause {
150 protected:
OpenACCSeqClause(SourceLocation BeginLoc,SourceLocation EndLoc)151   OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc)
152       : OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {}
153 
154 public:
classof(const OpenACCClause * C)155   static bool classof(const OpenACCClause *C) {
156     return C->getClauseKind() == OpenACCClauseKind::Seq;
157   }
158 
159   static OpenACCSeqClause *
160   Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
161 
children()162   child_range children() {
163     return child_range(child_iterator(), child_iterator());
164   }
children()165   const_child_range children() const {
166     return const_child_range(const_child_iterator(), const_child_iterator());
167   }
168 };
169 // Represents the 'nohost' clause.
170 class OpenACCNoHostClause : public OpenACCClause {
171 protected:
OpenACCNoHostClause(SourceLocation BeginLoc,SourceLocation EndLoc)172   OpenACCNoHostClause(SourceLocation BeginLoc, SourceLocation EndLoc)
173       : OpenACCClause(OpenACCClauseKind::NoHost, BeginLoc, EndLoc) {}
174 
175 public:
classof(const OpenACCClause * C)176   static bool classof(const OpenACCClause *C) {
177     return C->getClauseKind() == OpenACCClauseKind::NoHost;
178   }
179   static OpenACCNoHostClause *
180   Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
181 
children()182   child_range children() {
183     return child_range(child_iterator(), child_iterator());
184   }
children()185   const_child_range children() const {
186     return const_child_range(const_child_iterator(), const_child_iterator());
187   }
188 };
189 
190 /// Represents a clause that has a list of parameters.
191 class OpenACCClauseWithParams : public OpenACCClause {
192   /// Location of the '('.
193   SourceLocation LParenLoc;
194 
195 protected:
OpenACCClauseWithParams(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,SourceLocation EndLoc)196   OpenACCClauseWithParams(OpenACCClauseKind K, SourceLocation BeginLoc,
197                           SourceLocation LParenLoc, SourceLocation EndLoc)
198       : OpenACCClause(K, BeginLoc, EndLoc), LParenLoc(LParenLoc) {}
199 
200 public:
201   static bool classof(const OpenACCClause *C);
202 
getLParenLoc()203   SourceLocation getLParenLoc() const { return LParenLoc; }
204 
children()205   child_range children() {
206     return child_range(child_iterator(), child_iterator());
207   }
children()208   const_child_range children() const {
209     return const_child_range(const_child_iterator(), const_child_iterator());
210   }
211 };
212 
213 class OpenACCBindClause final : public OpenACCClauseWithParams {
214   std::variant<const StringLiteral *, const IdentifierInfo *> Argument;
215 
OpenACCBindClause(SourceLocation BeginLoc,SourceLocation LParenLoc,const clang::StringLiteral * SL,SourceLocation EndLoc)216   OpenACCBindClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
217                     const clang::StringLiteral *SL, SourceLocation EndLoc)
218       : OpenACCClauseWithParams(OpenACCClauseKind::Bind, BeginLoc, LParenLoc,
219                                 EndLoc),
220         Argument(SL) {}
OpenACCBindClause(SourceLocation BeginLoc,SourceLocation LParenLoc,const IdentifierInfo * ID,SourceLocation EndLoc)221   OpenACCBindClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
222                     const IdentifierInfo *ID, SourceLocation EndLoc)
223       : OpenACCClauseWithParams(OpenACCClauseKind::Bind, BeginLoc, LParenLoc,
224                                 EndLoc),
225         Argument(ID) {}
226 
227 public:
classof(const OpenACCClause * C)228   static bool classof(const OpenACCClause *C) {
229     return C->getClauseKind() == OpenACCClauseKind::Bind;
230   }
231   static OpenACCBindClause *Create(const ASTContext &C, SourceLocation BeginLoc,
232                                    SourceLocation LParenLoc,
233                                    const IdentifierInfo *ID,
234                                    SourceLocation EndLoc);
235   static OpenACCBindClause *Create(const ASTContext &C, SourceLocation BeginLoc,
236                                    SourceLocation LParenLoc,
237                                    const StringLiteral *SL,
238                                    SourceLocation EndLoc);
239 
isStringArgument()240   bool isStringArgument() const {
241     return std::holds_alternative<const StringLiteral *>(Argument);
242   }
243 
getStringArgument()244   const StringLiteral *getStringArgument() const {
245     return std::get<const StringLiteral *>(Argument);
246   }
247 
isIdentifierArgument()248   bool isIdentifierArgument() const {
249     return std::holds_alternative<const IdentifierInfo *>(Argument);
250   }
251 
getIdentifierArgument()252   const IdentifierInfo *getIdentifierArgument() const {
253     return std::get<const IdentifierInfo *>(Argument);
254   }
255 };
256 
257 bool operator==(const OpenACCBindClause &LHS, const OpenACCBindClause &RHS);
258 inline bool operator!=(const OpenACCBindClause &LHS,
259                        const OpenACCBindClause &RHS) {
260   return !(LHS == RHS);
261 }
262 
263 using DeviceTypeArgument = IdentifierLoc;
264 /// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or
265 /// an identifier. The 'asterisk' means 'the rest'.
266 class OpenACCDeviceTypeClause final
267     : public OpenACCClauseWithParams,
268       private llvm::TrailingObjects<OpenACCDeviceTypeClause,
269                                    DeviceTypeArgument> {
270   friend TrailingObjects;
271   // Data stored in trailing objects as IdentifierInfo* /SourceLocation pairs. A
272   // nullptr IdentifierInfo* represents an asterisk.
273   unsigned NumArchs;
OpenACCDeviceTypeClause(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<DeviceTypeArgument> Archs,SourceLocation EndLoc)274   OpenACCDeviceTypeClause(OpenACCClauseKind K, SourceLocation BeginLoc,
275                           SourceLocation LParenLoc,
276                           ArrayRef<DeviceTypeArgument> Archs,
277                           SourceLocation EndLoc)
278       : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
279         NumArchs(Archs.size()) {
280     assert(
281         (K == OpenACCClauseKind::DeviceType || K == OpenACCClauseKind::DType) &&
282         "Invalid clause kind for device-type");
283 
284     assert(!llvm::any_of(Archs, [](const DeviceTypeArgument &Arg) {
285       return Arg.getLoc().isInvalid();
286     }) && "Invalid SourceLocation for an argument");
287 
288     assert((Archs.size() == 1 ||
289             !llvm::any_of(Archs,
290                           [](const DeviceTypeArgument &Arg) {
291                             return Arg.getIdentifierInfo() == nullptr;
292                           })) &&
293            "Only a single asterisk version is permitted, and must be the "
294            "only one");
295 
296     llvm::uninitialized_copy(Archs, getTrailingObjects());
297   }
298 
299 public:
classof(const OpenACCClause * C)300   static bool classof(const OpenACCClause *C) {
301     return C->getClauseKind() == OpenACCClauseKind::DType ||
302            C->getClauseKind() == OpenACCClauseKind::DeviceType;
303   }
hasAsterisk()304   bool hasAsterisk() const {
305     return getArchitectures().size() > 0 &&
306            getArchitectures()[0].getIdentifierInfo() == nullptr;
307   }
308 
getArchitectures()309   ArrayRef<DeviceTypeArgument> getArchitectures() const {
310     return getTrailingObjects(NumArchs);
311   }
312 
313   static OpenACCDeviceTypeClause *
314   Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc,
315          SourceLocation LParenLoc, ArrayRef<DeviceTypeArgument> Archs,
316          SourceLocation EndLoc);
317 };
318 
319 /// A 'default' clause, has the optional 'none' or 'present' argument.
320 class OpenACCDefaultClause : public OpenACCClauseWithParams {
321   friend class ASTReaderStmt;
322   friend class ASTWriterStmt;
323 
324   OpenACCDefaultClauseKind DefaultClauseKind;
325 
326 protected:
OpenACCDefaultClause(OpenACCDefaultClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,SourceLocation EndLoc)327   OpenACCDefaultClause(OpenACCDefaultClauseKind K, SourceLocation BeginLoc,
328                        SourceLocation LParenLoc, SourceLocation EndLoc)
329       : OpenACCClauseWithParams(OpenACCClauseKind::Default, BeginLoc, LParenLoc,
330                                 EndLoc),
331         DefaultClauseKind(K) {
332     assert((DefaultClauseKind == OpenACCDefaultClauseKind::None ||
333             DefaultClauseKind == OpenACCDefaultClauseKind::Present) &&
334            "Invalid Clause Kind");
335   }
336 
337 public:
classof(const OpenACCClause * C)338   static bool classof(const OpenACCClause *C) {
339     return C->getClauseKind() == OpenACCClauseKind::Default;
340   }
getDefaultClauseKind()341   OpenACCDefaultClauseKind getDefaultClauseKind() const {
342     return DefaultClauseKind;
343   }
344 
345   static OpenACCDefaultClause *Create(const ASTContext &C,
346                                       OpenACCDefaultClauseKind K,
347                                       SourceLocation BeginLoc,
348                                       SourceLocation LParenLoc,
349                                       SourceLocation EndLoc);
350 };
351 
352 /// Represents one of the handful of classes that has an optional/required
353 /// 'condition' expression as an argument.
354 class OpenACCClauseWithCondition : public OpenACCClauseWithParams {
355   Expr *ConditionExpr = nullptr;
356 
357 protected:
OpenACCClauseWithCondition(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,Expr * ConditionExpr,SourceLocation EndLoc)358   OpenACCClauseWithCondition(OpenACCClauseKind K, SourceLocation BeginLoc,
359                              SourceLocation LParenLoc, Expr *ConditionExpr,
360                              SourceLocation EndLoc)
361       : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
362         ConditionExpr(ConditionExpr) {}
363 
364 public:
365   static bool classof(const OpenACCClause *C);
366 
hasConditionExpr()367   bool hasConditionExpr() const { return ConditionExpr; }
getConditionExpr()368   const Expr *getConditionExpr() const { return ConditionExpr; }
getConditionExpr()369   Expr *getConditionExpr() { return ConditionExpr; }
370 
children()371   child_range children() {
372     if (ConditionExpr)
373       return child_range(reinterpret_cast<Stmt **>(&ConditionExpr),
374                          reinterpret_cast<Stmt **>(&ConditionExpr + 1));
375     return child_range(child_iterator(), child_iterator());
376   }
377 
children()378   const_child_range children() const {
379     if (ConditionExpr)
380       return const_child_range(
381           reinterpret_cast<Stmt *const *>(&ConditionExpr),
382           reinterpret_cast<Stmt *const *>(&ConditionExpr + 1));
383     return const_child_range(const_child_iterator(), const_child_iterator());
384   }
385 };
386 
387 /// An 'if' clause, which has a required condition expression.
388 class OpenACCIfClause : public OpenACCClauseWithCondition {
389 protected:
390   OpenACCIfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
391                   Expr *ConditionExpr, SourceLocation EndLoc);
392 
393 public:
classof(const OpenACCClause * C)394   static bool classof(const OpenACCClause *C) {
395     return C->getClauseKind() == OpenACCClauseKind::If;
396   }
397   static OpenACCIfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
398                                  SourceLocation LParenLoc, Expr *ConditionExpr,
399                                  SourceLocation EndLoc);
400 };
401 
402 /// A 'self' clause, which has an optional condition expression, or, in the
403 /// event of an 'update' directive, contains a 'VarList'.
404 class OpenACCSelfClause final
405     : public OpenACCClauseWithParams,
406       private llvm::TrailingObjects<OpenACCSelfClause, Expr *> {
407   friend TrailingObjects;
408   // Holds whether this HAS a condition expression. Lacks a value if this is NOT
409   // a condition-expr self clause.
410   std::optional<bool> HasConditionExpr;
411   // Holds the number of stored expressions.  In the case of a condition-expr
412   // self clause, this is expected to be ONE (and there to be 1 trailing
413   // object), whether or not that is null.
414   unsigned NumExprs;
415 
416   OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
417                     Expr *ConditionExpr, SourceLocation EndLoc);
418   OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
419                     ArrayRef<Expr *> VarList, SourceLocation EndLoc);
420 
421   // Intentionally internal, meant to be an implementation detail of everything
422   // else. All non-internal uses should go through getConditionExpr/getVarList.
getExprs()423   ArrayRef<Expr *> getExprs() const { return getTrailingObjects(NumExprs); }
424 
425 public:
classof(const OpenACCClause * C)426   static bool classof(const OpenACCClause *C) {
427     return C->getClauseKind() == OpenACCClauseKind::Self;
428   }
429 
isConditionExprClause()430   bool isConditionExprClause() const { return HasConditionExpr.has_value(); }
isVarListClause()431   bool isVarListClause() const { return !isConditionExprClause(); }
isEmptySelfClause()432   bool isEmptySelfClause() const {
433     return (isConditionExprClause() && !hasConditionExpr()) ||
434            (!isConditionExprClause() && getVarList().empty());
435   }
436 
hasConditionExpr()437   bool hasConditionExpr() const {
438     assert(HasConditionExpr.has_value() &&
439            "VarList Self Clause asked about condition expression");
440     return *HasConditionExpr;
441   }
442 
getConditionExpr()443   const Expr *getConditionExpr() const {
444     assert(HasConditionExpr.has_value() &&
445            "VarList Self Clause asked about condition expression");
446     assert(getExprs().size() == 1 &&
447            "ConditionExpr Self Clause with too many Exprs");
448     return getExprs()[0];
449   }
450 
getConditionExpr()451   Expr *getConditionExpr() {
452     assert(HasConditionExpr.has_value() &&
453            "VarList Self Clause asked about condition expression");
454     assert(getExprs().size() == 1 &&
455            "ConditionExpr Self Clause with too many Exprs");
456     return getExprs()[0];
457   }
458 
getVarList()459   ArrayRef<Expr *> getVarList() {
460     assert(!HasConditionExpr.has_value() &&
461            "Condition Expr self clause asked about var list");
462     return getExprs();
463   }
getVarList()464   ArrayRef<Expr *> getVarList() const {
465     assert(!HasConditionExpr.has_value() &&
466            "Condition Expr self clause asked about var list");
467     return getExprs();
468   }
469 
children()470   child_range children() {
471     return child_range(
472         reinterpret_cast<Stmt **>(getTrailingObjects()),
473         reinterpret_cast<Stmt **>(getTrailingObjects() + NumExprs));
474   }
475 
children()476   const_child_range children() const {
477     child_range Children = const_cast<OpenACCSelfClause *>(this)->children();
478     return const_child_range(Children.begin(), Children.end());
479   }
480 
481   static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
482                                    SourceLocation LParenLoc,
483                                    Expr *ConditionExpr, SourceLocation EndLoc);
484   static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
485                                    SourceLocation LParenLoc,
486                                    ArrayRef<Expr *> ConditionExpr,
487                                    SourceLocation EndLoc);
488 };
489 
490 /// Represents a clause that has one or more expressions associated with it.
491 class OpenACCClauseWithExprs : public OpenACCClauseWithParams {
492   MutableArrayRef<Expr *> Exprs;
493 
494 protected:
OpenACCClauseWithExprs(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,SourceLocation EndLoc)495   OpenACCClauseWithExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
496                          SourceLocation LParenLoc, SourceLocation EndLoc)
497       : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {}
498 
499   /// Used only for initialization, the leaf class can initialize this to
500   /// trailing storage.
setExprs(MutableArrayRef<Expr * > NewExprs)501   void setExprs(MutableArrayRef<Expr *> NewExprs) {
502     assert(Exprs.empty() && "Cannot change Exprs list");
503     Exprs = NewExprs;
504   }
505 
506   /// Used only for initialization, the leaf class can initialize this to
507   /// trailing storage, and initialize the data in the trailing storage as well.
setExprs(MutableArrayRef<Expr * > NewStorage,ArrayRef<Expr * > Exprs)508   void setExprs(MutableArrayRef<Expr *> NewStorage, ArrayRef<Expr *> Exprs) {
509     assert(NewStorage.size() == Exprs.size());
510     llvm::uninitialized_copy(Exprs, NewStorage.begin());
511     setExprs(NewStorage);
512   }
513 
514   /// Gets the entire list of expressions, but leave it to the
515   /// individual clauses to expose this how they'd like.
getExprs()516   ArrayRef<Expr *> getExprs() const { return Exprs; }
517 
518 public:
519   static bool classof(const OpenACCClause *C);
children()520   child_range children() {
521     return child_range(reinterpret_cast<Stmt **>(Exprs.begin()),
522                        reinterpret_cast<Stmt **>(Exprs.end()));
523   }
524 
children()525   const_child_range children() const {
526     child_range Children =
527         const_cast<OpenACCClauseWithExprs *>(this)->children();
528     return const_child_range(Children.begin(), Children.end());
529   }
530 };
531 
532 // Represents the 'devnum' and expressions lists for the 'wait' clause.
533 class OpenACCWaitClause final
534     : public OpenACCClauseWithExprs,
535       private llvm::TrailingObjects<OpenACCWaitClause, Expr *> {
536   friend TrailingObjects;
537   SourceLocation QueuesLoc;
OpenACCWaitClause(SourceLocation BeginLoc,SourceLocation LParenLoc,Expr * DevNumExpr,SourceLocation QueuesLoc,ArrayRef<Expr * > QueueIdExprs,SourceLocation EndLoc)538   OpenACCWaitClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
539                     Expr *DevNumExpr, SourceLocation QueuesLoc,
540                     ArrayRef<Expr *> QueueIdExprs, SourceLocation EndLoc)
541       : OpenACCClauseWithExprs(OpenACCClauseKind::Wait, BeginLoc, LParenLoc,
542                                EndLoc),
543         QueuesLoc(QueuesLoc) {
544     // The first element of the trailing storage is always the devnum expr,
545     // whether it is used or not.
546     auto *Exprs = getTrailingObjects();
547     llvm::uninitialized_copy(ArrayRef(DevNumExpr), Exprs);
548     llvm::uninitialized_copy(QueueIdExprs, Exprs + 1);
549     setExprs(getTrailingObjects(QueueIdExprs.size() + 1));
550   }
551 
552 public:
classof(const OpenACCClause * C)553   static bool classof(const OpenACCClause *C) {
554     return C->getClauseKind() == OpenACCClauseKind::Wait;
555   }
556   static OpenACCWaitClause *Create(const ASTContext &C, SourceLocation BeginLoc,
557                                    SourceLocation LParenLoc, Expr *DevNumExpr,
558                                    SourceLocation QueuesLoc,
559                                    ArrayRef<Expr *> QueueIdExprs,
560                                    SourceLocation EndLoc);
561 
hasQueuesTag()562   bool hasQueuesTag() const { return !QueuesLoc.isInvalid(); }
getQueuesLoc()563   SourceLocation getQueuesLoc() const { return QueuesLoc; }
hasDevNumExpr()564   bool hasDevNumExpr() const { return getExprs()[0]; }
getDevNumExpr()565   Expr *getDevNumExpr() const { return getExprs()[0]; }
getQueueIdExprs()566   ArrayRef<Expr *> getQueueIdExprs() {
567     return OpenACCClauseWithExprs::getExprs().drop_front();
568   }
getQueueIdExprs()569   ArrayRef<Expr *> getQueueIdExprs() const {
570     return OpenACCClauseWithExprs::getExprs().drop_front();
571   }
572   // If this is a plain `wait` (no parens) this returns 'false'. Else Sema/Parse
573   // ensures we have at least one QueueId expression.
hasExprs()574   bool hasExprs() const { return getLParenLoc().isValid(); }
575 };
576 
577 class OpenACCNumGangsClause final
578     : public OpenACCClauseWithExprs,
579       private llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> {
580   friend TrailingObjects;
581 
OpenACCNumGangsClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > IntExprs,SourceLocation EndLoc)582   OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
583                         ArrayRef<Expr *> IntExprs, SourceLocation EndLoc)
584       : OpenACCClauseWithExprs(OpenACCClauseKind::NumGangs, BeginLoc, LParenLoc,
585                                EndLoc) {
586     setExprs(getTrailingObjects(IntExprs.size()), IntExprs);
587   }
588 
589 public:
classof(const OpenACCClause * C)590   static bool classof(const OpenACCClause *C) {
591     return C->getClauseKind() == OpenACCClauseKind::NumGangs;
592   }
593   static OpenACCNumGangsClause *
594   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
595          ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
596 
getIntExprs()597   ArrayRef<Expr *> getIntExprs() { return OpenACCClauseWithExprs::getExprs(); }
598 
getIntExprs()599   ArrayRef<Expr *> getIntExprs() const {
600     return OpenACCClauseWithExprs::getExprs();
601   }
602 };
603 
604 class OpenACCTileClause final
605     : public OpenACCClauseWithExprs,
606       private llvm::TrailingObjects<OpenACCTileClause, Expr *> {
607   friend TrailingObjects;
OpenACCTileClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > SizeExprs,SourceLocation EndLoc)608   OpenACCTileClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
609                     ArrayRef<Expr *> SizeExprs, SourceLocation EndLoc)
610       : OpenACCClauseWithExprs(OpenACCClauseKind::Tile, BeginLoc, LParenLoc,
611                                EndLoc) {
612     setExprs(getTrailingObjects(SizeExprs.size()), SizeExprs);
613   }
614 
615 public:
classof(const OpenACCClause * C)616   static bool classof(const OpenACCClause *C) {
617     return C->getClauseKind() == OpenACCClauseKind::Tile;
618   }
619   static OpenACCTileClause *Create(const ASTContext &C, SourceLocation BeginLoc,
620                                    SourceLocation LParenLoc,
621                                    ArrayRef<Expr *> SizeExprs,
622                                    SourceLocation EndLoc);
getSizeExprs()623   ArrayRef<Expr *> getSizeExprs() { return OpenACCClauseWithExprs::getExprs(); }
624 
getSizeExprs()625   ArrayRef<Expr *> getSizeExprs() const {
626     return OpenACCClauseWithExprs::getExprs();
627   }
628 };
629 
630 /// Represents one of a handful of clauses that have a single integer
631 /// expression.
632 class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs {
633   Expr *IntExpr;
634 
635 protected:
OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,Expr * IntExpr,SourceLocation EndLoc)636   OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc,
637                                  SourceLocation LParenLoc, Expr *IntExpr,
638                                  SourceLocation EndLoc)
639       : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc),
640         IntExpr(IntExpr) {
641     if (IntExpr)
642       setExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
643   }
644 
645 public:
646   static bool classof(const OpenACCClause *C);
hasIntExpr()647   bool hasIntExpr() const { return !getExprs().empty(); }
getIntExpr()648   const Expr *getIntExpr() const {
649     return hasIntExpr() ? getExprs()[0] : nullptr;
650   }
651 
getIntExpr()652   Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; };
653 };
654 
655 class OpenACCGangClause final
656     : public OpenACCClauseWithExprs,
657       private llvm::TrailingObjects<OpenACCGangClause, Expr *, OpenACCGangKind> {
658   friend TrailingObjects;
659 protected:
660   OpenACCGangClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
661                     ArrayRef<OpenACCGangKind> GangKinds,
662                     ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
663 
getGangKind(unsigned I)664   OpenACCGangKind getGangKind(unsigned I) const {
665     return getTrailingObjects<OpenACCGangKind>()[I];
666   }
667 
668 public:
classof(const OpenACCClause * C)669   static bool classof(const OpenACCClause *C) {
670     return C->getClauseKind() == OpenACCClauseKind::Gang;
671   }
672 
numTrailingObjects(OverloadToken<Expr * >)673   size_t numTrailingObjects(OverloadToken<Expr *>) const {
674     return getNumExprs();
675   }
676 
getNumExprs()677   unsigned getNumExprs() const { return getExprs().size(); }
getExpr(unsigned I)678   std::pair<OpenACCGangKind, const Expr *> getExpr(unsigned I) const {
679     return {getGangKind(I), getExprs()[I]};
680   }
681 
hasExprOfKind(OpenACCGangKind GK)682   bool hasExprOfKind(OpenACCGangKind GK) const {
683     for (unsigned I = 0; I < getNumExprs(); ++I) {
684       if (getGangKind(I) == GK)
685         return true;
686     }
687     return false;
688   }
689 
690   static OpenACCGangClause *
691   Create(const ASTContext &Ctx, SourceLocation BeginLoc,
692          SourceLocation LParenLoc, ArrayRef<OpenACCGangKind> GangKinds,
693          ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
694 };
695 
696 class OpenACCWorkerClause : public OpenACCClauseWithSingleIntExpr {
697 protected:
698   OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
699                       Expr *IntExpr, SourceLocation EndLoc);
700 
701 public:
classof(const OpenACCClause * C)702   static bool classof(const OpenACCClause *C) {
703     return C->getClauseKind() == OpenACCClauseKind::Worker;
704   }
705 
706   static OpenACCWorkerClause *Create(const ASTContext &Ctx,
707                                      SourceLocation BeginLoc,
708                                      SourceLocation LParenLoc, Expr *IntExpr,
709                                      SourceLocation EndLoc);
710 };
711 
712 class OpenACCVectorClause : public OpenACCClauseWithSingleIntExpr {
713 protected:
714   OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
715                       Expr *IntExpr, SourceLocation EndLoc);
716 
717 public:
classof(const OpenACCClause * C)718   static bool classof(const OpenACCClause *C) {
719     return C->getClauseKind() == OpenACCClauseKind::Vector;
720   }
721 
722   static OpenACCVectorClause *Create(const ASTContext &Ctx,
723                                      SourceLocation BeginLoc,
724                                      SourceLocation LParenLoc, Expr *IntExpr,
725                                      SourceLocation EndLoc);
726 };
727 
728 class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
729   OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
730                           Expr *IntExpr, SourceLocation EndLoc);
731 
732 public:
classof(const OpenACCClause * C)733   static bool classof(const OpenACCClause *C) {
734     return C->getClauseKind() == OpenACCClauseKind::NumWorkers;
735   }
736   static OpenACCNumWorkersClause *Create(const ASTContext &C,
737                                          SourceLocation BeginLoc,
738                                          SourceLocation LParenLoc,
739                                          Expr *IntExpr, SourceLocation EndLoc);
740 };
741 
742 class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr {
743   OpenACCVectorLengthClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
744                             Expr *IntExpr, SourceLocation EndLoc);
745 
746 public:
classof(const OpenACCClause * C)747   static bool classof(const OpenACCClause *C) {
748     return C->getClauseKind() == OpenACCClauseKind::VectorLength;
749   }
750   static OpenACCVectorLengthClause *
751   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
752          Expr *IntExpr, SourceLocation EndLoc);
753 };
754 
755 class OpenACCAsyncClause : public OpenACCClauseWithSingleIntExpr {
756   OpenACCAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
757                      Expr *IntExpr, SourceLocation EndLoc);
758 
759 public:
classof(const OpenACCClause * C)760   static bool classof(const OpenACCClause *C) {
761     return C->getClauseKind() == OpenACCClauseKind::Async;
762   }
763   static OpenACCAsyncClause *Create(const ASTContext &C,
764                                     SourceLocation BeginLoc,
765                                     SourceLocation LParenLoc, Expr *IntExpr,
766                                     SourceLocation EndLoc);
767 };
768 
769 class OpenACCDeviceNumClause : public OpenACCClauseWithSingleIntExpr {
770   OpenACCDeviceNumClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
771                      Expr *IntExpr, SourceLocation EndLoc);
772 
773 public:
classof(const OpenACCClause * C)774   static bool classof(const OpenACCClause *C) {
775     return C->getClauseKind() == OpenACCClauseKind::DeviceNum;
776   }
777   static OpenACCDeviceNumClause *Create(const ASTContext &C,
778                                         SourceLocation BeginLoc,
779                                         SourceLocation LParenLoc, Expr *IntExpr,
780                                         SourceLocation EndLoc);
781 };
782 
783 class OpenACCDefaultAsyncClause : public OpenACCClauseWithSingleIntExpr {
784   OpenACCDefaultAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
785                             Expr *IntExpr, SourceLocation EndLoc);
786 
787 public:
classof(const OpenACCClause * C)788   static bool classof(const OpenACCClause *C) {
789     return C->getClauseKind() == OpenACCClauseKind::DefaultAsync;
790   }
791   static OpenACCDefaultAsyncClause *
792   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
793          Expr *IntExpr, SourceLocation EndLoc);
794 };
795 
796 /// Represents a 'collapse' clause on a 'loop' construct. This clause takes an
797 /// integer constant expression 'N' that represents how deep to collapse the
798 /// construct. It also takes an optional 'force' tag that permits intervening
799 /// code in the loops.
800 class OpenACCCollapseClause : public OpenACCClauseWithSingleIntExpr {
801   bool HasForce = false;
802 
803   OpenACCCollapseClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
804                         bool HasForce, Expr *LoopCount, SourceLocation EndLoc);
805 
806 public:
getLoopCount()807   const Expr *getLoopCount() const { return getIntExpr(); }
getLoopCount()808   Expr *getLoopCount() { return getIntExpr(); }
809 
hasForce()810   bool hasForce() const { return HasForce; }
811 
classof(const OpenACCClause * C)812   static bool classof(const OpenACCClause *C) {
813     return C->getClauseKind() == OpenACCClauseKind::Collapse;
814   }
815 
816   static OpenACCCollapseClause *Create(const ASTContext &C,
817                                        SourceLocation BeginLoc,
818                                        SourceLocation LParenLoc, bool HasForce,
819                                        Expr *LoopCount, SourceLocation EndLoc);
820 };
821 
822 /// Represents a clause with one or more 'var' objects, represented as an expr,
823 /// as its arguments. Var-list is expected to be stored in trailing storage.
824 /// For now, we're just storing the original expression in its entirety, unlike
825 /// OMP which has to do a bunch of work to create a private.
826 class OpenACCClauseWithVarList : public OpenACCClauseWithExprs {
827 protected:
OpenACCClauseWithVarList(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,SourceLocation EndLoc)828   OpenACCClauseWithVarList(OpenACCClauseKind K, SourceLocation BeginLoc,
829                            SourceLocation LParenLoc, SourceLocation EndLoc)
830       : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {}
831 
832 public:
833   static bool classof(const OpenACCClause *C);
getVarList()834   ArrayRef<Expr *> getVarList() { return getExprs(); }
getVarList()835   ArrayRef<Expr *> getVarList() const { return getExprs(); }
836 };
837 
838 class OpenACCPrivateClause final
839     : public OpenACCClauseWithVarList,
840       private llvm::TrailingObjects<OpenACCPrivateClause, Expr *> {
841   friend TrailingObjects;
842 
OpenACCPrivateClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)843   OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
844                        ArrayRef<Expr *> VarList, SourceLocation EndLoc)
845       : OpenACCClauseWithVarList(OpenACCClauseKind::Private, BeginLoc,
846                                  LParenLoc, EndLoc) {
847     setExprs(getTrailingObjects(VarList.size()), VarList);
848   }
849 
850 public:
classof(const OpenACCClause * C)851   static bool classof(const OpenACCClause *C) {
852     return C->getClauseKind() == OpenACCClauseKind::Private;
853   }
854   static OpenACCPrivateClause *
855   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
856          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
857 };
858 
859 class OpenACCFirstPrivateClause final
860     : public OpenACCClauseWithVarList,
861       private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *> {
862   friend TrailingObjects;
863 
OpenACCFirstPrivateClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)864   OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
865                             ArrayRef<Expr *> VarList, SourceLocation EndLoc)
866       : OpenACCClauseWithVarList(OpenACCClauseKind::FirstPrivate, BeginLoc,
867                                  LParenLoc, EndLoc) {
868     setExprs(getTrailingObjects(VarList.size()), VarList);
869   }
870 
871 public:
classof(const OpenACCClause * C)872   static bool classof(const OpenACCClause *C) {
873     return C->getClauseKind() == OpenACCClauseKind::FirstPrivate;
874   }
875   static OpenACCFirstPrivateClause *
876   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
877          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
878 };
879 
880 class OpenACCDevicePtrClause final
881     : public OpenACCClauseWithVarList,
882       private llvm::TrailingObjects<OpenACCDevicePtrClause, Expr *> {
883   friend TrailingObjects;
884 
OpenACCDevicePtrClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)885   OpenACCDevicePtrClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
886                          ArrayRef<Expr *> VarList, SourceLocation EndLoc)
887       : OpenACCClauseWithVarList(OpenACCClauseKind::DevicePtr, BeginLoc,
888                                  LParenLoc, EndLoc) {
889     setExprs(getTrailingObjects(VarList.size()), VarList);
890   }
891 
892 public:
classof(const OpenACCClause * C)893   static bool classof(const OpenACCClause *C) {
894     return C->getClauseKind() == OpenACCClauseKind::DevicePtr;
895   }
896   static OpenACCDevicePtrClause *
897   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
898          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
899 };
900 
901 class OpenACCAttachClause final
902     : public OpenACCClauseWithVarList,
903       private llvm::TrailingObjects<OpenACCAttachClause, Expr *> {
904   friend TrailingObjects;
905 
OpenACCAttachClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)906   OpenACCAttachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
907                       ArrayRef<Expr *> VarList, SourceLocation EndLoc)
908       : OpenACCClauseWithVarList(OpenACCClauseKind::Attach, BeginLoc, LParenLoc,
909                                  EndLoc) {
910     setExprs(getTrailingObjects(VarList.size()), VarList);
911   }
912 
913 public:
classof(const OpenACCClause * C)914   static bool classof(const OpenACCClause *C) {
915     return C->getClauseKind() == OpenACCClauseKind::Attach;
916   }
917   static OpenACCAttachClause *
918   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
919          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
920 };
921 
922 class OpenACCDetachClause final
923     : public OpenACCClauseWithVarList,
924       private llvm::TrailingObjects<OpenACCDetachClause, Expr *> {
925   friend TrailingObjects;
926 
OpenACCDetachClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)927   OpenACCDetachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
928                       ArrayRef<Expr *> VarList, SourceLocation EndLoc)
929       : OpenACCClauseWithVarList(OpenACCClauseKind::Detach, BeginLoc, LParenLoc,
930                                  EndLoc) {
931     setExprs(getTrailingObjects(VarList.size()), VarList);
932   }
933 
934 public:
classof(const OpenACCClause * C)935   static bool classof(const OpenACCClause *C) {
936     return C->getClauseKind() == OpenACCClauseKind::Detach;
937   }
938   static OpenACCDetachClause *
939   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
940          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
941 };
942 
943 class OpenACCDeleteClause final
944     : public OpenACCClauseWithVarList,
945       private llvm::TrailingObjects<OpenACCDeleteClause, Expr *> {
946   friend TrailingObjects;
947 
OpenACCDeleteClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)948   OpenACCDeleteClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
949                       ArrayRef<Expr *> VarList, SourceLocation EndLoc)
950       : OpenACCClauseWithVarList(OpenACCClauseKind::Delete, BeginLoc, LParenLoc,
951                                  EndLoc) {
952     setExprs(getTrailingObjects(VarList.size()), VarList);
953   }
954 
955 public:
classof(const OpenACCClause * C)956   static bool classof(const OpenACCClause *C) {
957     return C->getClauseKind() == OpenACCClauseKind::Delete;
958   }
959   static OpenACCDeleteClause *
960   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
961          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
962 };
963 
964 class OpenACCUseDeviceClause final
965     : public OpenACCClauseWithVarList,
966       private llvm::TrailingObjects<OpenACCUseDeviceClause, Expr *> {
967   friend TrailingObjects;
968 
OpenACCUseDeviceClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)969   OpenACCUseDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
970                          ArrayRef<Expr *> VarList, SourceLocation EndLoc)
971       : OpenACCClauseWithVarList(OpenACCClauseKind::UseDevice, BeginLoc,
972                                  LParenLoc, EndLoc) {
973     setExprs(getTrailingObjects(VarList.size()), VarList);
974   }
975 
976 public:
classof(const OpenACCClause * C)977   static bool classof(const OpenACCClause *C) {
978     return C->getClauseKind() == OpenACCClauseKind::UseDevice;
979   }
980   static OpenACCUseDeviceClause *
981   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
982          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
983 };
984 
985 class OpenACCNoCreateClause final
986     : public OpenACCClauseWithVarList,
987       private llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {
988   friend TrailingObjects;
989 
OpenACCNoCreateClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)990   OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
991                         ArrayRef<Expr *> VarList, SourceLocation EndLoc)
992       : OpenACCClauseWithVarList(OpenACCClauseKind::NoCreate, BeginLoc,
993                                  LParenLoc, EndLoc) {
994     setExprs(getTrailingObjects(VarList.size()), VarList);
995   }
996 
997 public:
classof(const OpenACCClause * C)998   static bool classof(const OpenACCClause *C) {
999     return C->getClauseKind() == OpenACCClauseKind::NoCreate;
1000   }
1001   static OpenACCNoCreateClause *
1002   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1003          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1004 };
1005 
1006 class OpenACCPresentClause final
1007     : public OpenACCClauseWithVarList,
1008       private llvm::TrailingObjects<OpenACCPresentClause, Expr *> {
1009   friend TrailingObjects;
1010 
OpenACCPresentClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1011   OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1012                        ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1013       : OpenACCClauseWithVarList(OpenACCClauseKind::Present, BeginLoc,
1014                                  LParenLoc, EndLoc) {
1015     setExprs(getTrailingObjects(VarList.size()), VarList);
1016   }
1017 
1018 public:
classof(const OpenACCClause * C)1019   static bool classof(const OpenACCClause *C) {
1020     return C->getClauseKind() == OpenACCClauseKind::Present;
1021   }
1022   static OpenACCPresentClause *
1023   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1024          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1025 };
1026 class OpenACCHostClause final
1027     : public OpenACCClauseWithVarList,
1028       private llvm::TrailingObjects<OpenACCHostClause, Expr *> {
1029   friend TrailingObjects;
1030 
OpenACCHostClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1031   OpenACCHostClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1032                     ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1033       : OpenACCClauseWithVarList(OpenACCClauseKind::Host, BeginLoc, LParenLoc,
1034                                  EndLoc) {
1035     setExprs(getTrailingObjects(VarList.size()), VarList);
1036   }
1037 
1038 public:
classof(const OpenACCClause * C)1039   static bool classof(const OpenACCClause *C) {
1040     return C->getClauseKind() == OpenACCClauseKind::Host;
1041   }
1042   static OpenACCHostClause *Create(const ASTContext &C, SourceLocation BeginLoc,
1043                                    SourceLocation LParenLoc,
1044                                    ArrayRef<Expr *> VarList,
1045                                    SourceLocation EndLoc);
1046 };
1047 
1048 class OpenACCDeviceClause final
1049     : public OpenACCClauseWithVarList,
1050       private llvm::TrailingObjects<OpenACCDeviceClause, Expr *> {
1051   friend TrailingObjects;
1052 
OpenACCDeviceClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1053   OpenACCDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1054                       ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1055       : OpenACCClauseWithVarList(OpenACCClauseKind::Device, BeginLoc, LParenLoc,
1056                                  EndLoc) {
1057     setExprs(getTrailingObjects(VarList.size()), VarList);
1058   }
1059 
1060 public:
classof(const OpenACCClause * C)1061   static bool classof(const OpenACCClause *C) {
1062     return C->getClauseKind() == OpenACCClauseKind::Device;
1063   }
1064   static OpenACCDeviceClause *
1065   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1066          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1067 };
1068 
1069 class OpenACCCopyClause final
1070     : public OpenACCClauseWithVarList,
1071       private llvm::TrailingObjects<OpenACCCopyClause, Expr *> {
1072   friend TrailingObjects;
1073   OpenACCModifierKind Modifiers;
1074 
OpenACCCopyClause(OpenACCClauseKind Spelling,SourceLocation BeginLoc,SourceLocation LParenLoc,OpenACCModifierKind Mods,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1075   OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1076                     SourceLocation LParenLoc, OpenACCModifierKind Mods,
1077                     ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1078       : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1079         Modifiers(Mods) {
1080     assert((Spelling == OpenACCClauseKind::Copy ||
1081             Spelling == OpenACCClauseKind::PCopy ||
1082             Spelling == OpenACCClauseKind::PresentOrCopy) &&
1083            "Invalid clause kind for copy-clause");
1084     setExprs(getTrailingObjects(VarList.size()), VarList);
1085   }
1086 
1087 public:
classof(const OpenACCClause * C)1088   static bool classof(const OpenACCClause *C) {
1089     return C->getClauseKind() == OpenACCClauseKind::Copy ||
1090            C->getClauseKind() == OpenACCClauseKind::PCopy ||
1091            C->getClauseKind() == OpenACCClauseKind::PresentOrCopy;
1092   }
1093   static OpenACCCopyClause *
1094   Create(const ASTContext &C, OpenACCClauseKind Spelling,
1095          SourceLocation BeginLoc, SourceLocation LParenLoc,
1096          OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
1097          SourceLocation EndLoc);
1098 
getModifierList()1099   OpenACCModifierKind getModifierList() const { return Modifiers; }
1100 };
1101 
1102 class OpenACCCopyInClause final
1103     : public OpenACCClauseWithVarList,
1104       private llvm::TrailingObjects<OpenACCCopyInClause, Expr *> {
1105   friend TrailingObjects;
1106   OpenACCModifierKind Modifiers;
1107 
OpenACCCopyInClause(OpenACCClauseKind Spelling,SourceLocation BeginLoc,SourceLocation LParenLoc,OpenACCModifierKind Mods,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1108   OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1109                       SourceLocation LParenLoc, OpenACCModifierKind Mods,
1110                       ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1111       : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1112         Modifiers(Mods) {
1113     assert((Spelling == OpenACCClauseKind::CopyIn ||
1114             Spelling == OpenACCClauseKind::PCopyIn ||
1115             Spelling == OpenACCClauseKind::PresentOrCopyIn) &&
1116            "Invalid clause kind for copyin-clause");
1117     setExprs(getTrailingObjects(VarList.size()), VarList);
1118   }
1119 
1120 public:
classof(const OpenACCClause * C)1121   static bool classof(const OpenACCClause *C) {
1122     return C->getClauseKind() == OpenACCClauseKind::CopyIn ||
1123            C->getClauseKind() == OpenACCClauseKind::PCopyIn ||
1124            C->getClauseKind() == OpenACCClauseKind::PresentOrCopyIn;
1125   }
getModifierList()1126   OpenACCModifierKind getModifierList() const { return Modifiers; }
1127   static OpenACCCopyInClause *
1128   Create(const ASTContext &C, OpenACCClauseKind Spelling,
1129          SourceLocation BeginLoc, SourceLocation LParenLoc,
1130          OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
1131          SourceLocation EndLoc);
1132 };
1133 
1134 class OpenACCCopyOutClause final
1135     : public OpenACCClauseWithVarList,
1136       private llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> {
1137   friend TrailingObjects;
1138   OpenACCModifierKind Modifiers;
1139 
OpenACCCopyOutClause(OpenACCClauseKind Spelling,SourceLocation BeginLoc,SourceLocation LParenLoc,OpenACCModifierKind Mods,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1140   OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1141                        SourceLocation LParenLoc, OpenACCModifierKind Mods,
1142                        ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1143       : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1144         Modifiers(Mods) {
1145     assert((Spelling == OpenACCClauseKind::CopyOut ||
1146             Spelling == OpenACCClauseKind::PCopyOut ||
1147             Spelling == OpenACCClauseKind::PresentOrCopyOut) &&
1148            "Invalid clause kind for copyout-clause");
1149     setExprs(getTrailingObjects(VarList.size()), VarList);
1150   }
1151 
1152 public:
classof(const OpenACCClause * C)1153   static bool classof(const OpenACCClause *C) {
1154     return C->getClauseKind() == OpenACCClauseKind::CopyOut ||
1155            C->getClauseKind() == OpenACCClauseKind::PCopyOut ||
1156            C->getClauseKind() == OpenACCClauseKind::PresentOrCopyOut;
1157   }
getModifierList()1158   OpenACCModifierKind getModifierList() const { return Modifiers; }
1159   static OpenACCCopyOutClause *
1160   Create(const ASTContext &C, OpenACCClauseKind Spelling,
1161          SourceLocation BeginLoc, SourceLocation LParenLoc,
1162          OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
1163          SourceLocation EndLoc);
1164 };
1165 
1166 class OpenACCCreateClause final
1167     : public OpenACCClauseWithVarList,
1168       private llvm::TrailingObjects<OpenACCCreateClause, Expr *> {
1169   friend TrailingObjects;
1170   OpenACCModifierKind Modifiers;
1171 
OpenACCCreateClause(OpenACCClauseKind Spelling,SourceLocation BeginLoc,SourceLocation LParenLoc,OpenACCModifierKind Mods,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1172   OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
1173                       SourceLocation LParenLoc, OpenACCModifierKind Mods,
1174                       ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1175       : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc),
1176         Modifiers(Mods) {
1177     assert((Spelling == OpenACCClauseKind::Create ||
1178             Spelling == OpenACCClauseKind::PCreate ||
1179             Spelling == OpenACCClauseKind::PresentOrCreate) &&
1180            "Invalid clause kind for create-clause");
1181     setExprs(getTrailingObjects(VarList.size()), VarList);
1182   }
1183 
1184 public:
classof(const OpenACCClause * C)1185   static bool classof(const OpenACCClause *C) {
1186     return C->getClauseKind() == OpenACCClauseKind::Create ||
1187            C->getClauseKind() == OpenACCClauseKind::PCreate ||
1188            C->getClauseKind() == OpenACCClauseKind::PresentOrCreate;
1189   }
getModifierList()1190   OpenACCModifierKind getModifierList() const { return Modifiers; }
1191   static OpenACCCreateClause *
1192   Create(const ASTContext &C, OpenACCClauseKind Spelling,
1193          SourceLocation BeginLoc, SourceLocation LParenLoc,
1194          OpenACCModifierKind Mods, ArrayRef<Expr *> VarList,
1195          SourceLocation EndLoc);
1196 };
1197 
1198 class OpenACCReductionClause final
1199     : public OpenACCClauseWithVarList,
1200       private llvm::TrailingObjects<OpenACCReductionClause, Expr *> {
1201   friend TrailingObjects;
1202   OpenACCReductionOperator Op;
1203 
OpenACCReductionClause(SourceLocation BeginLoc,SourceLocation LParenLoc,OpenACCReductionOperator Operator,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1204   OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1205                          OpenACCReductionOperator Operator,
1206                          ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1207       : OpenACCClauseWithVarList(OpenACCClauseKind::Reduction, BeginLoc,
1208                                  LParenLoc, EndLoc),
1209         Op(Operator) {
1210     setExprs(getTrailingObjects(VarList.size()), VarList);
1211   }
1212 
1213 public:
classof(const OpenACCClause * C)1214   static bool classof(const OpenACCClause *C) {
1215     return C->getClauseKind() == OpenACCClauseKind::Reduction;
1216   }
1217 
1218   static OpenACCReductionClause *
1219   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1220          OpenACCReductionOperator Operator, ArrayRef<Expr *> VarList,
1221          SourceLocation EndLoc);
1222 
getReductionOp()1223   OpenACCReductionOperator getReductionOp() const { return Op; }
1224 };
1225 
1226 class OpenACCLinkClause final
1227     : public OpenACCClauseWithVarList,
1228       private llvm::TrailingObjects<OpenACCLinkClause, Expr *> {
1229   friend TrailingObjects;
1230 
OpenACCLinkClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1231   OpenACCLinkClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1232                     ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1233       : OpenACCClauseWithVarList(OpenACCClauseKind::Link, BeginLoc, LParenLoc,
1234                                  EndLoc) {
1235     setExprs(getTrailingObjects(VarList.size()), VarList);
1236   }
1237 
1238 public:
classof(const OpenACCClause * C)1239   static bool classof(const OpenACCClause *C) {
1240     return C->getClauseKind() == OpenACCClauseKind::Link;
1241   }
1242 
1243   static OpenACCLinkClause *Create(const ASTContext &C, SourceLocation BeginLoc,
1244                                    SourceLocation LParenLoc,
1245                                    ArrayRef<Expr *> VarList,
1246                                    SourceLocation EndLoc);
1247 };
1248 
1249 class OpenACCDeviceResidentClause final
1250     : public OpenACCClauseWithVarList,
1251       private llvm::TrailingObjects<OpenACCDeviceResidentClause, Expr *> {
1252   friend TrailingObjects;
1253 
OpenACCDeviceResidentClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)1254   OpenACCDeviceResidentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
1255                               ArrayRef<Expr *> VarList, SourceLocation EndLoc)
1256       : OpenACCClauseWithVarList(OpenACCClauseKind::DeviceResident, BeginLoc,
1257                                  LParenLoc, EndLoc) {
1258     setExprs(getTrailingObjects(VarList.size()), VarList);
1259   }
1260 
1261 public:
classof(const OpenACCClause * C)1262   static bool classof(const OpenACCClause *C) {
1263     return C->getClauseKind() == OpenACCClauseKind::DeviceResident;
1264   }
1265 
1266   static OpenACCDeviceResidentClause *
1267   Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
1268          ArrayRef<Expr *> VarList, SourceLocation EndLoc);
1269 };
1270 
1271 template <class Impl> class OpenACCClauseVisitor {
getDerived()1272   Impl &getDerived() { return static_cast<Impl &>(*this); }
1273 
1274 public:
VisitClauseList(ArrayRef<const OpenACCClause * > List)1275   void VisitClauseList(ArrayRef<const OpenACCClause *> List) {
1276     for (const OpenACCClause *Clause : List)
1277       Visit(Clause);
1278   }
1279 
Visit(const OpenACCClause * C)1280   void Visit(const OpenACCClause *C) {
1281     if (!C)
1282       return;
1283 
1284     switch (C->getClauseKind()) {
1285 #define VISIT_CLAUSE(CLAUSE_NAME)                                              \
1286   case OpenACCClauseKind::CLAUSE_NAME:                                         \
1287     getDerived().Visit##CLAUSE_NAME##Clause(                                   \
1288         *cast<OpenACC##CLAUSE_NAME##Clause>(C));                               \
1289     return;
1290 #define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED)                      \
1291   case OpenACCClauseKind::ALIAS_NAME:                                          \
1292     getDerived().Visit##CLAUSE_NAME##Clause(                                   \
1293         *cast<OpenACC##CLAUSE_NAME##Clause>(C));                               \
1294     return;
1295 #include "clang/Basic/OpenACCClauses.def"
1296 
1297     default:
1298       llvm_unreachable("Clause visitor not yet implemented");
1299     }
1300     llvm_unreachable("Invalid Clause kind");
1301   }
1302 
1303 #define VISIT_CLAUSE(CLAUSE_NAME)                                              \
1304   void Visit##CLAUSE_NAME##Clause(                                             \
1305       const OpenACC##CLAUSE_NAME##Clause &Clause) {                            \
1306     return getDerived().VisitClause(Clause);                                   \
1307   }
1308 
1309 #include "clang/Basic/OpenACCClauses.def"
1310 };
1311 
1312 class OpenACCClausePrinter final
1313     : public OpenACCClauseVisitor<OpenACCClausePrinter> {
1314   raw_ostream &OS;
1315   const PrintingPolicy &Policy;
1316 
1317   void printExpr(const Expr *E);
1318 
1319 public:
VisitClauseList(ArrayRef<const OpenACCClause * > List)1320   void VisitClauseList(ArrayRef<const OpenACCClause *> List) {
1321     for (const OpenACCClause *Clause : List) {
1322       Visit(Clause);
1323 
1324       if (Clause != List.back())
1325         OS << ' ';
1326     }
1327   }
OpenACCClausePrinter(raw_ostream & OS,const PrintingPolicy & Policy)1328   OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
1329       : OS(OS), Policy(Policy) {}
1330 
1331 #define VISIT_CLAUSE(CLAUSE_NAME)                                              \
1332   void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
1333 #include "clang/Basic/OpenACCClauses.def"
1334 };
1335 
1336 } // namespace clang
1337 
1338 #endif // LLVM_CLANG_AST_OPENACCCLAUSE_H
1339