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