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
18using namespace clang;
19
20bool OpenACCClauseWithParams::classof(const OpenACCClause *C) {
21 return OpenACCDeviceTypeClause::classof(C) ||
22 OpenACCClauseWithCondition::classof(C) ||
23 OpenACCClauseWithExprs::classof(C);
24}
25bool OpenACCClauseWithExprs::classof(const OpenACCClause *C) {
26 return OpenACCWaitClause::classof(C) || OpenACCNumGangsClause::classof(C) ||
27 OpenACCClauseWithSingleIntExpr::classof(C) ||
28 OpenACCClauseWithVarList::classof(C);
29}
30bool OpenACCClauseWithVarList::classof(const OpenACCClause *C) {
31 return OpenACCPrivateClause::classof(C) ||
32 OpenACCFirstPrivateClause::classof(C) ||
33 OpenACCDevicePtrClause::classof(C) ||
34 OpenACCDevicePtrClause::classof(C) ||
35 OpenACCAttachClause::classof(C) || OpenACCNoCreateClause::classof(C) ||
36 OpenACCPresentClause::classof(C) || OpenACCCopyClause::classof(C) ||
37 OpenACCCopyInClause::classof(C) || OpenACCCopyOutClause::classof(C) ||
38 OpenACCReductionClause::classof(C) || OpenACCCreateClause::classof(C);
39}
40bool OpenACCClauseWithCondition::classof(const OpenACCClause *C) {
41 return OpenACCIfClause::classof(C) || OpenACCSelfClause::classof(C);
42}
43bool OpenACCClauseWithSingleIntExpr::classof(const OpenACCClause *C) {
44 return OpenACCNumWorkersClause::classof(C) ||
45 OpenACCVectorLengthClause::classof(C) ||
46 OpenACCAsyncClause::classof(C);
47}
48OpenACCDefaultClause *OpenACCDefaultClause::Create(const ASTContext &C,
49 OpenACCDefaultClauseKind K,
50 SourceLocation BeginLoc,
51 SourceLocation LParenLoc,
52 SourceLocation EndLoc) {
53 void *Mem =
54 C.Allocate(Size: sizeof(OpenACCDefaultClause), Align: alignof(OpenACCDefaultClause));
55
56 return new (Mem) OpenACCDefaultClause(K, BeginLoc, LParenLoc, EndLoc);
57}
58
59OpenACCIfClause *OpenACCIfClause::Create(const ASTContext &C,
60 SourceLocation BeginLoc,
61 SourceLocation LParenLoc,
62 Expr *ConditionExpr,
63 SourceLocation EndLoc) {
64 void *Mem = C.Allocate(Size: sizeof(OpenACCIfClause), Align: alignof(OpenACCIfClause));
65 return new (Mem) OpenACCIfClause(BeginLoc, LParenLoc, ConditionExpr, EndLoc);
66}
67
68OpenACCIfClause::OpenACCIfClause(SourceLocation BeginLoc,
69 SourceLocation LParenLoc, Expr *ConditionExpr,
70 SourceLocation EndLoc)
71 : OpenACCClauseWithCondition(OpenACCClauseKind::If, BeginLoc, LParenLoc,
72 ConditionExpr, EndLoc) {
73 assert(ConditionExpr && "if clause requires condition expr");
74 assert((ConditionExpr->isInstantiationDependent() ||
75 ConditionExpr->getType()->isScalarType()) &&
76 "Condition expression type not scalar/dependent");
77}
78
79OpenACCSelfClause *OpenACCSelfClause::Create(const ASTContext &C,
80 SourceLocation BeginLoc,
81 SourceLocation LParenLoc,
82 Expr *ConditionExpr,
83 SourceLocation EndLoc) {
84 void *Mem = C.Allocate(Size: sizeof(OpenACCIfClause), Align: alignof(OpenACCIfClause));
85 return new (Mem)
86 OpenACCSelfClause(BeginLoc, LParenLoc, ConditionExpr, EndLoc);
87}
88
89OpenACCSelfClause::OpenACCSelfClause(SourceLocation BeginLoc,
90 SourceLocation LParenLoc,
91 Expr *ConditionExpr, SourceLocation EndLoc)
92 : OpenACCClauseWithCondition(OpenACCClauseKind::Self, BeginLoc, LParenLoc,
93 ConditionExpr, EndLoc) {
94 assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() ||
95 ConditionExpr->getType()->isScalarType()) &&
96 "Condition expression type not scalar/dependent");
97}
98
99OpenACCClause::child_range OpenACCClause::children() {
100 switch (getClauseKind()) {
101 default:
102 assert(false && "Clause children function not implemented");
103 break;
104#define VISIT_CLAUSE(CLAUSE_NAME) \
105 case OpenACCClauseKind::CLAUSE_NAME: \
106 return cast<OpenACC##CLAUSE_NAME##Clause>(this)->children();
107#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \
108 case OpenACCClauseKind::ALIAS_NAME: \
109 return cast<OpenACC##CLAUSE_NAME##Clause>(this)->children();
110
111#include "clang/Basic/OpenACCClauses.def"
112 }
113 return child_range(child_iterator(), child_iterator());
114}
115
116OpenACCNumWorkersClause::OpenACCNumWorkersClause(SourceLocation BeginLoc,
117 SourceLocation LParenLoc,
118 Expr *IntExpr,
119 SourceLocation EndLoc)
120 : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::NumWorkers, BeginLoc,
121 LParenLoc, IntExpr, EndLoc) {
122 assert((!IntExpr || IntExpr->isInstantiationDependent() ||
123 IntExpr->getType()->isIntegerType()) &&
124 "Condition expression type not scalar/dependent");
125}
126
127OpenACCNumWorkersClause *
128OpenACCNumWorkersClause::Create(const ASTContext &C, SourceLocation BeginLoc,
129 SourceLocation LParenLoc, Expr *IntExpr,
130 SourceLocation EndLoc) {
131 void *Mem = C.Allocate(Size: sizeof(OpenACCNumWorkersClause),
132 Align: alignof(OpenACCNumWorkersClause));
133 return new (Mem)
134 OpenACCNumWorkersClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
135}
136
137OpenACCVectorLengthClause::OpenACCVectorLengthClause(SourceLocation BeginLoc,
138 SourceLocation LParenLoc,
139 Expr *IntExpr,
140 SourceLocation EndLoc)
141 : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::VectorLength, BeginLoc,
142 LParenLoc, IntExpr, EndLoc) {
143 assert((!IntExpr || IntExpr->isInstantiationDependent() ||
144 IntExpr->getType()->isIntegerType()) &&
145 "Condition expression type not scalar/dependent");
146}
147
148OpenACCVectorLengthClause *
149OpenACCVectorLengthClause::Create(const ASTContext &C, SourceLocation BeginLoc,
150 SourceLocation LParenLoc, Expr *IntExpr,
151 SourceLocation EndLoc) {
152 void *Mem = C.Allocate(Size: sizeof(OpenACCVectorLengthClause),
153 Align: alignof(OpenACCVectorLengthClause));
154 return new (Mem)
155 OpenACCVectorLengthClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
156}
157
158OpenACCAsyncClause::OpenACCAsyncClause(SourceLocation BeginLoc,
159 SourceLocation LParenLoc, Expr *IntExpr,
160 SourceLocation EndLoc)
161 : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::Async, BeginLoc,
162 LParenLoc, IntExpr, EndLoc) {
163 assert((!IntExpr || IntExpr->isInstantiationDependent() ||
164 IntExpr->getType()->isIntegerType()) &&
165 "Condition expression type not scalar/dependent");
166}
167
168OpenACCAsyncClause *OpenACCAsyncClause::Create(const ASTContext &C,
169 SourceLocation BeginLoc,
170 SourceLocation LParenLoc,
171 Expr *IntExpr,
172 SourceLocation EndLoc) {
173 void *Mem =
174 C.Allocate(Size: sizeof(OpenACCAsyncClause), Align: alignof(OpenACCAsyncClause));
175 return new (Mem) OpenACCAsyncClause(BeginLoc, LParenLoc, IntExpr, EndLoc);
176}
177
178OpenACCWaitClause *OpenACCWaitClause::Create(
179 const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
180 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
181 SourceLocation EndLoc) {
182 // Allocates enough room in trailing storage for all the int-exprs, plus a
183 // placeholder for the devnum.
184 void *Mem = C.Allocate(
185 Size: OpenACCWaitClause::totalSizeToAlloc<Expr *>(Counts: QueueIdExprs.size() + 1));
186 return new (Mem) OpenACCWaitClause(BeginLoc, LParenLoc, DevNumExpr, QueuesLoc,
187 QueueIdExprs, EndLoc);
188}
189
190OpenACCNumGangsClause *OpenACCNumGangsClause::Create(const ASTContext &C,
191 SourceLocation BeginLoc,
192 SourceLocation LParenLoc,
193 ArrayRef<Expr *> IntExprs,
194 SourceLocation EndLoc) {
195 void *Mem = C.Allocate(
196 Size: OpenACCNumGangsClause::totalSizeToAlloc<Expr *>(Counts: IntExprs.size()));
197 return new (Mem) OpenACCNumGangsClause(BeginLoc, LParenLoc, IntExprs, EndLoc);
198}
199
200OpenACCPrivateClause *OpenACCPrivateClause::Create(const ASTContext &C,
201 SourceLocation BeginLoc,
202 SourceLocation LParenLoc,
203 ArrayRef<Expr *> VarList,
204 SourceLocation EndLoc) {
205 void *Mem = C.Allocate(
206 Size: OpenACCPrivateClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
207 return new (Mem) OpenACCPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
208}
209
210OpenACCFirstPrivateClause *OpenACCFirstPrivateClause::Create(
211 const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
212 ArrayRef<Expr *> VarList, SourceLocation EndLoc) {
213 void *Mem = C.Allocate(
214 Size: OpenACCFirstPrivateClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
215 return new (Mem)
216 OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
217}
218
219OpenACCAttachClause *OpenACCAttachClause::Create(const ASTContext &C,
220 SourceLocation BeginLoc,
221 SourceLocation LParenLoc,
222 ArrayRef<Expr *> VarList,
223 SourceLocation EndLoc) {
224 void *Mem =
225 C.Allocate(Size: OpenACCAttachClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
226 return new (Mem) OpenACCAttachClause(BeginLoc, LParenLoc, VarList, EndLoc);
227}
228
229OpenACCDevicePtrClause *OpenACCDevicePtrClause::Create(const ASTContext &C,
230 SourceLocation BeginLoc,
231 SourceLocation LParenLoc,
232 ArrayRef<Expr *> VarList,
233 SourceLocation EndLoc) {
234 void *Mem = C.Allocate(
235 Size: OpenACCDevicePtrClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
236 return new (Mem) OpenACCDevicePtrClause(BeginLoc, LParenLoc, VarList, EndLoc);
237}
238
239OpenACCNoCreateClause *OpenACCNoCreateClause::Create(const ASTContext &C,
240 SourceLocation BeginLoc,
241 SourceLocation LParenLoc,
242 ArrayRef<Expr *> VarList,
243 SourceLocation EndLoc) {
244 void *Mem = C.Allocate(
245 Size: OpenACCNoCreateClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
246 return new (Mem) OpenACCNoCreateClause(BeginLoc, LParenLoc, VarList, EndLoc);
247}
248
249OpenACCPresentClause *OpenACCPresentClause::Create(const ASTContext &C,
250 SourceLocation BeginLoc,
251 SourceLocation LParenLoc,
252 ArrayRef<Expr *> VarList,
253 SourceLocation EndLoc) {
254 void *Mem = C.Allocate(
255 Size: OpenACCPresentClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
256 return new (Mem) OpenACCPresentClause(BeginLoc, LParenLoc, VarList, EndLoc);
257}
258
259OpenACCCopyClause *
260OpenACCCopyClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
261 SourceLocation BeginLoc, SourceLocation LParenLoc,
262 ArrayRef<Expr *> VarList, SourceLocation EndLoc) {
263 void *Mem =
264 C.Allocate(Size: OpenACCCopyClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
265 return new (Mem)
266 OpenACCCopyClause(Spelling, BeginLoc, LParenLoc, VarList, EndLoc);
267}
268
269OpenACCCopyInClause *
270OpenACCCopyInClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
271 SourceLocation BeginLoc, SourceLocation LParenLoc,
272 bool IsReadOnly, ArrayRef<Expr *> VarList,
273 SourceLocation EndLoc) {
274 void *Mem =
275 C.Allocate(Size: OpenACCCopyInClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
276 return new (Mem) OpenACCCopyInClause(Spelling, BeginLoc, LParenLoc,
277 IsReadOnly, VarList, EndLoc);
278}
279
280OpenACCCopyOutClause *
281OpenACCCopyOutClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
282 SourceLocation BeginLoc, SourceLocation LParenLoc,
283 bool IsZero, ArrayRef<Expr *> VarList,
284 SourceLocation EndLoc) {
285 void *Mem = C.Allocate(
286 Size: OpenACCCopyOutClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
287 return new (Mem) OpenACCCopyOutClause(Spelling, BeginLoc, LParenLoc, IsZero,
288 VarList, EndLoc);
289}
290
291OpenACCCreateClause *
292OpenACCCreateClause::Create(const ASTContext &C, OpenACCClauseKind Spelling,
293 SourceLocation BeginLoc, SourceLocation LParenLoc,
294 bool IsZero, ArrayRef<Expr *> VarList,
295 SourceLocation EndLoc) {
296 void *Mem =
297 C.Allocate(Size: OpenACCCreateClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
298 return new (Mem) OpenACCCreateClause(Spelling, BeginLoc, LParenLoc, IsZero,
299 VarList, EndLoc);
300}
301
302OpenACCDeviceTypeClause *OpenACCDeviceTypeClause::Create(
303 const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc,
304 SourceLocation LParenLoc, ArrayRef<DeviceTypeArgument> Archs,
305 SourceLocation EndLoc) {
306 void *Mem =
307 C.Allocate(Size: OpenACCDeviceTypeClause::totalSizeToAlloc<DeviceTypeArgument>(
308 Counts: Archs.size()));
309 return new (Mem)
310 OpenACCDeviceTypeClause(K, BeginLoc, LParenLoc, Archs, EndLoc);
311}
312
313OpenACCReductionClause *OpenACCReductionClause::Create(
314 const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
315 OpenACCReductionOperator Operator, ArrayRef<Expr *> VarList,
316 SourceLocation EndLoc) {
317 void *Mem = C.Allocate(
318 Size: OpenACCReductionClause::totalSizeToAlloc<Expr *>(Counts: VarList.size()));
319 return new (Mem)
320 OpenACCReductionClause(BeginLoc, LParenLoc, Operator, VarList, EndLoc);
321}
322
323OpenACCAutoClause *OpenACCAutoClause::Create(const ASTContext &C,
324 SourceLocation BeginLoc,
325 SourceLocation EndLoc) {
326 void *Mem = C.Allocate(Size: sizeof(OpenACCAutoClause));
327 return new (Mem) OpenACCAutoClause(BeginLoc, EndLoc);
328}
329
330OpenACCIndependentClause *
331OpenACCIndependentClause::Create(const ASTContext &C, SourceLocation BeginLoc,
332 SourceLocation EndLoc) {
333 void *Mem = C.Allocate(Size: sizeof(OpenACCIndependentClause));
334 return new (Mem) OpenACCIndependentClause(BeginLoc, EndLoc);
335}
336
337OpenACCSeqClause *OpenACCSeqClause::Create(const ASTContext &C,
338 SourceLocation BeginLoc,
339 SourceLocation EndLoc) {
340 void *Mem = C.Allocate(Size: sizeof(OpenACCSeqClause));
341 return new (Mem) OpenACCSeqClause(BeginLoc, EndLoc);
342}
343
344OpenACCGangClause *OpenACCGangClause::Create(const ASTContext &C,
345 SourceLocation BeginLoc,
346 SourceLocation EndLoc) {
347 void *Mem = C.Allocate(Size: sizeof(OpenACCGangClause));
348 return new (Mem) OpenACCGangClause(BeginLoc, EndLoc);
349}
350
351OpenACCWorkerClause *OpenACCWorkerClause::Create(const ASTContext &C,
352 SourceLocation BeginLoc,
353 SourceLocation EndLoc) {
354 void *Mem = C.Allocate(Size: sizeof(OpenACCWorkerClause));
355 return new (Mem) OpenACCWorkerClause(BeginLoc, EndLoc);
356}
357
358OpenACCVectorClause *OpenACCVectorClause::Create(const ASTContext &C,
359 SourceLocation BeginLoc,
360 SourceLocation EndLoc) {
361 void *Mem = C.Allocate(Size: sizeof(OpenACCVectorClause));
362 return new (Mem) OpenACCVectorClause(BeginLoc, EndLoc);
363}
364
365//===----------------------------------------------------------------------===//
366// OpenACC clauses printing methods
367//===----------------------------------------------------------------------===//
368
369void OpenACCClausePrinter::printExpr(const Expr *E) {
370 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
371}
372
373void OpenACCClausePrinter::VisitDefaultClause(const OpenACCDefaultClause &C) {
374 OS << "default(" << C.getDefaultClauseKind() << ")";
375}
376
377void OpenACCClausePrinter::VisitIfClause(const OpenACCIfClause &C) {
378 OS << "if(";
379 printExpr(E: C.getConditionExpr());
380 OS << ")";
381}
382
383void OpenACCClausePrinter::VisitSelfClause(const OpenACCSelfClause &C) {
384 OS << "self";
385 if (const Expr *CondExpr = C.getConditionExpr()) {
386 OS << "(";
387 printExpr(E: CondExpr);
388 OS << ")";
389 }
390}
391
392void OpenACCClausePrinter::VisitNumGangsClause(const OpenACCNumGangsClause &C) {
393 OS << "num_gangs(";
394 llvm::interleaveComma(c: C.getIntExprs(), os&: OS,
395 each_fn: [&](const Expr *E) { printExpr(E); });
396 OS << ")";
397}
398
399void OpenACCClausePrinter::VisitNumWorkersClause(
400 const OpenACCNumWorkersClause &C) {
401 OS << "num_workers(";
402 printExpr(E: C.getIntExpr());
403 OS << ")";
404}
405
406void OpenACCClausePrinter::VisitVectorLengthClause(
407 const OpenACCVectorLengthClause &C) {
408 OS << "vector_length(";
409 printExpr(E: C.getIntExpr());
410 OS << ")";
411}
412
413void OpenACCClausePrinter::VisitAsyncClause(const OpenACCAsyncClause &C) {
414 OS << "async";
415 if (C.hasIntExpr()) {
416 OS << "(";
417 printExpr(E: C.getIntExpr());
418 OS << ")";
419 }
420}
421
422void OpenACCClausePrinter::VisitPrivateClause(const OpenACCPrivateClause &C) {
423 OS << "private(";
424 llvm::interleaveComma(c: C.getVarList(), os&: OS,
425 each_fn: [&](const Expr *E) { printExpr(E); });
426 OS << ")";
427}
428
429void OpenACCClausePrinter::VisitFirstPrivateClause(
430 const OpenACCFirstPrivateClause &C) {
431 OS << "firstprivate(";
432 llvm::interleaveComma(c: C.getVarList(), os&: OS,
433 each_fn: [&](const Expr *E) { printExpr(E); });
434 OS << ")";
435}
436
437void OpenACCClausePrinter::VisitAttachClause(const OpenACCAttachClause &C) {
438 OS << "attach(";
439 llvm::interleaveComma(c: C.getVarList(), os&: OS,
440 each_fn: [&](const Expr *E) { printExpr(E); });
441 OS << ")";
442}
443
444void OpenACCClausePrinter::VisitDevicePtrClause(
445 const OpenACCDevicePtrClause &C) {
446 OS << "deviceptr(";
447 llvm::interleaveComma(c: C.getVarList(), os&: OS,
448 each_fn: [&](const Expr *E) { printExpr(E); });
449 OS << ")";
450}
451
452void OpenACCClausePrinter::VisitNoCreateClause(const OpenACCNoCreateClause &C) {
453 OS << "no_create(";
454 llvm::interleaveComma(c: C.getVarList(), os&: OS,
455 each_fn: [&](const Expr *E) { printExpr(E); });
456 OS << ")";
457}
458
459void OpenACCClausePrinter::VisitPresentClause(const OpenACCPresentClause &C) {
460 OS << "present(";
461 llvm::interleaveComma(c: C.getVarList(), os&: OS,
462 each_fn: [&](const Expr *E) { printExpr(E); });
463 OS << ")";
464}
465
466void OpenACCClausePrinter::VisitCopyClause(const OpenACCCopyClause &C) {
467 OS << C.getClauseKind() << '(';
468 llvm::interleaveComma(c: C.getVarList(), os&: OS,
469 each_fn: [&](const Expr *E) { printExpr(E); });
470 OS << ")";
471}
472
473void OpenACCClausePrinter::VisitCopyInClause(const OpenACCCopyInClause &C) {
474 OS << C.getClauseKind() << '(';
475 if (C.isReadOnly())
476 OS << "readonly: ";
477 llvm::interleaveComma(c: C.getVarList(), os&: OS,
478 each_fn: [&](const Expr *E) { printExpr(E); });
479 OS << ")";
480}
481
482void OpenACCClausePrinter::VisitCopyOutClause(const OpenACCCopyOutClause &C) {
483 OS << C.getClauseKind() << '(';
484 if (C.isZero())
485 OS << "zero: ";
486 llvm::interleaveComma(c: C.getVarList(), os&: OS,
487 each_fn: [&](const Expr *E) { printExpr(E); });
488 OS << ")";
489}
490
491void OpenACCClausePrinter::VisitCreateClause(const OpenACCCreateClause &C) {
492 OS << C.getClauseKind() << '(';
493 if (C.isZero())
494 OS << "zero: ";
495 llvm::interleaveComma(c: C.getVarList(), os&: OS,
496 each_fn: [&](const Expr *E) { printExpr(E); });
497 OS << ")";
498}
499
500void OpenACCClausePrinter::VisitReductionClause(
501 const OpenACCReductionClause &C) {
502 OS << "reduction(" << C.getReductionOp() << ": ";
503 llvm::interleaveComma(c: C.getVarList(), os&: OS,
504 each_fn: [&](const Expr *E) { printExpr(E); });
505 OS << ")";
506}
507
508void OpenACCClausePrinter::VisitWaitClause(const OpenACCWaitClause &C) {
509 OS << "wait";
510 if (!C.getLParenLoc().isInvalid()) {
511 OS << "(";
512 if (C.hasDevNumExpr()) {
513 OS << "devnum: ";
514 printExpr(E: C.getDevNumExpr());
515 OS << " : ";
516 }
517
518 if (C.hasQueuesTag())
519 OS << "queues: ";
520
521 llvm::interleaveComma(c: C.getQueueIdExprs(), os&: OS,
522 each_fn: [&](const Expr *E) { printExpr(E); });
523 OS << ")";
524 }
525}
526
527void OpenACCClausePrinter::VisitDeviceTypeClause(
528 const OpenACCDeviceTypeClause &C) {
529 OS << C.getClauseKind();
530 OS << "(";
531 llvm::interleaveComma(c: C.getArchitectures(), os&: OS,
532 each_fn: [&](const DeviceTypeArgument &Arch) {
533 if (Arch.first == nullptr)
534 OS << "*";
535 else
536 OS << Arch.first->getName();
537 });
538 OS << ")";
539}
540
541void OpenACCClausePrinter::VisitAutoClause(const OpenACCAutoClause &C) {
542 OS << "auto";
543}
544
545void OpenACCClausePrinter::VisitIndependentClause(
546 const OpenACCIndependentClause &C) {
547 OS << "independent";
548}
549
550void OpenACCClausePrinter::VisitSeqClause(const OpenACCSeqClause &C) {
551 OS << "seq";
552}
553