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