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