xref: /llvm-project/clang/lib/AST/OpenACCClause.cpp (revision be32621ce8cbffe674c62e87c0c51c9fc4a21e5f)
1 //===---- OpenACCClause.cpp - Classes for OpenACC Clauses  ----------------===//
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 // This file implements the subclasses of the OpenACCClause class declared in
10 // OpenACCClause.h
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/OpenACCClause.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Expr.h"
17 
18 using namespace clang;
19 
20 bool OpenACCClauseWithParams::classof(const OpenACCClause *C) {
21   return OpenACCDeviceTypeClause::classof(C) ||
22          OpenACCClauseWithCondition::classof(C) ||
23          OpenACCClauseWithExprs::classof(C) || OpenACCSelfClause::classof(C);
24 }
25 bool OpenACCClauseWithExprs::classof(const OpenACCClause *C) {
26   return OpenACCWaitClause::classof(C) || OpenACCNumGangsClause::classof(C) ||
27          OpenACCTileClause::classof(C) ||
28          OpenACCClauseWithSingleIntExpr::classof(C) ||
29          OpenACCGangClause::classof(C) || OpenACCClauseWithVarList::classof(C);
30 }
31 bool OpenACCClauseWithVarList::classof(const OpenACCClause *C) {
32   return OpenACCPrivateClause::classof(C) ||
33          OpenACCFirstPrivateClause::classof(C) ||
34          OpenACCDevicePtrClause::classof(C) ||
35          OpenACCDeleteClause::classof(C) ||
36          OpenACCUseDeviceClause::classof(C) ||
37          OpenACCDetachClause::classof(C) || OpenACCAttachClause::classof(C) ||
38          OpenACCNoCreateClause::classof(C) ||
39          OpenACCPresentClause::classof(C) || OpenACCCopyClause::classof(C) ||
40          OpenACCCopyInClause::classof(C) || OpenACCCopyOutClause::classof(C) ||
41          OpenACCReductionClause::classof(C) ||
42          OpenACCCreateClause::classof(C) || OpenACCDeviceClause::classof(C) ||
43          OpenACCHostClause::classof(C);
44 }
45 bool OpenACCClauseWithCondition::classof(const OpenACCClause *C) {
46   return OpenACCIfClause::classof(C);
47 }
48 bool OpenACCClauseWithSingleIntExpr::classof(const OpenACCClause *C) {
49   return OpenACCNumWorkersClause::classof(C) ||
50          OpenACCVectorLengthClause::classof(C) ||
51          OpenACCDeviceNumClause::classof(C) ||
52          OpenACCDefaultAsyncClause::classof(C) ||
53          OpenACCVectorClause::classof(C) || OpenACCWorkerClause::classof(C) ||
54          OpenACCCollapseClause::classof(C) || OpenACCAsyncClause::classof(C);
55 }
56 OpenACCDefaultClause *OpenACCDefaultClause::Create(const ASTContext &C,
57                                                    OpenACCDefaultClauseKind K,
58                                                    SourceLocation BeginLoc,
59                                                    SourceLocation LParenLoc,
60                                                    SourceLocation EndLoc) {
61   void *Mem =
62       C.Allocate(sizeof(OpenACCDefaultClause), alignof(OpenACCDefaultClause));
63 
64   return new (Mem) OpenACCDefaultClause(K, BeginLoc, LParenLoc, EndLoc);
65 }
66 
67 OpenACCIfClause *OpenACCIfClause::Create(const ASTContext &C,
68                                          SourceLocation BeginLoc,
69                                          SourceLocation LParenLoc,
70                                          Expr *ConditionExpr,
71                                          SourceLocation EndLoc) {
72   void *Mem = C.Allocate(sizeof(OpenACCIfClause), alignof(OpenACCIfClause));
73   return new (Mem) OpenACCIfClause(BeginLoc, LParenLoc, ConditionExpr, EndLoc);
74 }
75 
76 OpenACCIfClause::OpenACCIfClause(SourceLocation BeginLoc,
77                                  SourceLocation LParenLoc, Expr *ConditionExpr,
78                                  SourceLocation EndLoc)
79     : OpenACCClauseWithCondition(OpenACCClauseKind::If, BeginLoc, LParenLoc,
80                                  ConditionExpr, EndLoc) {
81   assert(ConditionExpr && "if clause requires condition expr");
82   assert((ConditionExpr->isInstantiationDependent() ||
83           ConditionExpr->getType()->isScalarType()) &&
84          "Condition expression type not scalar/dependent");
85 }
86 
87 OpenACCSelfClause *OpenACCSelfClause::Create(const ASTContext &C,
88                                              SourceLocation BeginLoc,
89                                              SourceLocation LParenLoc,
90                                              Expr *ConditionExpr,
91                                              SourceLocation EndLoc) {
92   void *Mem = C.Allocate(OpenACCSelfClause::totalSizeToAlloc<Expr *>(1));
93   return new (Mem)
94       OpenACCSelfClause(BeginLoc, LParenLoc, ConditionExpr, EndLoc);
95 }
96 
97 OpenACCSelfClause *OpenACCSelfClause::Create(const ASTContext &C,
98                                              SourceLocation BeginLoc,
99                                              SourceLocation LParenLoc,
100                                              ArrayRef<Expr *> VarList,
101                                              SourceLocation EndLoc) {
102   void *Mem =
103       C.Allocate(OpenACCSelfClause::totalSizeToAlloc<Expr *>(VarList.size()));
104   return new (Mem) OpenACCSelfClause(BeginLoc, LParenLoc, VarList, EndLoc);
105 }
106 
107 OpenACCSelfClause::OpenACCSelfClause(SourceLocation BeginLoc,
108                                      SourceLocation LParenLoc,
109                                      llvm::ArrayRef<Expr *> VarList,
110                                      SourceLocation EndLoc)
111     : OpenACCClauseWithParams(OpenACCClauseKind::Self, BeginLoc, LParenLoc,
112                               EndLoc),
113       HasConditionExpr(std::nullopt), NumExprs(VarList.size()) {
114   std::uninitialized_copy(VarList.begin(), VarList.end(),
115                           getTrailingObjects<Expr *>());
116 }
117 
118 OpenACCSelfClause::OpenACCSelfClause(SourceLocation BeginLoc,
119                                      SourceLocation LParenLoc,
120                                      Expr *ConditionExpr, SourceLocation EndLoc)
121     : OpenACCClauseWithParams(OpenACCClauseKind::Self, BeginLoc, LParenLoc,
122                               EndLoc),
123       HasConditionExpr(ConditionExpr != nullptr), NumExprs(1) {
124   assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() ||
125           ConditionExpr->getType()->isScalarType()) &&
126          "Condition expression type not scalar/dependent");
127   std::uninitialized_copy(&ConditionExpr, &ConditionExpr + 1,
128                           getTrailingObjects<Expr *>());
129 }
130 
131 OpenACCClause::child_range OpenACCClause::children() {
132   switch (getClauseKind()) {
133   default:
134     assert(false && "Clause children function not implemented");
135     break;
136 #define VISIT_CLAUSE(CLAUSE_NAME)                                              \
137   case OpenACCClauseKind::CLAUSE_NAME:                                         \
138     return cast<OpenACC##CLAUSE_NAME##Clause>(this)->children();
139 #define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED)                      \
140   case OpenACCClauseKind::ALIAS_NAME:                                          \
141     return cast<OpenACC##CLAUSE_NAME##Clause>(this)->children();
142 
143 #include "clang/Basic/OpenACCClauses.def"
144   }
145   return child_range(child_iterator(), child_iterator());
146 }
147 
148 OpenACCNumWorkersClause::OpenACCNumWorkersClause(SourceLocation BeginLoc,
149                                                  SourceLocation LParenLoc,
150                                                  Expr *IntExpr,
151                                                  SourceLocation EndLoc)
152     : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::NumWorkers, BeginLoc,
153                                      LParenLoc, IntExpr, EndLoc) {
154   assert((!IntExpr || IntExpr->isInstantiationDependent() ||
155           IntExpr->getType()->isIntegerType()) &&
156          "Condition expression type not scalar/dependent");
157 }
158 
159 OpenACCGangClause::OpenACCGangClause(SourceLocation BeginLoc,
160                                      SourceLocation LParenLoc,
161                                      ArrayRef<OpenACCGangKind> GangKinds,
162                                      ArrayRef<Expr *> IntExprs,
163                                      SourceLocation EndLoc)
164     : OpenACCClauseWithExprs(OpenACCClauseKind::Gang, BeginLoc, LParenLoc,
165                              EndLoc) {
166   assert(GangKinds.size() == IntExprs.size() && "Mismatch exprs/kind?");
167   std::uninitialized_copy(IntExprs.begin(), IntExprs.end(),
168                           getTrailingObjects<Expr *>());
169   setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size()));
170   std::uninitialized_copy(GangKinds.begin(), GangKinds.end(),
171                           getTrailingObjects<OpenACCGangKind>());
172 }
173 
174 OpenACCNumWorkersClause *
175 OpenACCNumWorkersClause::Create(const ASTContext &C, SourceLocation BeginLoc,
176                                 SourceLocation LParenLoc, Expr *IntExpr,
177                                 SourceLocation EndLoc) {
178   void *Mem = C.Allocate(sizeof(OpenACCNumWorkersClause),
179                          alignof(OpenACCNumWorkersClause));
180   return new (Mem)
181       OpenACCNumWorkersClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
182 }
183 
184 OpenACCCollapseClause::OpenACCCollapseClause(SourceLocation BeginLoc,
185                                              SourceLocation LParenLoc,
186                                              bool HasForce, Expr *LoopCount,
187                                              SourceLocation EndLoc)
188     : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::Collapse, BeginLoc,
189                                      LParenLoc, LoopCount, EndLoc),
190       HasForce(HasForce) {
191   assert(LoopCount && "LoopCount required");
192 }
193 
194 OpenACCCollapseClause *
195 OpenACCCollapseClause::Create(const ASTContext &C, SourceLocation BeginLoc,
196                               SourceLocation LParenLoc, bool HasForce,
197                               Expr *LoopCount, SourceLocation EndLoc) {
198   assert(
199       LoopCount &&
200       (LoopCount->isInstantiationDependent() || isa<ConstantExpr>(LoopCount)) &&
201       "Loop count not constant expression");
202   void *Mem =
203       C.Allocate(sizeof(OpenACCCollapseClause), alignof(OpenACCCollapseClause));
204   return new (Mem)
205       OpenACCCollapseClause(BeginLoc, LParenLoc, HasForce, LoopCount, EndLoc);
206 }
207 
208 OpenACCVectorLengthClause::OpenACCVectorLengthClause(SourceLocation BeginLoc,
209                                                      SourceLocation LParenLoc,
210                                                      Expr *IntExpr,
211                                                      SourceLocation EndLoc)
212     : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::VectorLength, BeginLoc,
213                                      LParenLoc, IntExpr, EndLoc) {
214   assert((!IntExpr || IntExpr->isInstantiationDependent() ||
215           IntExpr->getType()->isIntegerType()) &&
216          "Condition expression type not scalar/dependent");
217 }
218 
219 OpenACCVectorLengthClause *
220 OpenACCVectorLengthClause::Create(const ASTContext &C, SourceLocation BeginLoc,
221                                   SourceLocation LParenLoc, Expr *IntExpr,
222                                   SourceLocation EndLoc) {
223   void *Mem = C.Allocate(sizeof(OpenACCVectorLengthClause),
224                          alignof(OpenACCVectorLengthClause));
225   return new (Mem)
226       OpenACCVectorLengthClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
227 }
228 
229 OpenACCAsyncClause::OpenACCAsyncClause(SourceLocation BeginLoc,
230                                        SourceLocation LParenLoc, Expr *IntExpr,
231                                        SourceLocation EndLoc)
232     : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::Async, BeginLoc,
233                                      LParenLoc, IntExpr, EndLoc) {
234   assert((!IntExpr || IntExpr->isInstantiationDependent() ||
235           IntExpr->getType()->isIntegerType()) &&
236          "Condition expression type not scalar/dependent");
237 }
238 
239 OpenACCAsyncClause *OpenACCAsyncClause::Create(const ASTContext &C,
240                                                SourceLocation BeginLoc,
241                                                SourceLocation LParenLoc,
242                                                Expr *IntExpr,
243                                                SourceLocation EndLoc) {
244   void *Mem =
245       C.Allocate(sizeof(OpenACCAsyncClause), alignof(OpenACCAsyncClause));
246   return new (Mem) OpenACCAsyncClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
247 }
248 
249 OpenACCDeviceNumClause::OpenACCDeviceNumClause(SourceLocation BeginLoc,
250                                        SourceLocation LParenLoc, Expr *IntExpr,
251                                        SourceLocation EndLoc)
252     : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::DeviceNum, BeginLoc,
253                                      LParenLoc, IntExpr, EndLoc) {
254   assert((IntExpr->isInstantiationDependent() ||
255           IntExpr->getType()->isIntegerType()) &&
256          "device_num expression type not scalar/dependent");
257 }
258 
259 OpenACCDeviceNumClause *OpenACCDeviceNumClause::Create(const ASTContext &C,
260                                                SourceLocation BeginLoc,
261                                                SourceLocation LParenLoc,
262                                                Expr *IntExpr,
263                                                SourceLocation EndLoc) {
264   void *Mem =
265       C.Allocate(sizeof(OpenACCDeviceNumClause), alignof(OpenACCDeviceNumClause));
266   return new (Mem) OpenACCDeviceNumClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
267 }
268 
269 OpenACCDefaultAsyncClause::OpenACCDefaultAsyncClause(SourceLocation BeginLoc,
270                                                      SourceLocation LParenLoc,
271                                                      Expr *IntExpr,
272                                                      SourceLocation EndLoc)
273     : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::DefaultAsync, BeginLoc,
274                                      LParenLoc, IntExpr, EndLoc) {
275   assert((IntExpr->isInstantiationDependent() ||
276           IntExpr->getType()->isIntegerType()) &&
277          "default_async expression type not scalar/dependent");
278 }
279 
280 OpenACCDefaultAsyncClause *
281 OpenACCDefaultAsyncClause::Create(const ASTContext &C, SourceLocation BeginLoc,
282                                   SourceLocation LParenLoc, Expr *IntExpr,
283                                   SourceLocation EndLoc) {
284   void *Mem = C.Allocate(sizeof(OpenACCDefaultAsyncClause),
285                          alignof(OpenACCDefaultAsyncClause));
286   return new (Mem)
287       OpenACCDefaultAsyncClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
288 }
289 
290 OpenACCWaitClause *OpenACCWaitClause::Create(
291     const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
292     Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
293     SourceLocation EndLoc) {
294   // Allocates enough room in trailing storage for all the int-exprs, plus a
295   // placeholder for the devnum.
296   void *Mem = C.Allocate(
297       OpenACCWaitClause::totalSizeToAlloc<Expr *>(QueueIdExprs.size() + 1));
298   return new (Mem) OpenACCWaitClause(BeginLoc, LParenLoc, DevNumExpr, QueuesLoc,
299                                      QueueIdExprs, EndLoc);
300 }
301 
302 OpenACCNumGangsClause *OpenACCNumGangsClause::Create(const ASTContext &C,
303                                                      SourceLocation BeginLoc,
304                                                      SourceLocation LParenLoc,
305                                                      ArrayRef<Expr *> IntExprs,
306                                                      SourceLocation EndLoc) {
307   void *Mem = C.Allocate(
308       OpenACCNumGangsClause::totalSizeToAlloc<Expr *>(IntExprs.size()));
309   return new (Mem) OpenACCNumGangsClause(BeginLoc, LParenLoc, IntExprs, EndLoc);
310 }
311 
312 OpenACCTileClause *OpenACCTileClause::Create(const ASTContext &C,
313                                              SourceLocation BeginLoc,
314                                              SourceLocation LParenLoc,
315                                              ArrayRef<Expr *> SizeExprs,
316                                              SourceLocation EndLoc) {
317   void *Mem =
318       C.Allocate(OpenACCTileClause::totalSizeToAlloc<Expr *>(SizeExprs.size()));
319   return new (Mem) OpenACCTileClause(BeginLoc, LParenLoc, SizeExprs, EndLoc);
320 }
321 
322 OpenACCPrivateClause *OpenACCPrivateClause::Create(const ASTContext &C,
323                                                    SourceLocation BeginLoc,
324                                                    SourceLocation LParenLoc,
325                                                    ArrayRef<Expr *> VarList,
326                                                    SourceLocation EndLoc) {
327   void *Mem = C.Allocate(
328       OpenACCPrivateClause::totalSizeToAlloc<Expr *>(VarList.size()));
329   return new (Mem) OpenACCPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
330 }
331 
332 OpenACCFirstPrivateClause *OpenACCFirstPrivateClause::Create(
333     const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
334     ArrayRef<Expr *> VarList, SourceLocation EndLoc) {
335   void *Mem = C.Allocate(
336       OpenACCFirstPrivateClause::totalSizeToAlloc<Expr *>(VarList.size()));
337   return new (Mem)
338       OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
339 }
340 
341 OpenACCAttachClause *OpenACCAttachClause::Create(const ASTContext &C,
342                                                  SourceLocation BeginLoc,
343                                                  SourceLocation LParenLoc,
344                                                  ArrayRef<Expr *> VarList,
345                                                  SourceLocation EndLoc) {
346   void *Mem =
347       C.Allocate(OpenACCAttachClause::totalSizeToAlloc<Expr *>(VarList.size()));
348   return new (Mem) OpenACCAttachClause(BeginLoc, LParenLoc, VarList, EndLoc);
349 }
350 
351 OpenACCDetachClause *OpenACCDetachClause::Create(const ASTContext &C,
352                                                  SourceLocation BeginLoc,
353                                                  SourceLocation LParenLoc,
354                                                  ArrayRef<Expr *> VarList,
355                                                  SourceLocation EndLoc) {
356   void *Mem =
357       C.Allocate(OpenACCDetachClause::totalSizeToAlloc<Expr *>(VarList.size()));
358   return new (Mem) OpenACCDetachClause(BeginLoc, LParenLoc, VarList, EndLoc);
359 }
360 
361 OpenACCDeleteClause *OpenACCDeleteClause::Create(const ASTContext &C,
362                                                  SourceLocation BeginLoc,
363                                                  SourceLocation LParenLoc,
364                                                  ArrayRef<Expr *> VarList,
365                                                  SourceLocation EndLoc) {
366   void *Mem =
367       C.Allocate(OpenACCDeleteClause::totalSizeToAlloc<Expr *>(VarList.size()));
368   return new (Mem) OpenACCDeleteClause(BeginLoc, LParenLoc, VarList, EndLoc);
369 }
370 
371 OpenACCUseDeviceClause *OpenACCUseDeviceClause::Create(const ASTContext &C,
372                                                        SourceLocation BeginLoc,
373                                                        SourceLocation LParenLoc,
374                                                        ArrayRef<Expr *> VarList,
375                                                        SourceLocation EndLoc) {
376   void *Mem = C.Allocate(
377       OpenACCUseDeviceClause::totalSizeToAlloc<Expr *>(VarList.size()));
378   return new (Mem) OpenACCUseDeviceClause(BeginLoc, LParenLoc, VarList, EndLoc);
379 }
380 
381 OpenACCDevicePtrClause *OpenACCDevicePtrClause::Create(const ASTContext &C,
382                                                        SourceLocation BeginLoc,
383                                                        SourceLocation LParenLoc,
384                                                        ArrayRef<Expr *> VarList,
385                                                        SourceLocation EndLoc) {
386   void *Mem = C.Allocate(
387       OpenACCDevicePtrClause::totalSizeToAlloc<Expr *>(VarList.size()));
388   return new (Mem) OpenACCDevicePtrClause(BeginLoc, LParenLoc, VarList, EndLoc);
389 }
390 
391 OpenACCNoCreateClause *OpenACCNoCreateClause::Create(const ASTContext &C,
392                                                      SourceLocation BeginLoc,
393                                                      SourceLocation LParenLoc,
394                                                      ArrayRef<Expr *> VarList,
395                                                      SourceLocation EndLoc) {
396   void *Mem = C.Allocate(
397       OpenACCNoCreateClause::totalSizeToAlloc<Expr *>(VarList.size()));
398   return new (Mem) OpenACCNoCreateClause(BeginLoc, LParenLoc, VarList, EndLoc);
399 }
400 
401 OpenACCPresentClause *OpenACCPresentClause::Create(const ASTContext &C,
402                                                    SourceLocation BeginLoc,
403                                                    SourceLocation LParenLoc,
404                                                    ArrayRef<Expr *> VarList,
405                                                    SourceLocation EndLoc) {
406   void *Mem = C.Allocate(
407       OpenACCPresentClause::totalSizeToAlloc<Expr *>(VarList.size()));
408   return new (Mem) OpenACCPresentClause(BeginLoc, LParenLoc, VarList, EndLoc);
409 }
410 
411 OpenACCHostClause *OpenACCHostClause::Create(const ASTContext &C,
412                                              SourceLocation BeginLoc,
413                                              SourceLocation LParenLoc,
414                                              ArrayRef<Expr *> VarList,
415                                              SourceLocation EndLoc) {
416   void *Mem =
417       C.Allocate(OpenACCHostClause::totalSizeToAlloc<Expr *>(VarList.size()));
418   return new (Mem) OpenACCHostClause(BeginLoc, LParenLoc, VarList, EndLoc);
419 }
420 
421 OpenACCDeviceClause *OpenACCDeviceClause::Create(const ASTContext &C,
422                                                  SourceLocation BeginLoc,
423                                                  SourceLocation LParenLoc,
424                                                  ArrayRef<Expr *> VarList,
425                                                  SourceLocation EndLoc) {
426   void *Mem =
427       C.Allocate(OpenACCDeviceClause::totalSizeToAlloc<Expr *>(VarList.size()));
428   return new (Mem) OpenACCDeviceClause(BeginLoc, LParenLoc, VarList, EndLoc);
429 }
430 
431 OpenACCCopyClause *
432 OpenACCCopyClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
433                           SourceLocation BeginLoc, SourceLocation LParenLoc,
434                           ArrayRef<Expr *> VarList, SourceLocation EndLoc) {
435   void *Mem =
436       C.Allocate(OpenACCCopyClause::totalSizeToAlloc<Expr *>(VarList.size()));
437   return new (Mem)
438       OpenACCCopyClause(Spelling, BeginLoc, LParenLoc, VarList, EndLoc);
439 }
440 
441 OpenACCCopyInClause *
442 OpenACCCopyInClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
443                             SourceLocation BeginLoc, SourceLocation LParenLoc,
444                             bool IsReadOnly, ArrayRef<Expr *> VarList,
445                             SourceLocation EndLoc) {
446   void *Mem =
447       C.Allocate(OpenACCCopyInClause::totalSizeToAlloc<Expr *>(VarList.size()));
448   return new (Mem) OpenACCCopyInClause(Spelling, BeginLoc, LParenLoc,
449                                        IsReadOnly, VarList, EndLoc);
450 }
451 
452 OpenACCCopyOutClause *
453 OpenACCCopyOutClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
454                              SourceLocation BeginLoc, SourceLocation LParenLoc,
455                              bool IsZero, ArrayRef<Expr *> VarList,
456                              SourceLocation EndLoc) {
457   void *Mem = C.Allocate(
458       OpenACCCopyOutClause::totalSizeToAlloc<Expr *>(VarList.size()));
459   return new (Mem) OpenACCCopyOutClause(Spelling, BeginLoc, LParenLoc, IsZero,
460                                         VarList, EndLoc);
461 }
462 
463 OpenACCCreateClause *
464 OpenACCCreateClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
465                             SourceLocation BeginLoc, SourceLocation LParenLoc,
466                             bool IsZero, ArrayRef<Expr *> VarList,
467                             SourceLocation EndLoc) {
468   void *Mem =
469       C.Allocate(OpenACCCreateClause::totalSizeToAlloc<Expr *>(VarList.size()));
470   return new (Mem) OpenACCCreateClause(Spelling, BeginLoc, LParenLoc, IsZero,
471                                        VarList, EndLoc);
472 }
473 
474 OpenACCDeviceTypeClause *OpenACCDeviceTypeClause::Create(
475     const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc,
476     SourceLocation LParenLoc, ArrayRef<DeviceTypeArgument> Archs,
477     SourceLocation EndLoc) {
478   void *Mem =
479       C.Allocate(OpenACCDeviceTypeClause::totalSizeToAlloc<DeviceTypeArgument>(
480           Archs.size()));
481   return new (Mem)
482       OpenACCDeviceTypeClause(K, BeginLoc, LParenLoc, Archs, EndLoc);
483 }
484 
485 OpenACCReductionClause *OpenACCReductionClause::Create(
486     const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
487     OpenACCReductionOperator Operator, ArrayRef<Expr *> VarList,
488     SourceLocation EndLoc) {
489   void *Mem = C.Allocate(
490       OpenACCReductionClause::totalSizeToAlloc<Expr *>(VarList.size()));
491   return new (Mem)
492       OpenACCReductionClause(BeginLoc, LParenLoc, Operator, VarList, EndLoc);
493 }
494 
495 OpenACCAutoClause *OpenACCAutoClause::Create(const ASTContext &C,
496                                              SourceLocation BeginLoc,
497                                              SourceLocation EndLoc) {
498   void *Mem = C.Allocate(sizeof(OpenACCAutoClause));
499   return new (Mem) OpenACCAutoClause(BeginLoc, EndLoc);
500 }
501 
502 OpenACCIndependentClause *
503 OpenACCIndependentClause::Create(const ASTContext &C, SourceLocation BeginLoc,
504                                  SourceLocation EndLoc) {
505   void *Mem = C.Allocate(sizeof(OpenACCIndependentClause));
506   return new (Mem) OpenACCIndependentClause(BeginLoc, EndLoc);
507 }
508 
509 OpenACCSeqClause *OpenACCSeqClause::Create(const ASTContext &C,
510                                            SourceLocation BeginLoc,
511                                            SourceLocation EndLoc) {
512   void *Mem = C.Allocate(sizeof(OpenACCSeqClause));
513   return new (Mem) OpenACCSeqClause(BeginLoc, EndLoc);
514 }
515 
516 OpenACCGangClause *
517 OpenACCGangClause::Create(const ASTContext &C, SourceLocation BeginLoc,
518                           SourceLocation LParenLoc,
519                           ArrayRef<OpenACCGangKind> GangKinds,
520                           ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) {
521   void *Mem =
522       C.Allocate(OpenACCGangClause::totalSizeToAlloc<Expr *, OpenACCGangKind>(
523           IntExprs.size(), GangKinds.size()));
524   return new (Mem)
525       OpenACCGangClause(BeginLoc, LParenLoc, GangKinds, IntExprs, EndLoc);
526 }
527 
528 OpenACCWorkerClause::OpenACCWorkerClause(SourceLocation BeginLoc,
529                                          SourceLocation LParenLoc,
530                                          Expr *IntExpr, SourceLocation EndLoc)
531     : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::Worker, BeginLoc,
532                                      LParenLoc, IntExpr, EndLoc) {
533   assert((!IntExpr || IntExpr->isInstantiationDependent() ||
534           IntExpr->getType()->isIntegerType()) &&
535          "Int expression type not scalar/dependent");
536 }
537 
538 OpenACCWorkerClause *OpenACCWorkerClause::Create(const ASTContext &C,
539                                                  SourceLocation BeginLoc,
540                                                  SourceLocation LParenLoc,
541                                                  Expr *IntExpr,
542                                                  SourceLocation EndLoc) {
543   void *Mem =
544       C.Allocate(sizeof(OpenACCWorkerClause), alignof(OpenACCWorkerClause));
545   return new (Mem) OpenACCWorkerClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
546 }
547 
548 OpenACCVectorClause::OpenACCVectorClause(SourceLocation BeginLoc,
549                                          SourceLocation LParenLoc,
550                                          Expr *IntExpr, SourceLocation EndLoc)
551     : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::Vector, BeginLoc,
552                                      LParenLoc, IntExpr, EndLoc) {
553   assert((!IntExpr || IntExpr->isInstantiationDependent() ||
554           IntExpr->getType()->isIntegerType()) &&
555          "Int expression type not scalar/dependent");
556 }
557 
558 OpenACCVectorClause *OpenACCVectorClause::Create(const ASTContext &C,
559                                                  SourceLocation BeginLoc,
560                                                  SourceLocation LParenLoc,
561                                                  Expr *IntExpr,
562                                                  SourceLocation EndLoc) {
563   void *Mem =
564       C.Allocate(sizeof(OpenACCVectorClause), alignof(OpenACCVectorClause));
565   return new (Mem) OpenACCVectorClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
566 }
567 
568 OpenACCFinalizeClause *OpenACCFinalizeClause::Create(const ASTContext &C,
569                                                      SourceLocation BeginLoc,
570                                                      SourceLocation EndLoc) {
571   void *Mem =
572       C.Allocate(sizeof(OpenACCFinalizeClause), alignof(OpenACCFinalizeClause));
573   return new (Mem) OpenACCFinalizeClause(BeginLoc, EndLoc);
574 }
575 
576 OpenACCIfPresentClause *OpenACCIfPresentClause::Create(const ASTContext &C,
577                                                        SourceLocation BeginLoc,
578                                                        SourceLocation EndLoc) {
579   void *Mem = C.Allocate(sizeof(OpenACCIfPresentClause),
580                          alignof(OpenACCIfPresentClause));
581   return new (Mem) OpenACCIfPresentClause(BeginLoc, EndLoc);
582 }
583 
584 //===----------------------------------------------------------------------===//
585 //  OpenACC clauses printing methods
586 //===----------------------------------------------------------------------===//
587 
588 void OpenACCClausePrinter::printExpr(const Expr *E) {
589   E->printPretty(OS, nullptr, Policy, 0);
590 }
591 
592 void OpenACCClausePrinter::VisitDefaultClause(const OpenACCDefaultClause &C) {
593   OS << "default(" << C.getDefaultClauseKind() << ")";
594 }
595 
596 void OpenACCClausePrinter::VisitIfClause(const OpenACCIfClause &C) {
597   OS << "if(";
598   printExpr(C.getConditionExpr());
599   OS << ")";
600 }
601 
602 void OpenACCClausePrinter::VisitSelfClause(const OpenACCSelfClause &C) {
603   OS << "self";
604 
605   if (C.isConditionExprClause()) {
606     if (const Expr *CondExpr = C.getConditionExpr()) {
607       OS << "(";
608       printExpr(CondExpr);
609       OS << ")";
610     }
611   } else {
612     OS << "(";
613     llvm::interleaveComma(C.getVarList(), OS,
614                           [&](const Expr *E) { printExpr(E); });
615     OS << ")";
616   }
617 }
618 
619 void OpenACCClausePrinter::VisitNumGangsClause(const OpenACCNumGangsClause &C) {
620   OS << "num_gangs(";
621   llvm::interleaveComma(C.getIntExprs(), OS,
622                         [&](const Expr *E) { printExpr(E); });
623   OS << ")";
624 }
625 
626 void OpenACCClausePrinter::VisitTileClause(const OpenACCTileClause &C) {
627   OS << "tile(";
628   llvm::interleaveComma(C.getSizeExprs(), OS,
629                         [&](const Expr *E) { printExpr(E); });
630   OS << ")";
631 }
632 
633 void OpenACCClausePrinter::VisitNumWorkersClause(
634     const OpenACCNumWorkersClause &C) {
635   OS << "num_workers(";
636   printExpr(C.getIntExpr());
637   OS << ")";
638 }
639 
640 void OpenACCClausePrinter::VisitVectorLengthClause(
641     const OpenACCVectorLengthClause &C) {
642   OS << "vector_length(";
643   printExpr(C.getIntExpr());
644   OS << ")";
645 }
646 
647 void OpenACCClausePrinter::VisitDeviceNumClause(
648     const OpenACCDeviceNumClause &C) {
649   OS << "device_num(";
650   printExpr(C.getIntExpr());
651   OS << ")";
652 }
653 
654 void OpenACCClausePrinter::VisitDefaultAsyncClause(
655     const OpenACCDefaultAsyncClause &C) {
656   OS << "default_async(";
657   printExpr(C.getIntExpr());
658   OS << ")";
659 }
660 
661 void OpenACCClausePrinter::VisitAsyncClause(const OpenACCAsyncClause &C) {
662   OS << "async";
663   if (C.hasIntExpr()) {
664     OS << "(";
665     printExpr(C.getIntExpr());
666     OS << ")";
667   }
668 }
669 
670 void OpenACCClausePrinter::VisitPrivateClause(const OpenACCPrivateClause &C) {
671   OS << "private(";
672   llvm::interleaveComma(C.getVarList(), OS,
673                         [&](const Expr *E) { printExpr(E); });
674   OS << ")";
675 }
676 
677 void OpenACCClausePrinter::VisitFirstPrivateClause(
678     const OpenACCFirstPrivateClause &C) {
679   OS << "firstprivate(";
680   llvm::interleaveComma(C.getVarList(), OS,
681                         [&](const Expr *E) { printExpr(E); });
682   OS << ")";
683 }
684 
685 void OpenACCClausePrinter::VisitAttachClause(const OpenACCAttachClause &C) {
686   OS << "attach(";
687   llvm::interleaveComma(C.getVarList(), OS,
688                         [&](const Expr *E) { printExpr(E); });
689   OS << ")";
690 }
691 
692 void OpenACCClausePrinter::VisitDetachClause(const OpenACCDetachClause &C) {
693   OS << "detach(";
694   llvm::interleaveComma(C.getVarList(), OS,
695                         [&](const Expr *E) { printExpr(E); });
696   OS << ")";
697 }
698 
699 void OpenACCClausePrinter::VisitDeleteClause(const OpenACCDeleteClause &C) {
700   OS << "delete(";
701   llvm::interleaveComma(C.getVarList(), OS,
702                         [&](const Expr *E) { printExpr(E); });
703   OS << ")";
704 }
705 
706 void OpenACCClausePrinter::VisitUseDeviceClause(
707     const OpenACCUseDeviceClause &C) {
708   OS << "use_device(";
709   llvm::interleaveComma(C.getVarList(), OS,
710                         [&](const Expr *E) { printExpr(E); });
711   OS << ")";
712 }
713 
714 void OpenACCClausePrinter::VisitDevicePtrClause(
715     const OpenACCDevicePtrClause &C) {
716   OS << "deviceptr(";
717   llvm::interleaveComma(C.getVarList(), OS,
718                         [&](const Expr *E) { printExpr(E); });
719   OS << ")";
720 }
721 
722 void OpenACCClausePrinter::VisitNoCreateClause(const OpenACCNoCreateClause &C) {
723   OS << "no_create(";
724   llvm::interleaveComma(C.getVarList(), OS,
725                         [&](const Expr *E) { printExpr(E); });
726   OS << ")";
727 }
728 
729 void OpenACCClausePrinter::VisitPresentClause(const OpenACCPresentClause &C) {
730   OS << "present(";
731   llvm::interleaveComma(C.getVarList(), OS,
732                         [&](const Expr *E) { printExpr(E); });
733   OS << ")";
734 }
735 
736 void OpenACCClausePrinter::VisitHostClause(const OpenACCHostClause &C) {
737   OS << "host(";
738   llvm::interleaveComma(C.getVarList(), OS,
739                         [&](const Expr *E) { printExpr(E); });
740   OS << ")";
741 }
742 
743 void OpenACCClausePrinter::VisitDeviceClause(const OpenACCDeviceClause &C) {
744   OS << "device(";
745   llvm::interleaveComma(C.getVarList(), OS,
746                         [&](const Expr *E) { printExpr(E); });
747   OS << ")";
748 }
749 
750 void OpenACCClausePrinter::VisitCopyClause(const OpenACCCopyClause &C) {
751   OS << C.getClauseKind() << '(';
752   llvm::interleaveComma(C.getVarList(), OS,
753                         [&](const Expr *E) { printExpr(E); });
754   OS << ")";
755 }
756 
757 void OpenACCClausePrinter::VisitCopyInClause(const OpenACCCopyInClause &C) {
758   OS << C.getClauseKind() << '(';
759   if (C.isReadOnly())
760     OS << "readonly: ";
761   llvm::interleaveComma(C.getVarList(), OS,
762                         [&](const Expr *E) { printExpr(E); });
763   OS << ")";
764 }
765 
766 void OpenACCClausePrinter::VisitCopyOutClause(const OpenACCCopyOutClause &C) {
767   OS << C.getClauseKind() << '(';
768   if (C.isZero())
769     OS << "zero: ";
770   llvm::interleaveComma(C.getVarList(), OS,
771                         [&](const Expr *E) { printExpr(E); });
772   OS << ")";
773 }
774 
775 void OpenACCClausePrinter::VisitCreateClause(const OpenACCCreateClause &C) {
776   OS << C.getClauseKind() << '(';
777   if (C.isZero())
778     OS << "zero: ";
779   llvm::interleaveComma(C.getVarList(), OS,
780                         [&](const Expr *E) { printExpr(E); });
781   OS << ")";
782 }
783 
784 void OpenACCClausePrinter::VisitReductionClause(
785     const OpenACCReductionClause &C) {
786   OS << "reduction(" << C.getReductionOp() << ": ";
787   llvm::interleaveComma(C.getVarList(), OS,
788                         [&](const Expr *E) { printExpr(E); });
789   OS << ")";
790 }
791 
792 void OpenACCClausePrinter::VisitWaitClause(const OpenACCWaitClause &C) {
793   OS << "wait";
794   if (!C.getLParenLoc().isInvalid()) {
795     OS << "(";
796     if (C.hasDevNumExpr()) {
797       OS << "devnum: ";
798       printExpr(C.getDevNumExpr());
799       OS << " : ";
800     }
801 
802     if (C.hasQueuesTag())
803       OS << "queues: ";
804 
805     llvm::interleaveComma(C.getQueueIdExprs(), OS,
806                           [&](const Expr *E) { printExpr(E); });
807     OS << ")";
808   }
809 }
810 
811 void OpenACCClausePrinter::VisitDeviceTypeClause(
812     const OpenACCDeviceTypeClause &C) {
813   OS << C.getClauseKind();
814   OS << "(";
815   llvm::interleaveComma(C.getArchitectures(), OS,
816                         [&](const DeviceTypeArgument &Arch) {
817                           if (Arch.first == nullptr)
818                             OS << "*";
819                           else
820                             OS << Arch.first->getName();
821                         });
822   OS << ")";
823 }
824 
825 void OpenACCClausePrinter::VisitAutoClause(const OpenACCAutoClause &C) {
826   OS << "auto";
827 }
828 
829 void OpenACCClausePrinter::VisitIndependentClause(
830     const OpenACCIndependentClause &C) {
831   OS << "independent";
832 }
833 
834 void OpenACCClausePrinter::VisitSeqClause(const OpenACCSeqClause &C) {
835   OS << "seq";
836 }
837 
838 void OpenACCClausePrinter::VisitCollapseClause(const OpenACCCollapseClause &C) {
839   OS << "collapse(";
840   if (C.hasForce())
841     OS << "force:";
842   printExpr(C.getLoopCount());
843   OS << ")";
844 }
845 
846 void OpenACCClausePrinter::VisitGangClause(const OpenACCGangClause &C) {
847   OS << "gang";
848 
849   if (C.getNumExprs() > 0) {
850     OS << "(";
851     bool first = true;
852     for (unsigned I = 0; I < C.getNumExprs(); ++I) {
853       if (!first)
854         OS << ", ";
855       first = false;
856 
857       OS << C.getExpr(I).first << ": ";
858       printExpr(C.getExpr(I).second);
859     }
860     OS << ")";
861   }
862 }
863 
864 void OpenACCClausePrinter::VisitWorkerClause(const OpenACCWorkerClause &C) {
865   OS << "worker";
866 
867   if (C.hasIntExpr()) {
868     OS << "(num: ";
869     printExpr(C.getIntExpr());
870     OS << ")";
871   }
872 }
873 
874 void OpenACCClausePrinter::VisitVectorClause(const OpenACCVectorClause &C) {
875   OS << "vector";
876 
877   if (C.hasIntExpr()) {
878     OS << "(length: ";
879     printExpr(C.getIntExpr());
880     OS << ")";
881   }
882 }
883 
884 void OpenACCClausePrinter::VisitFinalizeClause(const OpenACCFinalizeClause &C) {
885   OS << "finalize";
886 }
887 
888 void OpenACCClausePrinter::VisitIfPresentClause(
889     const OpenACCIfPresentClause &C) {
890   OS << "if_present";
891 }
892