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