1//===- OpenMPClause.cpp - Classes for OpenMP 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 subclesses of Stmt class declared in OpenMPClause.h
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/OpenMPClause.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Attr.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclOpenMP.h"
18#include "clang/Basic/LLVM.h"
19#include "clang/Basic/OpenMPKinds.h"
20#include "clang/Basic/TargetInfo.h"
21#include "llvm/ADT/SmallPtrSet.h"
22#include "llvm/Support/ErrorHandling.h"
23#include <algorithm>
24#include <cassert>
25#include <optional>
26
27using namespace clang;
28using namespace llvm;
29using namespace omp;
30
31OMPClause::child_range OMPClause::children() {
32 switch (getClauseKind()) {
33 default:
34 break;
35#define GEN_CLANG_CLAUSE_CLASS
36#define CLAUSE_CLASS(Enum, Str, Class) \
37 case Enum: \
38 return static_cast<Class *>(this)->children();
39#include "llvm/Frontend/OpenMP/OMP.inc"
40 }
41 llvm_unreachable("unknown OMPClause");
42}
43
44OMPClause::child_range OMPClause::used_children() {
45 switch (getClauseKind()) {
46#define GEN_CLANG_CLAUSE_CLASS
47#define CLAUSE_CLASS(Enum, Str, Class) \
48 case Enum: \
49 return static_cast<Class *>(this)->used_children();
50#define CLAUSE_NO_CLASS(Enum, Str) \
51 case Enum: \
52 break;
53#include "llvm/Frontend/OpenMP/OMP.inc"
54 }
55 llvm_unreachable("unknown OMPClause");
56}
57
58OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {
59 auto *Res = OMPClauseWithPreInit::get(C: const_cast<const OMPClause *>(C));
60 return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
61}
62
63const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
64 switch (C->getClauseKind()) {
65 case OMPC_schedule:
66 return static_cast<const OMPScheduleClause *>(C);
67 case OMPC_dist_schedule:
68 return static_cast<const OMPDistScheduleClause *>(C);
69 case OMPC_firstprivate:
70 return static_cast<const OMPFirstprivateClause *>(C);
71 case OMPC_lastprivate:
72 return static_cast<const OMPLastprivateClause *>(C);
73 case OMPC_reduction:
74 return static_cast<const OMPReductionClause *>(C);
75 case OMPC_task_reduction:
76 return static_cast<const OMPTaskReductionClause *>(C);
77 case OMPC_in_reduction:
78 return static_cast<const OMPInReductionClause *>(C);
79 case OMPC_linear:
80 return static_cast<const OMPLinearClause *>(C);
81 case OMPC_if:
82 return static_cast<const OMPIfClause *>(C);
83 case OMPC_num_threads:
84 return static_cast<const OMPNumThreadsClause *>(C);
85 case OMPC_num_teams:
86 return static_cast<const OMPNumTeamsClause *>(C);
87 case OMPC_thread_limit:
88 return static_cast<const OMPThreadLimitClause *>(C);
89 case OMPC_device:
90 return static_cast<const OMPDeviceClause *>(C);
91 case OMPC_grainsize:
92 return static_cast<const OMPGrainsizeClause *>(C);
93 case OMPC_num_tasks:
94 return static_cast<const OMPNumTasksClause *>(C);
95 case OMPC_final:
96 return static_cast<const OMPFinalClause *>(C);
97 case OMPC_priority:
98 return static_cast<const OMPPriorityClause *>(C);
99 case OMPC_novariants:
100 return static_cast<const OMPNovariantsClause *>(C);
101 case OMPC_nocontext:
102 return static_cast<const OMPNocontextClause *>(C);
103 case OMPC_filter:
104 return static_cast<const OMPFilterClause *>(C);
105 case OMPC_ompx_dyn_cgroup_mem:
106 return static_cast<const OMPXDynCGroupMemClause *>(C);
107 case OMPC_default:
108 case OMPC_proc_bind:
109 case OMPC_safelen:
110 case OMPC_simdlen:
111 case OMPC_sizes:
112 case OMPC_allocator:
113 case OMPC_allocate:
114 case OMPC_collapse:
115 case OMPC_private:
116 case OMPC_shared:
117 case OMPC_aligned:
118 case OMPC_copyin:
119 case OMPC_copyprivate:
120 case OMPC_ordered:
121 case OMPC_nowait:
122 case OMPC_untied:
123 case OMPC_mergeable:
124 case OMPC_threadprivate:
125 case OMPC_flush:
126 case OMPC_depobj:
127 case OMPC_read:
128 case OMPC_write:
129 case OMPC_update:
130 case OMPC_capture:
131 case OMPC_compare:
132 case OMPC_fail:
133 case OMPC_seq_cst:
134 case OMPC_acq_rel:
135 case OMPC_acquire:
136 case OMPC_release:
137 case OMPC_relaxed:
138 case OMPC_depend:
139 case OMPC_threads:
140 case OMPC_simd:
141 case OMPC_map:
142 case OMPC_nogroup:
143 case OMPC_hint:
144 case OMPC_defaultmap:
145 case OMPC_unknown:
146 case OMPC_uniform:
147 case OMPC_to:
148 case OMPC_from:
149 case OMPC_use_device_ptr:
150 case OMPC_use_device_addr:
151 case OMPC_is_device_ptr:
152 case OMPC_has_device_addr:
153 case OMPC_unified_address:
154 case OMPC_unified_shared_memory:
155 case OMPC_reverse_offload:
156 case OMPC_dynamic_allocators:
157 case OMPC_atomic_default_mem_order:
158 case OMPC_self_maps:
159 case OMPC_at:
160 case OMPC_severity:
161 case OMPC_message:
162 case OMPC_device_type:
163 case OMPC_match:
164 case OMPC_nontemporal:
165 case OMPC_order:
166 case OMPC_destroy:
167 case OMPC_detach:
168 case OMPC_inclusive:
169 case OMPC_exclusive:
170 case OMPC_uses_allocators:
171 case OMPC_affinity:
172 case OMPC_when:
173 case OMPC_bind:
174 case OMPC_ompx_bare:
175 break;
176 default:
177 break;
178 }
179
180 return nullptr;
181}
182
183OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) {
184 auto *Res = OMPClauseWithPostUpdate::get(C: const_cast<const OMPClause *>(C));
185 return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
186}
187
188const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) {
189 switch (C->getClauseKind()) {
190 case OMPC_lastprivate:
191 return static_cast<const OMPLastprivateClause *>(C);
192 case OMPC_reduction:
193 return static_cast<const OMPReductionClause *>(C);
194 case OMPC_task_reduction:
195 return static_cast<const OMPTaskReductionClause *>(C);
196 case OMPC_in_reduction:
197 return static_cast<const OMPInReductionClause *>(C);
198 case OMPC_linear:
199 return static_cast<const OMPLinearClause *>(C);
200 case OMPC_schedule:
201 case OMPC_dist_schedule:
202 case OMPC_firstprivate:
203 case OMPC_default:
204 case OMPC_proc_bind:
205 case OMPC_if:
206 case OMPC_final:
207 case OMPC_num_threads:
208 case OMPC_safelen:
209 case OMPC_simdlen:
210 case OMPC_sizes:
211 case OMPC_allocator:
212 case OMPC_allocate:
213 case OMPC_collapse:
214 case OMPC_private:
215 case OMPC_shared:
216 case OMPC_aligned:
217 case OMPC_copyin:
218 case OMPC_copyprivate:
219 case OMPC_ordered:
220 case OMPC_nowait:
221 case OMPC_untied:
222 case OMPC_mergeable:
223 case OMPC_threadprivate:
224 case OMPC_flush:
225 case OMPC_depobj:
226 case OMPC_read:
227 case OMPC_write:
228 case OMPC_update:
229 case OMPC_capture:
230 case OMPC_compare:
231 case OMPC_fail:
232 case OMPC_seq_cst:
233 case OMPC_acq_rel:
234 case OMPC_acquire:
235 case OMPC_release:
236 case OMPC_relaxed:
237 case OMPC_depend:
238 case OMPC_device:
239 case OMPC_threads:
240 case OMPC_simd:
241 case OMPC_map:
242 case OMPC_num_teams:
243 case OMPC_thread_limit:
244 case OMPC_priority:
245 case OMPC_grainsize:
246 case OMPC_nogroup:
247 case OMPC_num_tasks:
248 case OMPC_hint:
249 case OMPC_defaultmap:
250 case OMPC_unknown:
251 case OMPC_uniform:
252 case OMPC_to:
253 case OMPC_from:
254 case OMPC_use_device_ptr:
255 case OMPC_use_device_addr:
256 case OMPC_is_device_ptr:
257 case OMPC_has_device_addr:
258 case OMPC_unified_address:
259 case OMPC_unified_shared_memory:
260 case OMPC_reverse_offload:
261 case OMPC_dynamic_allocators:
262 case OMPC_atomic_default_mem_order:
263 case OMPC_self_maps:
264 case OMPC_at:
265 case OMPC_severity:
266 case OMPC_message:
267 case OMPC_device_type:
268 case OMPC_match:
269 case OMPC_nontemporal:
270 case OMPC_order:
271 case OMPC_destroy:
272 case OMPC_novariants:
273 case OMPC_nocontext:
274 case OMPC_detach:
275 case OMPC_inclusive:
276 case OMPC_exclusive:
277 case OMPC_uses_allocators:
278 case OMPC_affinity:
279 case OMPC_when:
280 case OMPC_bind:
281 break;
282 default:
283 break;
284 }
285
286 return nullptr;
287}
288
289/// Gets the address of the original, non-captured, expression used in the
290/// clause as the preinitializer.
291static Stmt **getAddrOfExprAsWritten(Stmt *S) {
292 if (!S)
293 return nullptr;
294 if (auto *DS = dyn_cast<DeclStmt>(Val: S)) {
295 assert(DS->isSingleDecl() && "Only single expression must be captured.");
296 if (auto *OED = dyn_cast<OMPCapturedExprDecl>(Val: DS->getSingleDecl()))
297 return OED->getInitAddress();
298 }
299 return nullptr;
300}
301
302OMPClause::child_range OMPIfClause::used_children() {
303 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
304 return child_range(C, C + 1);
305 return child_range(&Condition, &Condition + 1);
306}
307
308OMPClause::child_range OMPGrainsizeClause::used_children() {
309 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
310 return child_range(C, C + 1);
311 return child_range(&Grainsize, &Grainsize + 1);
312}
313
314OMPClause::child_range OMPNumTasksClause::used_children() {
315 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
316 return child_range(C, C + 1);
317 return child_range(&NumTasks, &NumTasks + 1);
318}
319
320OMPClause::child_range OMPFinalClause::used_children() {
321 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
322 return child_range(C, C + 1);
323 return children();
324}
325
326OMPClause::child_range OMPPriorityClause::used_children() {
327 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
328 return child_range(C, C + 1);
329 return child_range(&Priority, &Priority + 1);
330}
331
332OMPClause::child_range OMPNovariantsClause::used_children() {
333 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
334 return child_range(C, C + 1);
335 return children();
336}
337
338OMPClause::child_range OMPNocontextClause::used_children() {
339 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
340 return child_range(C, C + 1);
341 return children();
342}
343
344OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,
345 unsigned NumLoops,
346 SourceLocation StartLoc,
347 SourceLocation LParenLoc,
348 SourceLocation EndLoc) {
349 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * NumLoops));
350 auto *Clause =
351 new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);
352 for (unsigned I = 0; I < NumLoops; ++I) {
353 Clause->setLoopNumIterations(NumLoop: I, NumIterations: nullptr);
354 Clause->setLoopCounter(NumLoop: I, Counter: nullptr);
355 }
356 return Clause;
357}
358
359OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C,
360 unsigned NumLoops) {
361 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * NumLoops));
362 auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
363 for (unsigned I = 0; I < NumLoops; ++I) {
364 Clause->setLoopNumIterations(NumLoop: I, NumIterations: nullptr);
365 Clause->setLoopCounter(NumLoop: I, Counter: nullptr);
366 }
367 return Clause;
368}
369
370void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop,
371 Expr *NumIterations) {
372 assert(NumLoop < NumberOfLoops && "out of loops number.");
373 getTrailingObjects()[NumLoop] = NumIterations;
374}
375
376ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations() const {
377 return getTrailingObjects(N: NumberOfLoops);
378}
379
380void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {
381 assert(NumLoop < NumberOfLoops && "out of loops number.");
382 getTrailingObjects()[NumberOfLoops + NumLoop] = Counter;
383}
384
385Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) {
386 assert(NumLoop < NumberOfLoops && "out of loops number.");
387 return getTrailingObjects()[NumberOfLoops + NumLoop];
388}
389
390const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
391 assert(NumLoop < NumberOfLoops && "out of loops number.");
392 return getTrailingObjects()[NumberOfLoops + NumLoop];
393}
394
395OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C,
396 SourceLocation StartLoc,
397 SourceLocation EndLoc) {
398 return new (C) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/false);
399}
400
401OMPUpdateClause *
402OMPUpdateClause::Create(const ASTContext &C, SourceLocation StartLoc,
403 SourceLocation LParenLoc, SourceLocation ArgumentLoc,
404 OpenMPDependClauseKind DK, SourceLocation EndLoc) {
405 void *Mem =
406 C.Allocate(Size: totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(Counts: 2, Counts: 1),
407 Align: alignof(OMPUpdateClause));
408 auto *Clause =
409 new (Mem) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/true);
410 Clause->setLParenLoc(LParenLoc);
411 Clause->setArgumentLoc(ArgumentLoc);
412 Clause->setDependencyKind(DK);
413 return Clause;
414}
415
416OMPUpdateClause *OMPUpdateClause::CreateEmpty(const ASTContext &C,
417 bool IsExtended) {
418 if (!IsExtended)
419 return new (C) OMPUpdateClause(/*IsExtended=*/false);
420 void *Mem =
421 C.Allocate(Size: totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(Counts: 2, Counts: 1),
422 Align: alignof(OMPUpdateClause));
423 auto *Clause = new (Mem) OMPUpdateClause(/*IsExtended=*/true);
424 Clause->IsExtended = true;
425 return Clause;
426}
427
428void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
429 assert(VL.size() == varlist_size() &&
430 "Number of private copies is not the same as the preallocated buffer");
431 llvm::copy(Range&: VL, Out: varlist_end());
432}
433
434OMPPrivateClause *
435OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
436 SourceLocation LParenLoc, SourceLocation EndLoc,
437 ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
438 // Allocate space for private variables and initializer expressions.
439 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * VL.size()));
440 OMPPrivateClause *Clause =
441 new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
442 Clause->setVarRefs(VL);
443 Clause->setPrivateCopies(PrivateVL);
444 return Clause;
445}
446
447OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
448 unsigned N) {
449 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * N));
450 return new (Mem) OMPPrivateClause(N);
451}
452
453void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
454 assert(VL.size() == varlist_size() &&
455 "Number of private copies is not the same as the preallocated buffer");
456 llvm::copy(Range&: VL, Out: varlist_end());
457}
458
459void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
460 assert(VL.size() == varlist_size() &&
461 "Number of inits is not the same as the preallocated buffer");
462 llvm::copy(Range&: VL, Out: getPrivateCopies().end());
463}
464
465OMPFirstprivateClause *
466OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
467 SourceLocation LParenLoc, SourceLocation EndLoc,
468 ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
469 ArrayRef<Expr *> InitVL, Stmt *PreInit) {
470 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 3 * VL.size()));
471 OMPFirstprivateClause *Clause =
472 new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
473 Clause->setVarRefs(VL);
474 Clause->setPrivateCopies(PrivateVL);
475 Clause->setInits(InitVL);
476 Clause->setPreInitStmt(S: PreInit);
477 return Clause;
478}
479
480OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
481 unsigned N) {
482 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 3 * N));
483 return new (Mem) OMPFirstprivateClause(N);
484}
485
486void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
487 assert(PrivateCopies.size() == varlist_size() &&
488 "Number of private copies is not the same as the preallocated buffer");
489 llvm::copy(Range&: PrivateCopies, Out: varlist_end());
490}
491
492void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
493 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
494 "not the same as the "
495 "preallocated buffer");
496 llvm::copy(Range&: SrcExprs, Out: getPrivateCopies().end());
497}
498
499void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
500 assert(DstExprs.size() == varlist_size() && "Number of destination "
501 "expressions is not the same as "
502 "the preallocated buffer");
503 llvm::copy(Range&: DstExprs, Out: getSourceExprs().end());
504}
505
506void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
507 assert(AssignmentOps.size() == varlist_size() &&
508 "Number of assignment expressions is not the same as the preallocated "
509 "buffer");
510 llvm::copy(Range&: AssignmentOps, Out: getDestinationExprs().end());
511}
512
513OMPLastprivateClause *OMPLastprivateClause::Create(
514 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
515 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
516 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
517 OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,
518 SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {
519 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * VL.size()));
520 OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(
521 StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());
522 Clause->setVarRefs(VL);
523 Clause->setSourceExprs(SrcExprs);
524 Clause->setDestinationExprs(DstExprs);
525 Clause->setAssignmentOps(AssignmentOps);
526 Clause->setPreInitStmt(S: PreInit);
527 Clause->setPostUpdateExpr(PostUpdate);
528 return Clause;
529}
530
531OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
532 unsigned N) {
533 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * N));
534 return new (Mem) OMPLastprivateClause(N);
535}
536
537OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
538 SourceLocation StartLoc,
539 SourceLocation LParenLoc,
540 SourceLocation EndLoc,
541 ArrayRef<Expr *> VL) {
542 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
543 OMPSharedClause *Clause =
544 new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
545 Clause->setVarRefs(VL);
546 return Clause;
547}
548
549OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
550 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
551 return new (Mem) OMPSharedClause(N);
552}
553
554void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
555 assert(PL.size() == varlist_size() &&
556 "Number of privates is not the same as the preallocated buffer");
557 llvm::copy(Range&: PL, Out: varlist_end());
558}
559
560void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
561 assert(IL.size() == varlist_size() &&
562 "Number of inits is not the same as the preallocated buffer");
563 llvm::copy(Range&: IL, Out: getPrivates().end());
564}
565
566void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
567 assert(UL.size() == varlist_size() &&
568 "Number of updates is not the same as the preallocated buffer");
569 llvm::copy(Range&: UL, Out: getInits().end());
570}
571
572void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
573 assert(FL.size() == varlist_size() &&
574 "Number of final updates is not the same as the preallocated buffer");
575 llvm::copy(Range&: FL, Out: getUpdates().end());
576}
577
578void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {
579 assert(
580 UE.size() == varlist_size() + 1 &&
581 "Number of used expressions is not the same as the preallocated buffer");
582 llvm::copy(Range&: UE, Out: getFinals().end() + 2);
583}
584
585OMPLinearClause *OMPLinearClause::Create(
586 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
587 OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
588 SourceLocation ColonLoc, SourceLocation StepModifierLoc,
589 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
590 ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
591 Expr *PostUpdate) {
592 // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
593 // (Step and CalcStep), list of used expression + step.
594 void *Mem =
595 C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * VL.size() + 2 + VL.size() + 1));
596 OMPLinearClause *Clause =
597 new (Mem) OMPLinearClause(StartLoc, LParenLoc, Modifier, ModifierLoc,
598 ColonLoc, StepModifierLoc, EndLoc, VL.size());
599 Clause->setVarRefs(VL);
600 Clause->setPrivates(PL);
601 Clause->setInits(IL);
602 // Fill update and final expressions with zeroes, they are provided later,
603 // after the directive construction.
604 std::fill(first: Clause->getInits().end(), last: Clause->getInits().end() + VL.size(),
605 value: nullptr);
606 std::fill(first: Clause->getUpdates().end(), last: Clause->getUpdates().end() + VL.size(),
607 value: nullptr);
608 std::fill(first: Clause->getUsedExprs().begin(), last: Clause->getUsedExprs().end(),
609 value: nullptr);
610 Clause->setStep(Step);
611 Clause->setCalcStep(CalcStep);
612 Clause->setPreInitStmt(S: PreInit);
613 Clause->setPostUpdateExpr(PostUpdate);
614 return Clause;
615}
616
617OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
618 unsigned NumVars) {
619 // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
620 // (Step and CalcStep), list of used expression + step.
621 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * NumVars + 2 + NumVars +1));
622 return new (Mem) OMPLinearClause(NumVars);
623}
624
625OMPClause::child_range OMPLinearClause::used_children() {
626 // Range includes only non-nullptr elements.
627 return child_range(
628 reinterpret_cast<Stmt **>(getUsedExprs().begin()),
629 reinterpret_cast<Stmt **>(llvm::find(Range: getUsedExprs(), Val: nullptr)));
630}
631
632OMPAlignedClause *
633OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
634 SourceLocation LParenLoc, SourceLocation ColonLoc,
635 SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
636 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + 1));
637 OMPAlignedClause *Clause = new (Mem)
638 OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
639 Clause->setVarRefs(VL);
640 Clause->setAlignment(A);
641 return Clause;
642}
643
644OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
645 unsigned NumVars) {
646 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: NumVars + 1));
647 return new (Mem) OMPAlignedClause(NumVars);
648}
649
650OMPAlignClause *OMPAlignClause::Create(const ASTContext &C, Expr *A,
651 SourceLocation StartLoc,
652 SourceLocation LParenLoc,
653 SourceLocation EndLoc) {
654 return new (C) OMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
655}
656
657void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
658 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
659 "not the same as the "
660 "preallocated buffer");
661 llvm::copy(Range&: SrcExprs, Out: varlist_end());
662}
663
664void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
665 assert(DstExprs.size() == varlist_size() && "Number of destination "
666 "expressions is not the same as "
667 "the preallocated buffer");
668 llvm::copy(Range&: DstExprs, Out: getSourceExprs().end());
669}
670
671void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
672 assert(AssignmentOps.size() == varlist_size() &&
673 "Number of assignment expressions is not the same as the preallocated "
674 "buffer");
675 llvm::copy(Range&: AssignmentOps, Out: getDestinationExprs().end());
676}
677
678OMPCopyinClause *OMPCopyinClause::Create(
679 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
680 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
681 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
682 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 4 * VL.size()));
683 OMPCopyinClause *Clause =
684 new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
685 Clause->setVarRefs(VL);
686 Clause->setSourceExprs(SrcExprs);
687 Clause->setDestinationExprs(DstExprs);
688 Clause->setAssignmentOps(AssignmentOps);
689 return Clause;
690}
691
692OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
693 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 4 * N));
694 return new (Mem) OMPCopyinClause(N);
695}
696
697void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
698 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
699 "not the same as the "
700 "preallocated buffer");
701 llvm::copy(Range&: SrcExprs, Out: varlist_end());
702}
703
704void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
705 assert(DstExprs.size() == varlist_size() && "Number of destination "
706 "expressions is not the same as "
707 "the preallocated buffer");
708 llvm::copy(Range&: DstExprs, Out: getSourceExprs().end());
709}
710
711void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
712 assert(AssignmentOps.size() == varlist_size() &&
713 "Number of assignment expressions is not the same as the preallocated "
714 "buffer");
715 llvm::copy(Range&: AssignmentOps, Out: getDestinationExprs().end());
716}
717
718OMPCopyprivateClause *OMPCopyprivateClause::Create(
719 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
720 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
721 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
722 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 4 * VL.size()));
723 OMPCopyprivateClause *Clause =
724 new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
725 Clause->setVarRefs(VL);
726 Clause->setSourceExprs(SrcExprs);
727 Clause->setDestinationExprs(DstExprs);
728 Clause->setAssignmentOps(AssignmentOps);
729 return Clause;
730}
731
732OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
733 unsigned N) {
734 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 4 * N));
735 return new (Mem) OMPCopyprivateClause(N);
736}
737
738void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
739 assert(Privates.size() == varlist_size() &&
740 "Number of private copies is not the same as the preallocated buffer");
741 llvm::copy(Range&: Privates, Out: varlist_end());
742}
743
744void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
745 assert(
746 LHSExprs.size() == varlist_size() &&
747 "Number of LHS expressions is not the same as the preallocated buffer");
748 llvm::copy(Range&: LHSExprs, Out: getPrivates().end());
749}
750
751void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
752 assert(
753 RHSExprs.size() == varlist_size() &&
754 "Number of RHS expressions is not the same as the preallocated buffer");
755 llvm::copy(Range&: RHSExprs, Out: getLHSExprs().end());
756}
757
758void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
759 assert(ReductionOps.size() == varlist_size() && "Number of reduction "
760 "expressions is not the same "
761 "as the preallocated buffer");
762 llvm::copy(Range&: ReductionOps, Out: getRHSExprs().end());
763}
764
765void OMPReductionClause::setInscanCopyOps(ArrayRef<Expr *> Ops) {
766 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
767 assert(Ops.size() == varlist_size() && "Number of copy "
768 "expressions is not the same "
769 "as the preallocated buffer");
770 llvm::copy(Range&: Ops, Out: getReductionOps().end());
771}
772
773void OMPReductionClause::setInscanCopyArrayTemps(
774 ArrayRef<Expr *> CopyArrayTemps) {
775 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
776 assert(CopyArrayTemps.size() == varlist_size() &&
777 "Number of copy temp expressions is not the same as the preallocated "
778 "buffer");
779 llvm::copy(Range&: CopyArrayTemps, Out: getInscanCopyOps().end());
780}
781
782void OMPReductionClause::setInscanCopyArrayElems(
783 ArrayRef<Expr *> CopyArrayElems) {
784 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
785 assert(CopyArrayElems.size() == varlist_size() &&
786 "Number of copy temp expressions is not the same as the preallocated "
787 "buffer");
788 llvm::copy(Range&: CopyArrayElems, Out: getInscanCopyArrayTemps().end());
789}
790
791OMPReductionClause *OMPReductionClause::Create(
792 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
793 SourceLocation ModifierLoc, SourceLocation EndLoc, SourceLocation ColonLoc,
794 OpenMPReductionClauseModifier Modifier, ArrayRef<Expr *> VL,
795 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
796 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
797 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
798 ArrayRef<Expr *> CopyOps, ArrayRef<Expr *> CopyArrayTemps,
799 ArrayRef<Expr *> CopyArrayElems, Stmt *PreInit, Expr *PostUpdate,
800 ArrayRef<bool> IsPrivateVarReduction,
801 OpenMPOriginalSharingModifier OrignalSharingModifier) {
802 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *, bool>(
803 Counts: (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size(), Counts: VL.size()));
804 auto *Clause = new (Mem) OMPReductionClause(
805 StartLoc, LParenLoc, ModifierLoc, EndLoc, ColonLoc, Modifier,
806 OrignalSharingModifier, VL.size(), QualifierLoc, NameInfo);
807 Clause->setVarRefs(VL);
808 Clause->setPrivates(Privates);
809 Clause->setLHSExprs(LHSExprs);
810 Clause->setRHSExprs(RHSExprs);
811 Clause->setReductionOps(ReductionOps);
812 Clause->setPreInitStmt(S: PreInit);
813 Clause->setPostUpdateExpr(PostUpdate);
814 Clause->setPrivateVariableReductionFlags(IsPrivateVarReduction);
815 if (Modifier == OMPC_REDUCTION_inscan) {
816 Clause->setInscanCopyOps(CopyOps);
817 Clause->setInscanCopyArrayTemps(CopyArrayTemps);
818 Clause->setInscanCopyArrayElems(CopyArrayElems);
819 } else {
820 assert(CopyOps.empty() &&
821 "copy operations are expected in inscan reductions only.");
822 assert(CopyArrayTemps.empty() &&
823 "copy array temps are expected in inscan reductions only.");
824 assert(CopyArrayElems.empty() &&
825 "copy array temps are expected in inscan reductions only.");
826 }
827 return Clause;
828}
829
830OMPReductionClause *
831OMPReductionClause::CreateEmpty(const ASTContext &C, unsigned N,
832 OpenMPReductionClauseModifier Modifier) {
833 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *, bool>(
834 Counts: (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N, Counts: N));
835 auto *Clause = new (Mem) OMPReductionClause(N);
836 Clause->setModifier(Modifier);
837 return Clause;
838}
839
840void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
841 assert(Privates.size() == varlist_size() &&
842 "Number of private copies is not the same as the preallocated buffer");
843 llvm::copy(Range&: Privates, Out: varlist_end());
844}
845
846void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
847 assert(
848 LHSExprs.size() == varlist_size() &&
849 "Number of LHS expressions is not the same as the preallocated buffer");
850 llvm::copy(Range&: LHSExprs, Out: getPrivates().end());
851}
852
853void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
854 assert(
855 RHSExprs.size() == varlist_size() &&
856 "Number of RHS expressions is not the same as the preallocated buffer");
857 llvm::copy(Range&: RHSExprs, Out: getLHSExprs().end());
858}
859
860void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
861 assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
862 "expressions is not the same "
863 "as the preallocated buffer");
864 llvm::copy(Range&: ReductionOps, Out: getRHSExprs().end());
865}
866
867OMPTaskReductionClause *OMPTaskReductionClause::Create(
868 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
869 SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
870 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
871 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
872 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
873 Expr *PostUpdate) {
874 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * VL.size()));
875 OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
876 StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
877 Clause->setVarRefs(VL);
878 Clause->setPrivates(Privates);
879 Clause->setLHSExprs(LHSExprs);
880 Clause->setRHSExprs(RHSExprs);
881 Clause->setReductionOps(ReductionOps);
882 Clause->setPreInitStmt(S: PreInit);
883 Clause->setPostUpdateExpr(PostUpdate);
884 return Clause;
885}
886
887OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
888 unsigned N) {
889 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * N));
890 return new (Mem) OMPTaskReductionClause(N);
891}
892
893void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
894 assert(Privates.size() == varlist_size() &&
895 "Number of private copies is not the same as the preallocated buffer");
896 llvm::copy(Range&: Privates, Out: varlist_end());
897}
898
899void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
900 assert(
901 LHSExprs.size() == varlist_size() &&
902 "Number of LHS expressions is not the same as the preallocated buffer");
903 llvm::copy(Range&: LHSExprs, Out: getPrivates().end());
904}
905
906void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
907 assert(
908 RHSExprs.size() == varlist_size() &&
909 "Number of RHS expressions is not the same as the preallocated buffer");
910 llvm::copy(Range&: RHSExprs, Out: getLHSExprs().end());
911}
912
913void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
914 assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
915 "expressions is not the same "
916 "as the preallocated buffer");
917 llvm::copy(Range&: ReductionOps, Out: getRHSExprs().end());
918}
919
920void OMPInReductionClause::setTaskgroupDescriptors(
921 ArrayRef<Expr *> TaskgroupDescriptors) {
922 assert(TaskgroupDescriptors.size() == varlist_size() &&
923 "Number of in reduction descriptors is not the same as the "
924 "preallocated buffer");
925 llvm::copy(Range&: TaskgroupDescriptors, Out: getReductionOps().end());
926}
927
928OMPInReductionClause *OMPInReductionClause::Create(
929 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
930 SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
931 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
932 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
933 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
934 ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
935 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 6 * VL.size()));
936 OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
937 StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
938 Clause->setVarRefs(VL);
939 Clause->setPrivates(Privates);
940 Clause->setLHSExprs(LHSExprs);
941 Clause->setRHSExprs(RHSExprs);
942 Clause->setReductionOps(ReductionOps);
943 Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
944 Clause->setPreInitStmt(S: PreInit);
945 Clause->setPostUpdateExpr(PostUpdate);
946 return Clause;
947}
948
949OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
950 unsigned N) {
951 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 6 * N));
952 return new (Mem) OMPInReductionClause(N);
953}
954
955OMPSizesClause *OMPSizesClause::Create(const ASTContext &C,
956 SourceLocation StartLoc,
957 SourceLocation LParenLoc,
958 SourceLocation EndLoc,
959 ArrayRef<Expr *> Sizes) {
960 OMPSizesClause *Clause = CreateEmpty(C, NumSizes: Sizes.size());
961 Clause->setLocStart(StartLoc);
962 Clause->setLParenLoc(LParenLoc);
963 Clause->setLocEnd(EndLoc);
964 Clause->setSizesRefs(Sizes);
965 return Clause;
966}
967
968OMPSizesClause *OMPSizesClause::CreateEmpty(const ASTContext &C,
969 unsigned NumSizes) {
970 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: NumSizes));
971 return new (Mem) OMPSizesClause(NumSizes);
972}
973
974OMPPermutationClause *OMPPermutationClause::Create(const ASTContext &C,
975 SourceLocation StartLoc,
976 SourceLocation LParenLoc,
977 SourceLocation EndLoc,
978 ArrayRef<Expr *> Args) {
979 OMPPermutationClause *Clause = CreateEmpty(C, NumLoops: Args.size());
980 Clause->setLocStart(StartLoc);
981 Clause->setLParenLoc(LParenLoc);
982 Clause->setLocEnd(EndLoc);
983 Clause->setArgRefs(Args);
984 return Clause;
985}
986
987OMPPermutationClause *OMPPermutationClause::CreateEmpty(const ASTContext &C,
988 unsigned NumLoops) {
989 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: NumLoops));
990 return new (Mem) OMPPermutationClause(NumLoops);
991}
992
993OMPFullClause *OMPFullClause::Create(const ASTContext &C,
994 SourceLocation StartLoc,
995 SourceLocation EndLoc) {
996 OMPFullClause *Clause = CreateEmpty(C);
997 Clause->setLocStart(StartLoc);
998 Clause->setLocEnd(EndLoc);
999 return Clause;
1000}
1001
1002OMPFullClause *OMPFullClause::CreateEmpty(const ASTContext &C) {
1003 return new (C) OMPFullClause();
1004}
1005
1006OMPPartialClause *OMPPartialClause::Create(const ASTContext &C,
1007 SourceLocation StartLoc,
1008 SourceLocation LParenLoc,
1009 SourceLocation EndLoc,
1010 Expr *Factor) {
1011 OMPPartialClause *Clause = CreateEmpty(C);
1012 Clause->setLocStart(StartLoc);
1013 Clause->setLParenLoc(LParenLoc);
1014 Clause->setLocEnd(EndLoc);
1015 Clause->setFactor(Factor);
1016 return Clause;
1017}
1018
1019OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
1020 return new (C) OMPPartialClause();
1021}
1022
1023OMPAllocateClause *OMPAllocateClause::Create(
1024 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
1025 Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc,
1026 OpenMPAllocateClauseModifier Modifier1, SourceLocation Modifier1Loc,
1027 OpenMPAllocateClauseModifier Modifier2, SourceLocation Modifier2Loc,
1028 SourceLocation EndLoc, ArrayRef<Expr *> VL) {
1029
1030 // Allocate space for private variables and initializer expressions.
1031 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
1032 auto *Clause = new (Mem) OMPAllocateClause(
1033 StartLoc, LParenLoc, Allocator, Alignment, ColonLoc, Modifier1,
1034 Modifier1Loc, Modifier2, Modifier2Loc, EndLoc, VL.size());
1035
1036 Clause->setVarRefs(VL);
1037 return Clause;
1038}
1039
1040OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,
1041 unsigned N) {
1042 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1043 return new (Mem) OMPAllocateClause(N);
1044}
1045
1046OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
1047 SourceLocation StartLoc,
1048 SourceLocation LParenLoc,
1049 SourceLocation EndLoc,
1050 ArrayRef<Expr *> VL) {
1051 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + 1));
1052 OMPFlushClause *Clause =
1053 new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
1054 Clause->setVarRefs(VL);
1055 return Clause;
1056}
1057
1058OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
1059 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1060 return new (Mem) OMPFlushClause(N);
1061}
1062
1063OMPDepobjClause *OMPDepobjClause::Create(const ASTContext &C,
1064 SourceLocation StartLoc,
1065 SourceLocation LParenLoc,
1066 SourceLocation RParenLoc,
1067 Expr *Depobj) {
1068 auto *Clause = new (C) OMPDepobjClause(StartLoc, LParenLoc, RParenLoc);
1069 Clause->setDepobj(Depobj);
1070 return Clause;
1071}
1072
1073OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) {
1074 return new (C) OMPDepobjClause();
1075}
1076
1077OMPDependClause *
1078OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
1079 SourceLocation LParenLoc, SourceLocation EndLoc,
1080 DependDataTy Data, Expr *DepModifier,
1081 ArrayRef<Expr *> VL, unsigned NumLoops) {
1082 void *Mem = C.Allocate(
1083 Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + /*depend-modifier*/ 1 + NumLoops),
1084 Align: alignof(OMPDependClause));
1085 OMPDependClause *Clause = new (Mem)
1086 OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
1087 Clause->setDependencyKind(Data.DepKind);
1088 Clause->setDependencyLoc(Data.DepLoc);
1089 Clause->setColonLoc(Data.ColonLoc);
1090 Clause->setOmpAllMemoryLoc(Data.OmpAllMemoryLoc);
1091 Clause->setModifier(DepModifier);
1092 Clause->setVarRefs(VL);
1093 for (unsigned I = 0 ; I < NumLoops; ++I)
1094 Clause->setLoopData(NumLoop: I, Cnt: nullptr);
1095 return Clause;
1096}
1097
1098OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,
1099 unsigned NumLoops) {
1100 void *Mem =
1101 C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N + /*depend-modifier*/ 1 + NumLoops),
1102 Align: alignof(OMPDependClause));
1103 return new (Mem) OMPDependClause(N, NumLoops);
1104}
1105
1106void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
1107 assert((getDependencyKind() == OMPC_DEPEND_sink ||
1108 getDependencyKind() == OMPC_DEPEND_source) &&
1109 NumLoop < NumLoops &&
1110 "Expected sink or source depend + loop index must be less number of "
1111 "loops.");
1112 auto *It = std::next(x: getVarRefs().end(), n: NumLoop + 1);
1113 *It = Cnt;
1114}
1115
1116Expr *OMPDependClause::getLoopData(unsigned NumLoop) {
1117 assert((getDependencyKind() == OMPC_DEPEND_sink ||
1118 getDependencyKind() == OMPC_DEPEND_source) &&
1119 NumLoop < NumLoops &&
1120 "Expected sink or source depend + loop index must be less number of "
1121 "loops.");
1122 auto *It = std::next(x: getVarRefs().end(), n: NumLoop + 1);
1123 return *It;
1124}
1125
1126const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {
1127 assert((getDependencyKind() == OMPC_DEPEND_sink ||
1128 getDependencyKind() == OMPC_DEPEND_source) &&
1129 NumLoop < NumLoops &&
1130 "Expected sink or source depend + loop index must be less number of "
1131 "loops.");
1132 const auto *It = std::next(x: getVarRefs().end(), n: NumLoop + 1);
1133 return *It;
1134}
1135
1136void OMPDependClause::setModifier(Expr *DepModifier) {
1137 *getVarRefs().end() = DepModifier;
1138}
1139Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); }
1140
1141unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
1142 MappableExprComponentListsRef ComponentLists) {
1143 unsigned TotalNum = 0u;
1144 for (auto &C : ComponentLists)
1145 TotalNum += C.size();
1146 return TotalNum;
1147}
1148
1149unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
1150 ArrayRef<const ValueDecl *> Declarations) {
1151 llvm::SmallPtrSet<const ValueDecl *, 8> UniqueDecls;
1152 for (const ValueDecl *D : Declarations) {
1153 const ValueDecl *VD = D ? cast<ValueDecl>(Val: D->getCanonicalDecl()) : nullptr;
1154 UniqueDecls.insert(Ptr: VD);
1155 }
1156 return UniqueDecls.size();
1157}
1158
1159OMPMapClause *OMPMapClause::Create(
1160 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1161 ArrayRef<ValueDecl *> Declarations,
1162 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1163 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapModifiers,
1164 ArrayRef<SourceLocation> MapModifiersLoc,
1165 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
1166 OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
1167 OMPMappableExprListSizeTy Sizes;
1168 Sizes.NumVars = Vars.size();
1169 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1170 Sizes.NumComponentLists = ComponentLists.size();
1171 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1172
1173 // We need to allocate:
1174 // 2 x NumVars x Expr* - we have an original list expression and an associated
1175 // user-defined mapper for each clause list entry.
1176 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1177 // with each component list.
1178 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1179 // number of lists for each unique declaration and the size of each component
1180 // list.
1181 // NumComponents x MappableComponent - the total of all the components in all
1182 // the lists.
1183 void *Mem = C.Allocate(
1184 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1185 OMPClauseMappableExprCommon::MappableComponent>(
1186 Counts: 2 * Sizes.NumVars + 1, Counts: Sizes.NumUniqueDeclarations,
1187 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1188 Counts: Sizes.NumComponents));
1189 OMPMapClause *Clause = new (Mem)
1190 OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
1191 Type, TypeIsImplicit, TypeLoc, Locs, Sizes);
1192
1193 Clause->setVarRefs(Vars);
1194 Clause->setUDMapperRefs(UDMapperRefs);
1195 Clause->setIteratorModifier(IteratorModifier);
1196 Clause->setClauseInfo(Declarations, ComponentLists);
1197 Clause->setMapType(Type);
1198 Clause->setMapLoc(TypeLoc);
1199 return Clause;
1200}
1201
1202OMPMapClause *
1203OMPMapClause::CreateEmpty(const ASTContext &C,
1204 const OMPMappableExprListSizeTy &Sizes) {
1205 void *Mem = C.Allocate(
1206 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1207 OMPClauseMappableExprCommon::MappableComponent>(
1208 Counts: 2 * Sizes.NumVars + 1, Counts: Sizes.NumUniqueDeclarations,
1209 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1210 Counts: Sizes.NumComponents));
1211 OMPMapClause *Clause = new (Mem) OMPMapClause(Sizes);
1212 Clause->setIteratorModifier(nullptr);
1213 return Clause;
1214}
1215
1216OMPToClause *OMPToClause::Create(
1217 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1218 ArrayRef<ValueDecl *> Declarations,
1219 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1220 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
1221 ArrayRef<SourceLocation> MotionModifiersLoc,
1222 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1223 OMPMappableExprListSizeTy Sizes;
1224 Sizes.NumVars = Vars.size();
1225 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1226 Sizes.NumComponentLists = ComponentLists.size();
1227 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1228
1229 // We need to allocate:
1230 // 2 x NumVars x Expr* - we have an original list expression and an associated
1231 // user-defined mapper for each clause list entry.
1232 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1233 // with each component list.
1234 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1235 // number of lists for each unique declaration and the size of each component
1236 // list.
1237 // NumComponents x MappableComponent - the total of all the components in all
1238 // the lists.
1239 void *Mem = C.Allocate(
1240 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1241 OMPClauseMappableExprCommon::MappableComponent>(
1242 Counts: 2 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1243 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1244 Counts: Sizes.NumComponents));
1245
1246 auto *Clause = new (Mem) OMPToClause(MotionModifiers, MotionModifiersLoc,
1247 UDMQualifierLoc, MapperId, Locs, Sizes);
1248
1249 Clause->setVarRefs(Vars);
1250 Clause->setUDMapperRefs(UDMapperRefs);
1251 Clause->setClauseInfo(Declarations, ComponentLists);
1252 return Clause;
1253}
1254
1255OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C,
1256 const OMPMappableExprListSizeTy &Sizes) {
1257 void *Mem = C.Allocate(
1258 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1259 OMPClauseMappableExprCommon::MappableComponent>(
1260 Counts: 2 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1261 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1262 Counts: Sizes.NumComponents));
1263 return new (Mem) OMPToClause(Sizes);
1264}
1265
1266OMPFromClause *OMPFromClause::Create(
1267 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1268 ArrayRef<ValueDecl *> Declarations,
1269 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1270 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
1271 ArrayRef<SourceLocation> MotionModifiersLoc,
1272 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1273 OMPMappableExprListSizeTy Sizes;
1274 Sizes.NumVars = Vars.size();
1275 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1276 Sizes.NumComponentLists = ComponentLists.size();
1277 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1278
1279 // We need to allocate:
1280 // 2 x NumVars x Expr* - we have an original list expression and an associated
1281 // user-defined mapper for each clause list entry.
1282 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1283 // with each component list.
1284 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1285 // number of lists for each unique declaration and the size of each component
1286 // list.
1287 // NumComponents x MappableComponent - the total of all the components in all
1288 // the lists.
1289 void *Mem = C.Allocate(
1290 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1291 OMPClauseMappableExprCommon::MappableComponent>(
1292 Counts: 2 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1293 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1294 Counts: Sizes.NumComponents));
1295
1296 auto *Clause =
1297 new (Mem) OMPFromClause(MotionModifiers, MotionModifiersLoc,
1298 UDMQualifierLoc, MapperId, Locs, Sizes);
1299
1300 Clause->setVarRefs(Vars);
1301 Clause->setUDMapperRefs(UDMapperRefs);
1302 Clause->setClauseInfo(Declarations, ComponentLists);
1303 return Clause;
1304}
1305
1306OMPFromClause *
1307OMPFromClause::CreateEmpty(const ASTContext &C,
1308 const OMPMappableExprListSizeTy &Sizes) {
1309 void *Mem = C.Allocate(
1310 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1311 OMPClauseMappableExprCommon::MappableComponent>(
1312 Counts: 2 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1313 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1314 Counts: Sizes.NumComponents));
1315 return new (Mem) OMPFromClause(Sizes);
1316}
1317
1318void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
1319 assert(VL.size() == varlist_size() &&
1320 "Number of private copies is not the same as the preallocated buffer");
1321 llvm::copy(Range&: VL, Out: varlist_end());
1322}
1323
1324void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
1325 assert(VL.size() == varlist_size() &&
1326 "Number of inits is not the same as the preallocated buffer");
1327 llvm::copy(Range&: VL, Out: getPrivateCopies().end());
1328}
1329
1330OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
1331 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1332 ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
1333 ArrayRef<ValueDecl *> Declarations,
1334 MappableExprComponentListsRef ComponentLists) {
1335 OMPMappableExprListSizeTy Sizes;
1336 Sizes.NumVars = Vars.size();
1337 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1338 Sizes.NumComponentLists = ComponentLists.size();
1339 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1340
1341 // We need to allocate:
1342 // NumVars x Expr* - we have an original list expression for each clause
1343 // list entry.
1344 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1345 // with each component list.
1346 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1347 // number of lists for each unique declaration and the size of each component
1348 // list.
1349 // NumComponents x MappableComponent - the total of all the components in all
1350 // the lists.
1351 void *Mem = C.Allocate(
1352 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1353 OMPClauseMappableExprCommon::MappableComponent>(
1354 Counts: 3 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1355 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1356 Counts: Sizes.NumComponents));
1357
1358 OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
1359
1360 Clause->setVarRefs(Vars);
1361 Clause->setPrivateCopies(PrivateVars);
1362 Clause->setInits(Inits);
1363 Clause->setClauseInfo(Declarations, ComponentLists);
1364 return Clause;
1365}
1366
1367OMPUseDevicePtrClause *
1368OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C,
1369 const OMPMappableExprListSizeTy &Sizes) {
1370 void *Mem = C.Allocate(
1371 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1372 OMPClauseMappableExprCommon::MappableComponent>(
1373 Counts: 3 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1374 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1375 Counts: Sizes.NumComponents));
1376 return new (Mem) OMPUseDevicePtrClause(Sizes);
1377}
1378
1379OMPUseDeviceAddrClause *
1380OMPUseDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1381 ArrayRef<Expr *> Vars,
1382 ArrayRef<ValueDecl *> Declarations,
1383 MappableExprComponentListsRef ComponentLists) {
1384 OMPMappableExprListSizeTy Sizes;
1385 Sizes.NumVars = Vars.size();
1386 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1387 Sizes.NumComponentLists = ComponentLists.size();
1388 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1389
1390 // We need to allocate:
1391 // 3 x NumVars x Expr* - we have an original list expression for each clause
1392 // list entry and an equal number of private copies and inits.
1393 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1394 // with each component list.
1395 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1396 // number of lists for each unique declaration and the size of each component
1397 // list.
1398 // NumComponents x MappableComponent - the total of all the components in all
1399 // the lists.
1400 void *Mem = C.Allocate(
1401 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1402 OMPClauseMappableExprCommon::MappableComponent>(
1403 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1404 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1405 Counts: Sizes.NumComponents));
1406
1407 auto *Clause = new (Mem) OMPUseDeviceAddrClause(Locs, Sizes);
1408
1409 Clause->setVarRefs(Vars);
1410 Clause->setClauseInfo(Declarations, ComponentLists);
1411 return Clause;
1412}
1413
1414OMPUseDeviceAddrClause *
1415OMPUseDeviceAddrClause::CreateEmpty(const ASTContext &C,
1416 const OMPMappableExprListSizeTy &Sizes) {
1417 void *Mem = C.Allocate(
1418 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1419 OMPClauseMappableExprCommon::MappableComponent>(
1420 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1421 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1422 Counts: Sizes.NumComponents));
1423 return new (Mem) OMPUseDeviceAddrClause(Sizes);
1424}
1425
1426OMPIsDevicePtrClause *
1427OMPIsDevicePtrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1428 ArrayRef<Expr *> Vars,
1429 ArrayRef<ValueDecl *> Declarations,
1430 MappableExprComponentListsRef ComponentLists) {
1431 OMPMappableExprListSizeTy Sizes;
1432 Sizes.NumVars = Vars.size();
1433 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1434 Sizes.NumComponentLists = ComponentLists.size();
1435 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1436
1437 // We need to allocate:
1438 // NumVars x Expr* - we have an original list expression for each clause list
1439 // entry.
1440 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1441 // with each component list.
1442 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1443 // number of lists for each unique declaration and the size of each component
1444 // list.
1445 // NumComponents x MappableComponent - the total of all the components in all
1446 // the lists.
1447 void *Mem = C.Allocate(
1448 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1449 OMPClauseMappableExprCommon::MappableComponent>(
1450 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1451 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1452 Counts: Sizes.NumComponents));
1453
1454 OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);
1455
1456 Clause->setVarRefs(Vars);
1457 Clause->setClauseInfo(Declarations, ComponentLists);
1458 return Clause;
1459}
1460
1461OMPIsDevicePtrClause *
1462OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,
1463 const OMPMappableExprListSizeTy &Sizes) {
1464 void *Mem = C.Allocate(
1465 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1466 OMPClauseMappableExprCommon::MappableComponent>(
1467 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1468 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1469 Counts: Sizes.NumComponents));
1470 return new (Mem) OMPIsDevicePtrClause(Sizes);
1471}
1472
1473OMPHasDeviceAddrClause *
1474OMPHasDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1475 ArrayRef<Expr *> Vars,
1476 ArrayRef<ValueDecl *> Declarations,
1477 MappableExprComponentListsRef ComponentLists) {
1478 OMPMappableExprListSizeTy Sizes;
1479 Sizes.NumVars = Vars.size();
1480 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1481 Sizes.NumComponentLists = ComponentLists.size();
1482 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1483
1484 // We need to allocate:
1485 // NumVars x Expr* - we have an original list expression for each clause list
1486 // entry.
1487 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1488 // with each component list.
1489 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1490 // number of lists for each unique declaration and the size of each component
1491 // list.
1492 // NumComponents x MappableComponent - the total of all the components in all
1493 // the lists.
1494 void *Mem = C.Allocate(
1495 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1496 OMPClauseMappableExprCommon::MappableComponent>(
1497 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1498 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1499 Counts: Sizes.NumComponents));
1500
1501 auto *Clause = new (Mem) OMPHasDeviceAddrClause(Locs, Sizes);
1502
1503 Clause->setVarRefs(Vars);
1504 Clause->setClauseInfo(Declarations, ComponentLists);
1505 return Clause;
1506}
1507
1508OMPHasDeviceAddrClause *
1509OMPHasDeviceAddrClause::CreateEmpty(const ASTContext &C,
1510 const OMPMappableExprListSizeTy &Sizes) {
1511 void *Mem = C.Allocate(
1512 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1513 OMPClauseMappableExprCommon::MappableComponent>(
1514 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1515 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1516 Counts: Sizes.NumComponents));
1517 return new (Mem) OMPHasDeviceAddrClause(Sizes);
1518}
1519
1520OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
1521 SourceLocation StartLoc,
1522 SourceLocation LParenLoc,
1523 SourceLocation EndLoc,
1524 ArrayRef<Expr *> VL) {
1525 // Allocate space for nontemporal variables + private references.
1526 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * VL.size()));
1527 auto *Clause =
1528 new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
1529 Clause->setVarRefs(VL);
1530 return Clause;
1531}
1532
1533OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,
1534 unsigned N) {
1535 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * N));
1536 return new (Mem) OMPNontemporalClause(N);
1537}
1538
1539void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {
1540 assert(VL.size() == varlist_size() && "Number of private references is not "
1541 "the same as the preallocated buffer");
1542 llvm::copy(Range&: VL, Out: varlist_end());
1543}
1544
1545OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C,
1546 SourceLocation StartLoc,
1547 SourceLocation LParenLoc,
1548 SourceLocation EndLoc,
1549 ArrayRef<Expr *> VL) {
1550 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
1551 auto *Clause =
1552 new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1553 Clause->setVarRefs(VL);
1554 return Clause;
1555}
1556
1557OMPInclusiveClause *OMPInclusiveClause::CreateEmpty(const ASTContext &C,
1558 unsigned N) {
1559 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1560 return new (Mem) OMPInclusiveClause(N);
1561}
1562
1563OMPExclusiveClause *OMPExclusiveClause::Create(const ASTContext &C,
1564 SourceLocation StartLoc,
1565 SourceLocation LParenLoc,
1566 SourceLocation EndLoc,
1567 ArrayRef<Expr *> VL) {
1568 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
1569 auto *Clause =
1570 new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1571 Clause->setVarRefs(VL);
1572 return Clause;
1573}
1574
1575OMPExclusiveClause *OMPExclusiveClause::CreateEmpty(const ASTContext &C,
1576 unsigned N) {
1577 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1578 return new (Mem) OMPExclusiveClause(N);
1579}
1580
1581void OMPUsesAllocatorsClause::setAllocatorsData(
1582 ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
1583 assert(Data.size() == NumOfAllocators &&
1584 "Size of allocators data is not the same as the preallocated buffer.");
1585 for (unsigned I = 0, E = Data.size(); I < E; ++I) {
1586 const OMPUsesAllocatorsClause::Data &D = Data[I];
1587 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1588 static_cast<int>(ExprOffsets::Allocator)] =
1589 D.Allocator;
1590 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1591 static_cast<int>(
1592 ExprOffsets::AllocatorTraits)] =
1593 D.AllocatorTraits;
1594 getTrailingObjects<
1595 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1596 static_cast<int>(ParenLocsOffsets::LParen)] =
1597 D.LParenLoc;
1598 getTrailingObjects<
1599 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1600 static_cast<int>(ParenLocsOffsets::RParen)] =
1601 D.RParenLoc;
1602 }
1603}
1604
1605OMPUsesAllocatorsClause::Data
1606OMPUsesAllocatorsClause::getAllocatorData(unsigned I) const {
1607 OMPUsesAllocatorsClause::Data Data;
1608 Data.Allocator =
1609 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1610 static_cast<int>(ExprOffsets::Allocator)];
1611 Data.AllocatorTraits =
1612 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1613 static_cast<int>(
1614 ExprOffsets::AllocatorTraits)];
1615 Data.LParenLoc = getTrailingObjects<
1616 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1617 static_cast<int>(ParenLocsOffsets::LParen)];
1618 Data.RParenLoc = getTrailingObjects<
1619 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1620 static_cast<int>(ParenLocsOffsets::RParen)];
1621 return Data;
1622}
1623
1624OMPUsesAllocatorsClause *
1625OMPUsesAllocatorsClause::Create(const ASTContext &C, SourceLocation StartLoc,
1626 SourceLocation LParenLoc, SourceLocation EndLoc,
1627 ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
1628 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *, SourceLocation>(
1629 Counts: static_cast<int>(ExprOffsets::Total) * Data.size(),
1630 Counts: static_cast<int>(ParenLocsOffsets::Total) * Data.size()));
1631 auto *Clause = new (Mem)
1632 OMPUsesAllocatorsClause(StartLoc, LParenLoc, EndLoc, Data.size());
1633 Clause->setAllocatorsData(Data);
1634 return Clause;
1635}
1636
1637OMPUsesAllocatorsClause *
1638OMPUsesAllocatorsClause::CreateEmpty(const ASTContext &C, unsigned N) {
1639 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *, SourceLocation>(
1640 Counts: static_cast<int>(ExprOffsets::Total) * N,
1641 Counts: static_cast<int>(ParenLocsOffsets::Total) * N));
1642 return new (Mem) OMPUsesAllocatorsClause(N);
1643}
1644
1645OMPAffinityClause *
1646OMPAffinityClause::Create(const ASTContext &C, SourceLocation StartLoc,
1647 SourceLocation LParenLoc, SourceLocation ColonLoc,
1648 SourceLocation EndLoc, Expr *Modifier,
1649 ArrayRef<Expr *> Locators) {
1650 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: Locators.size() + 1));
1651 auto *Clause = new (Mem)
1652 OMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, Locators.size());
1653 Clause->setModifier(Modifier);
1654 Clause->setVarRefs(Locators);
1655 return Clause;
1656}
1657
1658OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C,
1659 unsigned N) {
1660 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N + 1));
1661 return new (Mem) OMPAffinityClause(N);
1662}
1663
1664OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar,
1665 OMPInteropInfo &InteropInfo,
1666 SourceLocation StartLoc,
1667 SourceLocation LParenLoc,
1668 SourceLocation VarLoc,
1669 SourceLocation EndLoc) {
1670
1671 void *Mem =
1672 C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: InteropInfo.PreferTypes.size() + 1));
1673 auto *Clause = new (Mem) OMPInitClause(
1674 InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc, LParenLoc,
1675 VarLoc, EndLoc, InteropInfo.PreferTypes.size() + 1);
1676 Clause->setInteropVar(InteropVar);
1677 llvm::copy(Range&: InteropInfo.PreferTypes, Out: Clause->getTrailingObjects() + 1);
1678 return Clause;
1679}
1680
1681OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {
1682 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1683 return new (Mem) OMPInitClause(N);
1684}
1685
1686OMPBindClause *
1687OMPBindClause::Create(const ASTContext &C, OpenMPBindClauseKind K,
1688 SourceLocation KLoc, SourceLocation StartLoc,
1689 SourceLocation LParenLoc, SourceLocation EndLoc) {
1690 return new (C) OMPBindClause(K, KLoc, StartLoc, LParenLoc, EndLoc);
1691}
1692
1693OMPBindClause *OMPBindClause::CreateEmpty(const ASTContext &C) {
1694 return new (C) OMPBindClause();
1695}
1696
1697OMPDoacrossClause *
1698OMPDoacrossClause::Create(const ASTContext &C, SourceLocation StartLoc,
1699 SourceLocation LParenLoc, SourceLocation EndLoc,
1700 OpenMPDoacrossClauseModifier DepType,
1701 SourceLocation DepLoc, SourceLocation ColonLoc,
1702 ArrayRef<Expr *> VL, unsigned NumLoops) {
1703 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + NumLoops),
1704 Align: alignof(OMPDoacrossClause));
1705 OMPDoacrossClause *Clause = new (Mem)
1706 OMPDoacrossClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
1707 Clause->setDependenceType(DepType);
1708 Clause->setDependenceLoc(DepLoc);
1709 Clause->setColonLoc(ColonLoc);
1710 Clause->setVarRefs(VL);
1711 for (unsigned I = 0; I < NumLoops; ++I)
1712 Clause->setLoopData(NumLoop: I, Cnt: nullptr);
1713 return Clause;
1714}
1715
1716OMPDoacrossClause *OMPDoacrossClause::CreateEmpty(const ASTContext &C,
1717 unsigned N,
1718 unsigned NumLoops) {
1719 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N + NumLoops),
1720 Align: alignof(OMPDoacrossClause));
1721 return new (Mem) OMPDoacrossClause(N, NumLoops);
1722}
1723
1724void OMPDoacrossClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
1725 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1726 auto *It = std::next(x: getVarRefs().end(), n: NumLoop);
1727 *It = Cnt;
1728}
1729
1730Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) {
1731 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1732 auto *It = std::next(x: getVarRefs().end(), n: NumLoop);
1733 return *It;
1734}
1735
1736const Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) const {
1737 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1738 const auto *It = std::next(x: getVarRefs().end(), n: NumLoop);
1739 return *It;
1740}
1741
1742OMPAbsentClause *OMPAbsentClause::Create(const ASTContext &C,
1743 ArrayRef<OpenMPDirectiveKind> DKVec,
1744 SourceLocation Loc,
1745 SourceLocation LLoc,
1746 SourceLocation RLoc) {
1747 void *Mem = C.Allocate(Size: totalSizeToAlloc<OpenMPDirectiveKind>(Counts: DKVec.size()),
1748 Align: alignof(OMPAbsentClause));
1749 auto *AC = new (Mem) OMPAbsentClause(Loc, LLoc, RLoc, DKVec.size());
1750 AC->setDirectiveKinds(DKVec);
1751 return AC;
1752}
1753
1754OMPAbsentClause *OMPAbsentClause::CreateEmpty(const ASTContext &C, unsigned K) {
1755 void *Mem = C.Allocate(Size: totalSizeToAlloc<OpenMPDirectiveKind>(Counts: K),
1756 Align: alignof(OMPAbsentClause));
1757 return new (Mem) OMPAbsentClause(K);
1758}
1759
1760OMPContainsClause *OMPContainsClause::Create(
1761 const ASTContext &C, ArrayRef<OpenMPDirectiveKind> DKVec,
1762 SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc) {
1763 void *Mem = C.Allocate(Size: totalSizeToAlloc<OpenMPDirectiveKind>(Counts: DKVec.size()),
1764 Align: alignof(OMPContainsClause));
1765 auto *CC = new (Mem) OMPContainsClause(Loc, LLoc, RLoc, DKVec.size());
1766 CC->setDirectiveKinds(DKVec);
1767 return CC;
1768}
1769
1770OMPContainsClause *OMPContainsClause::CreateEmpty(const ASTContext &C,
1771 unsigned K) {
1772 void *Mem = C.Allocate(Size: totalSizeToAlloc<OpenMPDirectiveKind>(Counts: K),
1773 Align: alignof(OMPContainsClause));
1774 return new (Mem) OMPContainsClause(K);
1775}
1776
1777OMPNumTeamsClause *OMPNumTeamsClause::Create(
1778 const ASTContext &C, OpenMPDirectiveKind CaptureRegion,
1779 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
1780 ArrayRef<Expr *> VL, Stmt *PreInit) {
1781 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
1782 OMPNumTeamsClause *Clause =
1783 new (Mem) OMPNumTeamsClause(C, StartLoc, LParenLoc, EndLoc, VL.size());
1784 Clause->setVarRefs(VL);
1785 Clause->setPreInitStmt(S: PreInit, ThisRegion: CaptureRegion);
1786 return Clause;
1787}
1788
1789OMPNumTeamsClause *OMPNumTeamsClause::CreateEmpty(const ASTContext &C,
1790 unsigned N) {
1791 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1792 return new (Mem) OMPNumTeamsClause(N);
1793}
1794
1795OMPThreadLimitClause *OMPThreadLimitClause::Create(
1796 const ASTContext &C, OpenMPDirectiveKind CaptureRegion,
1797 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
1798 ArrayRef<Expr *> VL, Stmt *PreInit) {
1799 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
1800 OMPThreadLimitClause *Clause =
1801 new (Mem) OMPThreadLimitClause(C, StartLoc, LParenLoc, EndLoc, VL.size());
1802 Clause->setVarRefs(VL);
1803 Clause->setPreInitStmt(S: PreInit, ThisRegion: CaptureRegion);
1804 return Clause;
1805}
1806
1807OMPThreadLimitClause *OMPThreadLimitClause::CreateEmpty(const ASTContext &C,
1808 unsigned N) {
1809 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1810 return new (Mem) OMPThreadLimitClause(N);
1811}
1812
1813//===----------------------------------------------------------------------===//
1814// OpenMP clauses printing methods
1815//===----------------------------------------------------------------------===//
1816
1817void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
1818 OS << "if(";
1819 if (Node->getNameModifier() != OMPD_unknown)
1820 OS << getOpenMPDirectiveName(D: Node->getNameModifier(), Ver: Version) << ": ";
1821 Node->getCondition()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1822 OS << ")";
1823}
1824
1825void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
1826 OS << "final(";
1827 Node->getCondition()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1828 OS << ")";
1829}
1830
1831void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
1832 OS << "num_threads(";
1833 OpenMPNumThreadsClauseModifier Modifier = Node->getModifier();
1834 if (Modifier != OMPC_NUMTHREADS_unknown) {
1835 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
1836 << ": ";
1837 }
1838 Node->getNumThreads()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1839 OS << ")";
1840}
1841
1842void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
1843 OS << "align(";
1844 Node->getAlignment()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1845 OS << ")";
1846}
1847
1848void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
1849 OS << "safelen(";
1850 Node->getSafelen()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1851 OS << ")";
1852}
1853
1854void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
1855 OS << "simdlen(";
1856 Node->getSimdlen()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1857 OS << ")";
1858}
1859
1860void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {
1861 OS << "sizes(";
1862 bool First = true;
1863 for (auto *Size : Node->getSizesRefs()) {
1864 if (!First)
1865 OS << ", ";
1866 Size->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1867 First = false;
1868 }
1869 OS << ")";
1870}
1871
1872void OMPClausePrinter::VisitOMPPermutationClause(OMPPermutationClause *Node) {
1873 OS << "permutation(";
1874 llvm::interleaveComma(c: Node->getArgsRefs(), os&: OS, each_fn: [&](const Expr *E) {
1875 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1876 });
1877 OS << ")";
1878}
1879
1880void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }
1881
1882void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
1883 OS << "partial";
1884
1885 if (Expr *Factor = Node->getFactor()) {
1886 OS << '(';
1887 Factor->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1888 OS << ')';
1889 }
1890}
1891
1892void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
1893 OS << "allocator(";
1894 Node->getAllocator()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1895 OS << ")";
1896}
1897
1898void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
1899 OS << "collapse(";
1900 Node->getNumForLoops()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1901 OS << ")";
1902}
1903
1904void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
1905 OS << "detach(";
1906 Node->getEventHandler()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1907 OS << ")";
1908}
1909
1910void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
1911 OS << "default("
1912 << getOpenMPSimpleClauseTypeName(Kind: OMPC_default,
1913 Type: unsigned(Node->getDefaultKind()))
1914 << ")";
1915}
1916
1917void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
1918 OS << "proc_bind("
1919 << getOpenMPSimpleClauseTypeName(Kind: OMPC_proc_bind,
1920 Type: unsigned(Node->getProcBindKind()))
1921 << ")";
1922}
1923
1924void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
1925 OS << "unified_address";
1926}
1927
1928void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
1929 OMPUnifiedSharedMemoryClause *) {
1930 OS << "unified_shared_memory";
1931}
1932
1933void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
1934 OS << "reverse_offload";
1935}
1936
1937void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
1938 OMPDynamicAllocatorsClause *) {
1939 OS << "dynamic_allocators";
1940}
1941
1942void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
1943 OMPAtomicDefaultMemOrderClause *Node) {
1944 OS << "atomic_default_mem_order("
1945 << getOpenMPSimpleClauseTypeName(Kind: OMPC_atomic_default_mem_order,
1946 Type: Node->getAtomicDefaultMemOrderKind())
1947 << ")";
1948}
1949
1950void OMPClausePrinter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {
1951 OS << "self_maps";
1952}
1953
1954void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
1955 OS << "at(" << getOpenMPSimpleClauseTypeName(Kind: OMPC_at, Type: Node->getAtKind())
1956 << ")";
1957}
1958
1959void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
1960 OS << "severity("
1961 << getOpenMPSimpleClauseTypeName(Kind: OMPC_severity, Type: Node->getSeverityKind())
1962 << ")";
1963}
1964
1965void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
1966 OS << "message(\""
1967 << cast<StringLiteral>(Val: Node->getMessageString())->getString() << "\")";
1968}
1969
1970void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
1971 OS << "schedule(";
1972 if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1973 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule,
1974 Type: Node->getFirstScheduleModifier());
1975 if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1976 OS << ", ";
1977 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule,
1978 Type: Node->getSecondScheduleModifier());
1979 }
1980 OS << ": ";
1981 }
1982 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule, Type: Node->getScheduleKind());
1983 if (auto *E = Node->getChunkSize()) {
1984 OS << ", ";
1985 E->printPretty(OS, Helper: nullptr, Policy);
1986 }
1987 OS << ")";
1988}
1989
1990void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
1991 OS << "ordered";
1992 if (auto *Num = Node->getNumForLoops()) {
1993 OS << "(";
1994 Num->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1995 OS << ")";
1996 }
1997}
1998
1999void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
2000 OS << "nowait";
2001}
2002
2003void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
2004 OS << "untied";
2005}
2006
2007void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
2008 OS << "nogroup";
2009}
2010
2011void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
2012 OS << "mergeable";
2013}
2014
2015void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
2016
2017void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
2018
2019void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
2020 OS << "update";
2021 if (Node->isExtended()) {
2022 OS << "(";
2023 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(),
2024 Type: Node->getDependencyKind());
2025 OS << ")";
2026 }
2027}
2028
2029void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
2030 OS << "capture";
2031}
2032
2033void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
2034 OS << "compare";
2035}
2036
2037void OMPClausePrinter::VisitOMPFailClause(OMPFailClause *Node) {
2038 OS << "fail";
2039 if (Node) {
2040 OS << "(";
2041 OS << getOpenMPSimpleClauseTypeName(
2042 Kind: Node->getClauseKind(), Type: static_cast<int>(Node->getFailParameter()));
2043 OS << ")";
2044 }
2045}
2046
2047void OMPClausePrinter::VisitOMPAbsentClause(OMPAbsentClause *Node) {
2048 OS << "absent(";
2049 bool First = true;
2050 for (auto &D : Node->getDirectiveKinds()) {
2051 if (!First)
2052 OS << ", ";
2053 OS << getOpenMPDirectiveName(D, Ver: Version);
2054 First = false;
2055 }
2056 OS << ")";
2057}
2058
2059void OMPClausePrinter::VisitOMPHoldsClause(OMPHoldsClause *Node) {
2060 OS << "holds(";
2061 Node->getExpr()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2062 OS << ")";
2063}
2064
2065void OMPClausePrinter::VisitOMPContainsClause(OMPContainsClause *Node) {
2066 OS << "contains(";
2067 bool First = true;
2068 for (auto &D : Node->getDirectiveKinds()) {
2069 if (!First)
2070 OS << ", ";
2071 OS << getOpenMPDirectiveName(D, Ver: Version);
2072 First = false;
2073 }
2074 OS << ")";
2075}
2076
2077void OMPClausePrinter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {
2078 OS << "no_openmp";
2079}
2080
2081void OMPClausePrinter::VisitOMPNoOpenMPRoutinesClause(
2082 OMPNoOpenMPRoutinesClause *) {
2083 OS << "no_openmp_routines";
2084}
2085
2086void OMPClausePrinter::VisitOMPNoOpenMPConstructsClause(
2087 OMPNoOpenMPConstructsClause *) {
2088 OS << "no_openmp_constructs";
2089}
2090
2091void OMPClausePrinter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {
2092 OS << "no_parallelism";
2093}
2094
2095void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
2096 OS << "seq_cst";
2097}
2098
2099void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
2100 OS << "acq_rel";
2101}
2102
2103void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
2104 OS << "acquire";
2105}
2106
2107void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
2108 OS << "release";
2109}
2110
2111void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
2112 OS << "relaxed";
2113}
2114
2115void OMPClausePrinter::VisitOMPWeakClause(OMPWeakClause *) { OS << "weak"; }
2116
2117void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
2118 OS << "threads";
2119}
2120
2121void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
2122
2123void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
2124 OS << "device(";
2125 OpenMPDeviceClauseModifier Modifier = Node->getModifier();
2126 if (Modifier != OMPC_DEVICE_unknown) {
2127 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2128 << ": ";
2129 }
2130 Node->getDevice()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2131 OS << ")";
2132}
2133
2134void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
2135 if (!Node->varlist_empty()) {
2136 OS << "num_teams";
2137 VisitOMPClauseList(Node, StartSym: '(');
2138 OS << ")";
2139 }
2140}
2141
2142void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
2143 if (!Node->varlist_empty()) {
2144 OS << "thread_limit";
2145 VisitOMPClauseList(Node, StartSym: '(');
2146 OS << ")";
2147 }
2148}
2149
2150void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
2151 OS << "priority(";
2152 Node->getPriority()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2153 OS << ")";
2154}
2155
2156void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
2157 OS << "grainsize(";
2158 OpenMPGrainsizeClauseModifier Modifier = Node->getModifier();
2159 if (Modifier != OMPC_GRAINSIZE_unknown) {
2160 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2161 << ": ";
2162 }
2163 Node->getGrainsize()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2164 OS << ")";
2165}
2166
2167void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
2168 OS << "num_tasks(";
2169 OpenMPNumTasksClauseModifier Modifier = Node->getModifier();
2170 if (Modifier != OMPC_NUMTASKS_unknown) {
2171 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2172 << ": ";
2173 }
2174 Node->getNumTasks()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2175 OS << ")";
2176}
2177
2178void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
2179 OS << "hint(";
2180 Node->getHint()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2181 OS << ")";
2182}
2183
2184void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
2185 OS << "init(";
2186 bool First = true;
2187 for (const Expr *E : Node->prefs()) {
2188 if (First)
2189 OS << "prefer_type(";
2190 else
2191 OS << ",";
2192 E->printPretty(OS, Helper: nullptr, Policy);
2193 First = false;
2194 }
2195 if (!First)
2196 OS << "), ";
2197 if (Node->getIsTarget())
2198 OS << "target";
2199 if (Node->getIsTargetSync()) {
2200 if (Node->getIsTarget())
2201 OS << ", ";
2202 OS << "targetsync";
2203 }
2204 OS << " : ";
2205 Node->getInteropVar()->printPretty(OS, Helper: nullptr, Policy);
2206 OS << ")";
2207}
2208
2209void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
2210 OS << "use(";
2211 Node->getInteropVar()->printPretty(OS, Helper: nullptr, Policy);
2212 OS << ")";
2213}
2214
2215void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {
2216 OS << "destroy";
2217 if (Expr *E = Node->getInteropVar()) {
2218 OS << "(";
2219 E->printPretty(OS, Helper: nullptr, Policy);
2220 OS << ")";
2221 }
2222}
2223
2224void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {
2225 OS << "novariants";
2226 if (Expr *E = Node->getCondition()) {
2227 OS << "(";
2228 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2229 OS << ")";
2230 }
2231}
2232
2233void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {
2234 OS << "nocontext";
2235 if (Expr *E = Node->getCondition()) {
2236 OS << "(";
2237 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2238 OS << ")";
2239 }
2240}
2241
2242template<typename T>
2243void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
2244 for (typename T::varlist_iterator I = Node->varlist_begin(),
2245 E = Node->varlist_end();
2246 I != E; ++I) {
2247 assert(*I && "Expected non-null Stmt");
2248 OS << (I == Node->varlist_begin() ? StartSym : ',');
2249 if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
2250 if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
2251 DRE->printPretty(OS, nullptr, Policy, 0);
2252 else
2253 DRE->getDecl()->printQualifiedName(OS);
2254 } else
2255 (*I)->printPretty(OS, nullptr, Policy, 0);
2256 }
2257}
2258
2259void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
2260 if (Node->varlist_empty())
2261 return;
2262
2263 Expr *FirstModifier = nullptr;
2264 Expr *SecondModifier = nullptr;
2265 auto FirstAllocMod = Node->getFirstAllocateModifier();
2266 auto SecondAllocMod = Node->getSecondAllocateModifier();
2267 bool FirstUnknown = FirstAllocMod == OMPC_ALLOCATE_unknown;
2268 bool SecondUnknown = SecondAllocMod == OMPC_ALLOCATE_unknown;
2269 if (FirstAllocMod == OMPC_ALLOCATE_allocator ||
2270 (FirstAllocMod == OMPC_ALLOCATE_unknown && Node->getAllocator())) {
2271 FirstModifier = Node->getAllocator();
2272 SecondModifier = Node->getAlignment();
2273 } else {
2274 FirstModifier = Node->getAlignment();
2275 SecondModifier = Node->getAllocator();
2276 }
2277
2278 OS << "allocate";
2279 // If we have any explicit modifiers.
2280 if (FirstModifier) {
2281 OS << "(";
2282 if (!FirstUnknown) {
2283 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: FirstAllocMod);
2284 OS << "(";
2285 }
2286 FirstModifier->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2287 if (!FirstUnknown)
2288 OS << ")";
2289 if (SecondModifier) {
2290 OS << ", ";
2291 if (!SecondUnknown) {
2292 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(),
2293 Type: SecondAllocMod);
2294 OS << "(";
2295 }
2296 SecondModifier->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2297 if (!SecondUnknown)
2298 OS << ")";
2299 }
2300 OS << ":";
2301 VisitOMPClauseList(Node, StartSym: ' ');
2302 } else {
2303 // No modifiers. Just print the variable list.
2304 VisitOMPClauseList(Node, StartSym: '(');
2305 }
2306 OS << ")";
2307}
2308
2309void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
2310 if (!Node->varlist_empty()) {
2311 OS << "private";
2312 VisitOMPClauseList(Node, StartSym: '(');
2313 OS << ")";
2314 }
2315}
2316
2317void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
2318 if (!Node->varlist_empty()) {
2319 OS << "firstprivate";
2320 VisitOMPClauseList(Node, StartSym: '(');
2321 OS << ")";
2322 }
2323}
2324
2325void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
2326 if (!Node->varlist_empty()) {
2327 OS << "lastprivate";
2328 OpenMPLastprivateModifier LPKind = Node->getKind();
2329 if (LPKind != OMPC_LASTPRIVATE_unknown) {
2330 OS << "("
2331 << getOpenMPSimpleClauseTypeName(Kind: OMPC_lastprivate, Type: Node->getKind())
2332 << ":";
2333 }
2334 VisitOMPClauseList(Node, StartSym: LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
2335 OS << ")";
2336 }
2337}
2338
2339void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
2340 if (!Node->varlist_empty()) {
2341 OS << "shared";
2342 VisitOMPClauseList(Node, StartSym: '(');
2343 OS << ")";
2344 }
2345}
2346
2347void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
2348 if (!Node->varlist_empty()) {
2349 OS << "reduction(";
2350 if (Node->getModifierLoc().isValid())
2351 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_reduction, Type: Node->getModifier())
2352 << ", ";
2353 NestedNameSpecifier *QualifierLoc =
2354 Node->getQualifierLoc().getNestedNameSpecifier();
2355 OverloadedOperatorKind OOK =
2356 Node->getNameInfo().getName().getCXXOverloadedOperator();
2357 if (QualifierLoc == nullptr && OOK != OO_None) {
2358 // Print reduction identifier in C format
2359 OS << getOperatorSpelling(Operator: OOK);
2360 } else {
2361 // Use C++ format
2362 if (QualifierLoc != nullptr)
2363 QualifierLoc->print(OS, Policy);
2364 OS << Node->getNameInfo();
2365 }
2366 OS << ":";
2367 VisitOMPClauseList(Node, StartSym: ' ');
2368 OS << ")";
2369 }
2370}
2371
2372void OMPClausePrinter::VisitOMPTaskReductionClause(
2373 OMPTaskReductionClause *Node) {
2374 if (!Node->varlist_empty()) {
2375 OS << "task_reduction(";
2376 NestedNameSpecifier *QualifierLoc =
2377 Node->getQualifierLoc().getNestedNameSpecifier();
2378 OverloadedOperatorKind OOK =
2379 Node->getNameInfo().getName().getCXXOverloadedOperator();
2380 if (QualifierLoc == nullptr && OOK != OO_None) {
2381 // Print reduction identifier in C format
2382 OS << getOperatorSpelling(Operator: OOK);
2383 } else {
2384 // Use C++ format
2385 if (QualifierLoc != nullptr)
2386 QualifierLoc->print(OS, Policy);
2387 OS << Node->getNameInfo();
2388 }
2389 OS << ":";
2390 VisitOMPClauseList(Node, StartSym: ' ');
2391 OS << ")";
2392 }
2393}
2394
2395void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
2396 if (!Node->varlist_empty()) {
2397 OS << "in_reduction(";
2398 NestedNameSpecifier *QualifierLoc =
2399 Node->getQualifierLoc().getNestedNameSpecifier();
2400 OverloadedOperatorKind OOK =
2401 Node->getNameInfo().getName().getCXXOverloadedOperator();
2402 if (QualifierLoc == nullptr && OOK != OO_None) {
2403 // Print reduction identifier in C format
2404 OS << getOperatorSpelling(Operator: OOK);
2405 } else {
2406 // Use C++ format
2407 if (QualifierLoc != nullptr)
2408 QualifierLoc->print(OS, Policy);
2409 OS << Node->getNameInfo();
2410 }
2411 OS << ":";
2412 VisitOMPClauseList(Node, StartSym: ' ');
2413 OS << ")";
2414 }
2415}
2416
2417void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
2418 if (!Node->varlist_empty()) {
2419 OS << "linear";
2420 VisitOMPClauseList(Node, StartSym: '(');
2421 if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {
2422 OS << ": ";
2423 }
2424 if (Node->getModifierLoc().isValid()) {
2425 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_linear, Type: Node->getModifier());
2426 }
2427 if (Node->getStep() != nullptr) {
2428 if (Node->getModifierLoc().isValid()) {
2429 OS << ", ";
2430 }
2431 OS << "step(";
2432 Node->getStep()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2433 OS << ")";
2434 }
2435 OS << ")";
2436 }
2437}
2438
2439void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
2440 if (!Node->varlist_empty()) {
2441 OS << "aligned";
2442 VisitOMPClauseList(Node, StartSym: '(');
2443 if (Node->getAlignment() != nullptr) {
2444 OS << ": ";
2445 Node->getAlignment()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2446 }
2447 OS << ")";
2448 }
2449}
2450
2451void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
2452 if (!Node->varlist_empty()) {
2453 OS << "copyin";
2454 VisitOMPClauseList(Node, StartSym: '(');
2455 OS << ")";
2456 }
2457}
2458
2459void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
2460 if (!Node->varlist_empty()) {
2461 OS << "copyprivate";
2462 VisitOMPClauseList(Node, StartSym: '(');
2463 OS << ")";
2464 }
2465}
2466
2467void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
2468 if (!Node->varlist_empty()) {
2469 VisitOMPClauseList(Node, StartSym: '(');
2470 OS << ")";
2471 }
2472}
2473
2474void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
2475 OS << "(";
2476 Node->getDepobj()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2477 OS << ")";
2478}
2479
2480void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
2481 OS << "depend(";
2482 if (Expr *DepModifier = Node->getModifier()) {
2483 DepModifier->printPretty(OS, Helper: nullptr, Policy);
2484 OS << ", ";
2485 }
2486 OpenMPDependClauseKind DepKind = Node->getDependencyKind();
2487 OpenMPDependClauseKind PrintKind = DepKind;
2488 bool IsOmpAllMemory = false;
2489 if (PrintKind == OMPC_DEPEND_outallmemory) {
2490 PrintKind = OMPC_DEPEND_out;
2491 IsOmpAllMemory = true;
2492 } else if (PrintKind == OMPC_DEPEND_inoutallmemory) {
2493 PrintKind = OMPC_DEPEND_inout;
2494 IsOmpAllMemory = true;
2495 }
2496 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: PrintKind);
2497 if (!Node->varlist_empty() || IsOmpAllMemory)
2498 OS << " :";
2499 VisitOMPClauseList(Node, StartSym: ' ');
2500 if (IsOmpAllMemory) {
2501 OS << (Node->varlist_empty() ? " " : ",");
2502 OS << "omp_all_memory";
2503 }
2504 OS << ")";
2505}
2506
2507template <typename T>
2508static void PrintMapper(raw_ostream &OS, T *Node,
2509 const PrintingPolicy &Policy) {
2510 OS << '(';
2511 NestedNameSpecifier *MapperNNS =
2512 Node->getMapperQualifierLoc().getNestedNameSpecifier();
2513 if (MapperNNS)
2514 MapperNNS->print(OS, Policy);
2515 OS << Node->getMapperIdInfo() << ')';
2516}
2517
2518template <typename T>
2519static void PrintIterator(raw_ostream &OS, T *Node,
2520 const PrintingPolicy &Policy) {
2521 if (Expr *IteratorModifier = Node->getIteratorModifier())
2522 IteratorModifier->printPretty(OS, Helper: nullptr, Policy);
2523}
2524
2525void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
2526 if (!Node->varlist_empty()) {
2527 OS << "map(";
2528 if (Node->getMapType() != OMPC_MAP_unknown) {
2529 for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
2530 if (Node->getMapTypeModifier(Cnt: I) != OMPC_MAP_MODIFIER_unknown) {
2531 if (Node->getMapTypeModifier(Cnt: I) == OMPC_MAP_MODIFIER_iterator) {
2532 PrintIterator(OS, Node, Policy);
2533 } else {
2534 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_map,
2535 Type: Node->getMapTypeModifier(Cnt: I));
2536 if (Node->getMapTypeModifier(Cnt: I) == OMPC_MAP_MODIFIER_mapper)
2537 PrintMapper(OS, Node, Policy);
2538 }
2539 OS << ',';
2540 }
2541 }
2542 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_map, Type: Node->getMapType());
2543 OS << ':';
2544 }
2545 VisitOMPClauseList(Node, StartSym: ' ');
2546 OS << ")";
2547 }
2548}
2549
2550template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {
2551 if (Node->varlist_empty())
2552 return;
2553 OS << getOpenMPClauseName(Node->getClauseKind());
2554 unsigned ModifierCount = 0;
2555 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2556 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)
2557 ++ModifierCount;
2558 }
2559 if (ModifierCount) {
2560 OS << '(';
2561 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2562 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {
2563 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
2564 Node->getMotionModifier(I));
2565 if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)
2566 PrintMapper(OS, Node, Policy);
2567 if (I < ModifierCount - 1)
2568 OS << ", ";
2569 }
2570 }
2571 OS << ':';
2572 VisitOMPClauseList(Node, ' ');
2573 } else {
2574 VisitOMPClauseList(Node, '(');
2575 }
2576 OS << ")";
2577}
2578
2579void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
2580 VisitOMPMotionClause(Node);
2581}
2582
2583void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
2584 VisitOMPMotionClause(Node);
2585}
2586
2587void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
2588 OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
2589 Kind: OMPC_dist_schedule, Type: Node->getDistScheduleKind());
2590 if (auto *E = Node->getChunkSize()) {
2591 OS << ", ";
2592 E->printPretty(OS, Helper: nullptr, Policy);
2593 }
2594 OS << ")";
2595}
2596
2597void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
2598 OS << "defaultmap(";
2599 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_defaultmap,
2600 Type: Node->getDefaultmapModifier());
2601 if (Node->getDefaultmapKind() != OMPC_DEFAULTMAP_unknown) {
2602 OS << ": ";
2603 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_defaultmap,
2604 Type: Node->getDefaultmapKind());
2605 }
2606 OS << ")";
2607}
2608
2609void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
2610 if (!Node->varlist_empty()) {
2611 OS << "use_device_ptr";
2612 VisitOMPClauseList(Node, StartSym: '(');
2613 OS << ")";
2614 }
2615}
2616
2617void OMPClausePrinter::VisitOMPUseDeviceAddrClause(
2618 OMPUseDeviceAddrClause *Node) {
2619 if (!Node->varlist_empty()) {
2620 OS << "use_device_addr";
2621 VisitOMPClauseList(Node, StartSym: '(');
2622 OS << ")";
2623 }
2624}
2625
2626void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
2627 if (!Node->varlist_empty()) {
2628 OS << "is_device_ptr";
2629 VisitOMPClauseList(Node, StartSym: '(');
2630 OS << ")";
2631 }
2632}
2633
2634void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {
2635 if (!Node->varlist_empty()) {
2636 OS << "has_device_addr";
2637 VisitOMPClauseList(Node, StartSym: '(');
2638 OS << ")";
2639 }
2640}
2641
2642void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
2643 if (!Node->varlist_empty()) {
2644 OS << "nontemporal";
2645 VisitOMPClauseList(Node, StartSym: '(');
2646 OS << ")";
2647 }
2648}
2649
2650void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
2651 OS << "order(";
2652 if (Node->getModifier() != OMPC_ORDER_MODIFIER_unknown) {
2653 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_order, Type: Node->getModifier());
2654 OS << ": ";
2655 }
2656 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_order, Type: Node->getKind()) << ")";
2657}
2658
2659void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
2660 if (!Node->varlist_empty()) {
2661 OS << "inclusive";
2662 VisitOMPClauseList(Node, StartSym: '(');
2663 OS << ")";
2664 }
2665}
2666
2667void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
2668 if (!Node->varlist_empty()) {
2669 OS << "exclusive";
2670 VisitOMPClauseList(Node, StartSym: '(');
2671 OS << ")";
2672 }
2673}
2674
2675void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
2676 OMPUsesAllocatorsClause *Node) {
2677 if (Node->getNumberOfAllocators() == 0)
2678 return;
2679 OS << "uses_allocators(";
2680 for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {
2681 OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);
2682 Data.Allocator->printPretty(OS, Helper: nullptr, Policy);
2683 if (Data.AllocatorTraits) {
2684 OS << "(";
2685 Data.AllocatorTraits->printPretty(OS, Helper: nullptr, Policy);
2686 OS << ")";
2687 }
2688 if (I < E - 1)
2689 OS << ",";
2690 }
2691 OS << ")";
2692}
2693
2694void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
2695 if (Node->varlist_empty())
2696 return;
2697 OS << "affinity";
2698 char StartSym = '(';
2699 if (Expr *Modifier = Node->getModifier()) {
2700 OS << "(";
2701 Modifier->printPretty(OS, Helper: nullptr, Policy);
2702 OS << " :";
2703 StartSym = ' ';
2704 }
2705 VisitOMPClauseList(Node, StartSym);
2706 OS << ")";
2707}
2708
2709void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
2710 OS << "filter(";
2711 Node->getThreadID()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2712 OS << ")";
2713}
2714
2715void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
2716 OS << "bind("
2717 << getOpenMPSimpleClauseTypeName(Kind: OMPC_bind, Type: unsigned(Node->getBindKind()))
2718 << ")";
2719}
2720
2721void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
2722 OMPXDynCGroupMemClause *Node) {
2723 OS << "ompx_dyn_cgroup_mem(";
2724 Node->getSize()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2725 OS << ")";
2726}
2727
2728void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {
2729 OS << "doacross(";
2730 OpenMPDoacrossClauseModifier DepType = Node->getDependenceType();
2731
2732 switch (DepType) {
2733 case OMPC_DOACROSS_source:
2734 OS << "source:";
2735 break;
2736 case OMPC_DOACROSS_sink:
2737 OS << "sink:";
2738 break;
2739 case OMPC_DOACROSS_source_omp_cur_iteration:
2740 OS << "source: omp_cur_iteration";
2741 break;
2742 case OMPC_DOACROSS_sink_omp_cur_iteration:
2743 OS << "sink: omp_cur_iteration - 1";
2744 break;
2745 default:
2746 llvm_unreachable("unknown docaross modifier");
2747 }
2748 VisitOMPClauseList(Node, StartSym: ' ');
2749 OS << ")";
2750}
2751
2752void OMPClausePrinter::VisitOMPXAttributeClause(OMPXAttributeClause *Node) {
2753 OS << "ompx_attribute(";
2754 bool IsFirst = true;
2755 for (auto &Attr : Node->getAttrs()) {
2756 if (!IsFirst)
2757 OS << ", ";
2758 Attr->printPretty(OS, Policy);
2759 IsFirst = false;
2760 }
2761 OS << ")";
2762}
2763
2764void OMPClausePrinter::VisitOMPXBareClause(OMPXBareClause *Node) {
2765 OS << "ompx_bare";
2766}
2767
2768void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
2769 VariantMatchInfo &VMI) const {
2770 for (const OMPTraitSet &Set : Sets) {
2771 for (const OMPTraitSelector &Selector : Set.Selectors) {
2772
2773 // User conditions are special as we evaluate the condition here.
2774 if (Selector.Kind == TraitSelector::user_condition) {
2775 assert(Selector.ScoreOrCondition &&
2776 "Ill-formed user condition, expected condition expression!");
2777 assert(Selector.Properties.size() == 1 &&
2778 Selector.Properties.front().Kind ==
2779 TraitProperty::user_condition_unknown &&
2780 "Ill-formed user condition, expected unknown trait property!");
2781
2782 if (std::optional<APSInt> CondVal =
2783 Selector.ScoreOrCondition->getIntegerConstantExpr(Ctx: ASTCtx))
2784 VMI.addTrait(Property: CondVal->isZero() ? TraitProperty::user_condition_false
2785 : TraitProperty::user_condition_true,
2786 RawString: "<condition>");
2787 else
2788 VMI.addTrait(Property: TraitProperty::user_condition_false, RawString: "<condition>");
2789 continue;
2790 }
2791
2792 std::optional<llvm::APSInt> Score;
2793 llvm::APInt *ScorePtr = nullptr;
2794 if (Selector.ScoreOrCondition) {
2795 if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(Ctx: ASTCtx)))
2796 ScorePtr = &*Score;
2797 else
2798 VMI.addTrait(Property: TraitProperty::user_condition_false,
2799 RawString: "<non-constant-score>");
2800 }
2801
2802 for (const OMPTraitProperty &Property : Selector.Properties)
2803 VMI.addTrait(Set: Set.Kind, Property: Property.Kind, RawString: Property.RawString, Score: ScorePtr);
2804
2805 if (Set.Kind != TraitSet::construct)
2806 continue;
2807
2808 // TODO: This might not hold once we implement SIMD properly.
2809 assert(Selector.Properties.size() == 1 &&
2810 Selector.Properties.front().Kind ==
2811 getOpenMPContextTraitPropertyForSelector(
2812 Selector.Kind) &&
2813 "Ill-formed construct selector!");
2814 }
2815 }
2816}
2817
2818void OMPTraitInfo::print(llvm::raw_ostream &OS,
2819 const PrintingPolicy &Policy) const {
2820 bool FirstSet = true;
2821 for (const OMPTraitSet &Set : Sets) {
2822 if (!FirstSet)
2823 OS << ", ";
2824 FirstSet = false;
2825 OS << getOpenMPContextTraitSetName(Kind: Set.Kind) << "={";
2826
2827 bool FirstSelector = true;
2828 for (const OMPTraitSelector &Selector : Set.Selectors) {
2829 if (!FirstSelector)
2830 OS << ", ";
2831 FirstSelector = false;
2832 OS << getOpenMPContextTraitSelectorName(Kind: Selector.Kind);
2833
2834 bool AllowsTraitScore = false;
2835 bool RequiresProperty = false;
2836 isValidTraitSelectorForTraitSet(
2837 Selector: Selector.Kind, Set: Set.Kind, AllowsTraitScore, RequiresProperty);
2838
2839 if (!RequiresProperty)
2840 continue;
2841
2842 OS << "(";
2843 if (Selector.Kind == TraitSelector::user_condition) {
2844 if (Selector.ScoreOrCondition)
2845 Selector.ScoreOrCondition->printPretty(OS, Helper: nullptr, Policy);
2846 else
2847 OS << "...";
2848 } else {
2849
2850 if (Selector.ScoreOrCondition) {
2851 OS << "score(";
2852 Selector.ScoreOrCondition->printPretty(OS, Helper: nullptr, Policy);
2853 OS << "): ";
2854 }
2855
2856 bool FirstProperty = true;
2857 for (const OMPTraitProperty &Property : Selector.Properties) {
2858 if (!FirstProperty)
2859 OS << ", ";
2860 FirstProperty = false;
2861 OS << getOpenMPContextTraitPropertyName(Kind: Property.Kind,
2862 RawString: Property.RawString);
2863 }
2864 }
2865 OS << ")";
2866 }
2867 OS << "}";
2868 }
2869}
2870
2871std::string OMPTraitInfo::getMangledName() const {
2872 std::string MangledName;
2873 llvm::raw_string_ostream OS(MangledName);
2874 for (const OMPTraitSet &Set : Sets) {
2875 OS << '$' << 'S' << unsigned(Set.Kind);
2876 for (const OMPTraitSelector &Selector : Set.Selectors) {
2877
2878 bool AllowsTraitScore = false;
2879 bool RequiresProperty = false;
2880 isValidTraitSelectorForTraitSet(
2881 Selector: Selector.Kind, Set: Set.Kind, AllowsTraitScore, RequiresProperty);
2882 OS << '$' << 's' << unsigned(Selector.Kind);
2883
2884 if (!RequiresProperty ||
2885 Selector.Kind == TraitSelector::user_condition)
2886 continue;
2887
2888 for (const OMPTraitProperty &Property : Selector.Properties)
2889 OS << '$' << 'P'
2890 << getOpenMPContextTraitPropertyName(Kind: Property.Kind,
2891 RawString: Property.RawString);
2892 }
2893 }
2894 return MangledName;
2895}
2896
2897OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
2898 unsigned long U;
2899 do {
2900 if (!MangledName.consume_front(Prefix: "$S"))
2901 break;
2902 if (MangledName.consumeInteger(Radix: 10, Result&: U))
2903 break;
2904 Sets.push_back(Elt: OMPTraitSet());
2905 OMPTraitSet &Set = Sets.back();
2906 Set.Kind = TraitSet(U);
2907 do {
2908 if (!MangledName.consume_front(Prefix: "$s"))
2909 break;
2910 if (MangledName.consumeInteger(Radix: 10, Result&: U))
2911 break;
2912 Set.Selectors.push_back(Elt: OMPTraitSelector());
2913 OMPTraitSelector &Selector = Set.Selectors.back();
2914 Selector.Kind = TraitSelector(U);
2915 do {
2916 if (!MangledName.consume_front(Prefix: "$P"))
2917 break;
2918 Selector.Properties.push_back(Elt: OMPTraitProperty());
2919 OMPTraitProperty &Property = Selector.Properties.back();
2920 std::pair<StringRef, StringRef> PropRestPair = MangledName.split(Separator: '$');
2921 Property.RawString = PropRestPair.first;
2922 Property.Kind = getOpenMPContextTraitPropertyKind(
2923 Set: Set.Kind, Selector: Selector.Kind, Str: PropRestPair.first);
2924 MangledName = MangledName.drop_front(N: PropRestPair.first.size());
2925 } while (true);
2926 } while (true);
2927 } while (true);
2928}
2929
2930llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
2931 const OMPTraitInfo &TI) {
2932 LangOptions LO;
2933 PrintingPolicy Policy(LO);
2934 TI.print(OS, Policy);
2935 return OS;
2936}
2937llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
2938 const OMPTraitInfo *TI) {
2939 return TI ? OS << *TI : OS;
2940}
2941
2942TargetOMPContext::TargetOMPContext(
2943 ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
2944 const FunctionDecl *CurrentFunctionDecl,
2945 ArrayRef<llvm::omp::TraitProperty> ConstructTraits, int DeviceNum)
2946 : OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
2947 ASTCtx.getTargetInfo().getTriple(),
2948 ASTCtx.getLangOpts().OMPTargetTriples.empty()
2949 ? llvm::Triple()
2950 : ASTCtx.getLangOpts().OMPTargetTriples[0],
2951 DeviceNum),
2952 FeatureValidityCheck([&](StringRef FeatureName) {
2953 return ASTCtx.getTargetInfo().isValidFeatureName(Feature: FeatureName);
2954 }),
2955 DiagUnknownTrait(std::move(DiagUnknownTrait)) {
2956 ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);
2957
2958 for (llvm::omp::TraitProperty Property : ConstructTraits)
2959 addTrait(Property);
2960}
2961
2962bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
2963 auto It = FeatureMap.find(Key: RawString);
2964 if (It != FeatureMap.end())
2965 return It->second;
2966 if (!FeatureValidityCheck(RawString))
2967 DiagUnknownTrait(RawString);
2968 return false;
2969}
2970