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, OpenMPThreadLimitClauseModifier Modifier,
1982 Expr *ModifierExpr, SourceLocation ModifierLoc, Stmt *PreInit) {
1983 // Reserve space for an extra modifier expression.
1984 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + 1));
1985 OMPThreadLimitClause *Clause =
1986 new (Mem) OMPThreadLimitClause(C, StartLoc, LParenLoc, EndLoc, VL.size());
1987 Clause->setVarRefs(VL);
1988 Clause->setModifier(Modifier);
1989 Clause->setModifierExpr(ModifierExpr);
1990 Clause->setModifierLoc(ModifierLoc);
1991 Clause->setPreInitStmt(S: PreInit, ThisRegion: CaptureRegion);
1992 return Clause;
1993}
1994
1995OMPThreadLimitClause *OMPThreadLimitClause::CreateEmpty(const ASTContext &C,
1996 unsigned N) {
1997 // Reserve space for an extra modifier expression.
1998 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N + 1));
1999 return new (Mem) OMPThreadLimitClause(N);
2000}
2001
2002//===----------------------------------------------------------------------===//
2003// OpenMP clauses printing methods
2004//===----------------------------------------------------------------------===//
2005
2006void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
2007 OS << "if(";
2008 if (Node->getNameModifier() != OMPD_unknown)
2009 OS << getOpenMPDirectiveName(D: Node->getNameModifier(), Ver: Version) << ": ";
2010 Node->getCondition()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2011 OS << ")";
2012}
2013
2014void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
2015 OS << "final(";
2016 Node->getCondition()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2017 OS << ")";
2018}
2019
2020void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
2021 OS << "num_threads(";
2022 OpenMPNumThreadsClauseModifier Modifier = Node->getModifier();
2023 if (Modifier != OMPC_NUMTHREADS_unknown) {
2024 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2025 << ": ";
2026 }
2027 Node->getNumThreads()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2028 OS << ")";
2029}
2030
2031void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
2032 OS << "align(";
2033 Node->getAlignment()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2034 OS << ")";
2035}
2036
2037void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
2038 OS << "safelen(";
2039 Node->getSafelen()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2040 OS << ")";
2041}
2042
2043void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
2044 OS << "simdlen(";
2045 Node->getSimdlen()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2046 OS << ")";
2047}
2048
2049void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {
2050 OS << "sizes(";
2051 bool First = true;
2052 for (auto *Size : Node->getSizesRefs()) {
2053 if (!First)
2054 OS << ", ";
2055 Size->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2056 First = false;
2057 }
2058 OS << ")";
2059}
2060
2061void OMPClausePrinter::VisitOMPCountsClause(OMPCountsClause *Node) {
2062 OS << "counts(";
2063 std::optional<unsigned> FillIdx = Node->getOmpFillIndex();
2064 ArrayRef<Expr *> Refs = Node->getCountsRefs();
2065 llvm::interleaveComma(c: llvm::seq<unsigned>(Size: Refs.size()), os&: OS, each_fn: [&](unsigned I) {
2066 if (FillIdx && I == *FillIdx)
2067 OS << "omp_fill";
2068 else
2069 Refs[I]->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2070 });
2071 OS << ")";
2072}
2073
2074void OMPClausePrinter::VisitOMPPermutationClause(OMPPermutationClause *Node) {
2075 OS << "permutation(";
2076 llvm::interleaveComma(c: Node->getArgsRefs(), os&: OS, each_fn: [&](const Expr *E) {
2077 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2078 });
2079 OS << ")";
2080}
2081
2082void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }
2083
2084void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
2085 OS << "partial";
2086
2087 if (Expr *Factor = Node->getFactor()) {
2088 OS << '(';
2089 Factor->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2090 OS << ')';
2091 }
2092}
2093
2094void OMPClausePrinter::VisitOMPLoopRangeClause(OMPLoopRangeClause *Node) {
2095 OS << "looprange";
2096
2097 Expr *First = Node->getFirst();
2098 Expr *Count = Node->getCount();
2099
2100 if (First && Count) {
2101 OS << "(";
2102 First->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2103 OS << ",";
2104 Count->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2105 OS << ")";
2106 }
2107}
2108
2109void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
2110 OS << "allocator(";
2111 Node->getAllocator()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2112 OS << ")";
2113}
2114
2115void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
2116 OS << "collapse(";
2117 Node->getNumForLoops()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2118 OS << ")";
2119}
2120
2121void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
2122 OS << "detach(";
2123 Node->getEventHandler()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2124 OS << ")";
2125}
2126
2127void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
2128 OS << "default("
2129 << getOpenMPSimpleClauseTypeName(Kind: OMPC_default,
2130 Type: unsigned(Node->getDefaultKind()));
2131 if (Version >= 60 && Node->getDefaultVC() != OMPC_DEFAULT_VC_all) {
2132 OS << ":"
2133 << getOpenMPDefaultVariableCategoryName(VC: unsigned(Node->getDefaultVC()));
2134 }
2135
2136 OS << ")";
2137}
2138
2139void OMPClausePrinter::VisitOMPThreadsetClause(OMPThreadsetClause *Node) {
2140 OS << "threadset("
2141 << getOpenMPSimpleClauseTypeName(Kind: OMPC_threadset,
2142 Type: unsigned(Node->getThreadsetKind()))
2143 << ")";
2144}
2145
2146void OMPClausePrinter::VisitOMPTransparentClause(OMPTransparentClause *Node) {
2147 OS << "transparent(";
2148 if (Node->getImpexType())
2149 Node->getImpexType()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2150 else
2151 OS << "omp_impex";
2152 OS << ")";
2153}
2154
2155void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
2156 OS << "proc_bind("
2157 << getOpenMPSimpleClauseTypeName(Kind: OMPC_proc_bind,
2158 Type: unsigned(Node->getProcBindKind()))
2159 << ")";
2160}
2161
2162void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
2163 OS << "unified_address";
2164}
2165
2166void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
2167 OMPUnifiedSharedMemoryClause *) {
2168 OS << "unified_shared_memory";
2169}
2170
2171void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
2172 OS << "reverse_offload";
2173}
2174
2175void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
2176 OMPDynamicAllocatorsClause *) {
2177 OS << "dynamic_allocators";
2178}
2179
2180void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
2181 OMPAtomicDefaultMemOrderClause *Node) {
2182 OS << "atomic_default_mem_order("
2183 << getOpenMPSimpleClauseTypeName(Kind: OMPC_atomic_default_mem_order,
2184 Type: Node->getAtomicDefaultMemOrderKind())
2185 << ")";
2186}
2187
2188void OMPClausePrinter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {
2189 OS << "self_maps";
2190}
2191
2192void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
2193 OS << "at(" << getOpenMPSimpleClauseTypeName(Kind: OMPC_at, Type: Node->getAtKind())
2194 << ")";
2195}
2196
2197void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
2198 OS << "severity("
2199 << getOpenMPSimpleClauseTypeName(Kind: OMPC_severity, Type: Node->getSeverityKind())
2200 << ")";
2201}
2202
2203void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
2204 OS << "message(";
2205 if (Expr *E = Node->getMessageString())
2206 E->printPretty(OS, Helper: nullptr, Policy);
2207 OS << ")";
2208}
2209
2210void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
2211 OS << "schedule(";
2212 if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
2213 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule,
2214 Type: Node->getFirstScheduleModifier());
2215 if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
2216 OS << ", ";
2217 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule,
2218 Type: Node->getSecondScheduleModifier());
2219 }
2220 OS << ": ";
2221 }
2222 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule, Type: Node->getScheduleKind());
2223 if (auto *E = Node->getChunkSize()) {
2224 OS << ", ";
2225 E->printPretty(OS, Helper: nullptr, Policy);
2226 }
2227 OS << ")";
2228}
2229
2230void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
2231 OS << "ordered";
2232 if (auto *Num = Node->getNumForLoops()) {
2233 OS << "(";
2234 Num->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2235 OS << ")";
2236 }
2237}
2238
2239void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *Node) {
2240 OS << "nowait";
2241 if (auto *Cond = Node->getCondition()) {
2242 OS << "(";
2243 Cond->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2244 OS << ")";
2245 }
2246}
2247
2248void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
2249 OS << "untied";
2250}
2251
2252void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
2253 OS << "nogroup";
2254}
2255
2256void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
2257 OS << "mergeable";
2258}
2259
2260void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
2261
2262void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
2263
2264void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
2265 OS << "update";
2266 if (Node->isExtended()) {
2267 OS << "(";
2268 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(),
2269 Type: Node->getDependencyKind());
2270 OS << ")";
2271 }
2272}
2273
2274void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
2275 OS << "capture";
2276}
2277
2278void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
2279 OS << "compare";
2280}
2281
2282void OMPClausePrinter::VisitOMPFailClause(OMPFailClause *Node) {
2283 OS << "fail";
2284 if (Node) {
2285 OS << "(";
2286 OS << getOpenMPSimpleClauseTypeName(
2287 Kind: Node->getClauseKind(), Type: static_cast<int>(Node->getFailParameter()));
2288 OS << ")";
2289 }
2290}
2291
2292void OMPClausePrinter::VisitOMPAbsentClause(OMPAbsentClause *Node) {
2293 OS << "absent(";
2294 bool First = true;
2295 for (auto &D : Node->getDirectiveKinds()) {
2296 if (!First)
2297 OS << ", ";
2298 OS << getOpenMPDirectiveName(D, Ver: Version);
2299 First = false;
2300 }
2301 OS << ")";
2302}
2303
2304void OMPClausePrinter::VisitOMPHoldsClause(OMPHoldsClause *Node) {
2305 OS << "holds(";
2306 Node->getExpr()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2307 OS << ")";
2308}
2309
2310void OMPClausePrinter::VisitOMPContainsClause(OMPContainsClause *Node) {
2311 OS << "contains(";
2312 bool First = true;
2313 for (auto &D : Node->getDirectiveKinds()) {
2314 if (!First)
2315 OS << ", ";
2316 OS << getOpenMPDirectiveName(D, Ver: Version);
2317 First = false;
2318 }
2319 OS << ")";
2320}
2321
2322void OMPClausePrinter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {
2323 OS << "no_openmp";
2324}
2325
2326void OMPClausePrinter::VisitOMPNoOpenMPRoutinesClause(
2327 OMPNoOpenMPRoutinesClause *) {
2328 OS << "no_openmp_routines";
2329}
2330
2331void OMPClausePrinter::VisitOMPNoOpenMPConstructsClause(
2332 OMPNoOpenMPConstructsClause *) {
2333 OS << "no_openmp_constructs";
2334}
2335
2336void OMPClausePrinter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {
2337 OS << "no_parallelism";
2338}
2339
2340void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
2341 OS << "seq_cst";
2342}
2343
2344void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
2345 OS << "acq_rel";
2346}
2347
2348void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
2349 OS << "acquire";
2350}
2351
2352void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
2353 OS << "release";
2354}
2355
2356void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
2357 OS << "relaxed";
2358}
2359
2360void OMPClausePrinter::VisitOMPWeakClause(OMPWeakClause *) { OS << "weak"; }
2361
2362void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
2363 OS << "threads";
2364}
2365
2366void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
2367
2368void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
2369 OS << "device(";
2370 OpenMPDeviceClauseModifier Modifier = Node->getModifier();
2371 if (Modifier != OMPC_DEVICE_unknown) {
2372 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2373 << ": ";
2374 }
2375 Node->getDevice()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2376 OS << ")";
2377}
2378
2379void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
2380 if (!Node->varlist_empty()) {
2381 OS << "num_teams";
2382 if (Node->getModifier() != OMPC_NUMTEAMS_unknown) {
2383 OS << "(";
2384 if (Node->getModifier() == OMPC_NUMTEAMS_dims)
2385 OS << "dims(";
2386 Node->getModifierExpr()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2387 if (Node->getModifier() == OMPC_NUMTEAMS_dims)
2388 OS << ")";
2389 VisitOMPClauseList(Node, StartSym: ':');
2390 } else {
2391 VisitOMPClauseList(Node, StartSym: '(');
2392 }
2393 OS << ")";
2394 }
2395}
2396
2397void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
2398 if (!Node->varlist_empty()) {
2399 OS << "thread_limit";
2400 if (Node->getModifier() == OMPC_THREADLIMIT_dims) {
2401 OS << "(dims(";
2402 Node->getModifierExpr()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2403 OS << ")";
2404 VisitOMPClauseList(Node, StartSym: ':');
2405 } else {
2406 VisitOMPClauseList(Node, StartSym: '(');
2407 }
2408 OS << ")";
2409 }
2410}
2411
2412void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
2413 OS << "priority(";
2414 Node->getPriority()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2415 OS << ")";
2416}
2417
2418void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
2419 OS << "grainsize(";
2420 OpenMPGrainsizeClauseModifier Modifier = Node->getModifier();
2421 if (Modifier != OMPC_GRAINSIZE_unknown) {
2422 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2423 << ": ";
2424 }
2425 Node->getGrainsize()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2426 OS << ")";
2427}
2428
2429void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
2430 OS << "num_tasks(";
2431 OpenMPNumTasksClauseModifier Modifier = Node->getModifier();
2432 if (Modifier != OMPC_NUMTASKS_unknown) {
2433 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2434 << ": ";
2435 }
2436 Node->getNumTasks()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2437 OS << ")";
2438}
2439
2440void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
2441 OS << "hint(";
2442 Node->getHint()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2443 OS << ")";
2444}
2445
2446void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
2447 OS << "init(";
2448 if (!Node->prefs().empty()) {
2449 OS << "prefer_type(";
2450 if (Node->hasPreferAttrs()) {
2451 // OMP 6.0 brace-grouped form
2452 llvm::interleaveComma(c: Node->prefs(), os&: OS, each_fn: [&](OMPInitClause::PrefView P) {
2453 OS << "{";
2454 if (P.Fr) {
2455 OS << "fr(";
2456 P.Fr->printPretty(OS, Helper: nullptr, Policy);
2457 OS << ")";
2458 if (!P.Attrs.empty())
2459 OS << ", ";
2460 }
2461 if (!P.Attrs.empty()) {
2462 OS << "attr(";
2463 llvm::interleaveComma(c: P.Attrs, os&: OS, each_fn: [&](const Expr *A) {
2464 A->printPretty(OS, Helper: nullptr, Policy);
2465 });
2466 OS << ")";
2467 }
2468 OS << "}";
2469 });
2470 } else {
2471 llvm::interleave(
2472 c: Node->prefs(), os&: OS,
2473 each_fn: [&](OMPInitClause::PrefView P) {
2474 if (P.Fr)
2475 P.Fr->printPretty(OS, Helper: nullptr, Policy);
2476 },
2477 separator: ",");
2478 }
2479 OS << "), ";
2480 }
2481 if (Node->getIsTarget())
2482 OS << "target";
2483 if (Node->getIsTargetSync()) {
2484 if (Node->getIsTarget())
2485 OS << ", ";
2486 OS << "targetsync";
2487 }
2488 OS << " : ";
2489 Node->getInteropVar()->printPretty(OS, Helper: nullptr, Policy);
2490 OS << ")";
2491}
2492
2493void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
2494 OS << "use(";
2495 Node->getInteropVar()->printPretty(OS, Helper: nullptr, Policy);
2496 OS << ")";
2497}
2498
2499void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {
2500 OS << "destroy";
2501 if (Expr *E = Node->getInteropVar()) {
2502 OS << "(";
2503 E->printPretty(OS, Helper: nullptr, Policy);
2504 OS << ")";
2505 }
2506}
2507
2508void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {
2509 OS << "novariants";
2510 if (Expr *E = Node->getCondition()) {
2511 OS << "(";
2512 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2513 OS << ")";
2514 }
2515}
2516
2517void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {
2518 OS << "nocontext";
2519 if (Expr *E = Node->getCondition()) {
2520 OS << "(";
2521 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2522 OS << ")";
2523 }
2524}
2525
2526template<typename T>
2527void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
2528 for (typename T::varlist_iterator I = Node->varlist_begin(),
2529 E = Node->varlist_end();
2530 I != E; ++I) {
2531 assert(*I && "Expected non-null Stmt");
2532 OS << (I == Node->varlist_begin() ? StartSym : ',');
2533 if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
2534 if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
2535 DRE->printPretty(OS, nullptr, Policy, 0);
2536 else
2537 DRE->getDecl()->printQualifiedName(OS);
2538 } else
2539 (*I)->printPretty(OS, nullptr, Policy, 0);
2540 }
2541}
2542
2543void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
2544 if (Node->varlist_empty())
2545 return;
2546
2547 Expr *FirstModifier = nullptr;
2548 Expr *SecondModifier = nullptr;
2549 auto FirstAllocMod = Node->getFirstAllocateModifier();
2550 auto SecondAllocMod = Node->getSecondAllocateModifier();
2551 bool FirstUnknown = FirstAllocMod == OMPC_ALLOCATE_unknown;
2552 bool SecondUnknown = SecondAllocMod == OMPC_ALLOCATE_unknown;
2553 if (FirstAllocMod == OMPC_ALLOCATE_allocator ||
2554 (FirstAllocMod == OMPC_ALLOCATE_unknown && Node->getAllocator())) {
2555 FirstModifier = Node->getAllocator();
2556 SecondModifier = Node->getAlignment();
2557 } else {
2558 FirstModifier = Node->getAlignment();
2559 SecondModifier = Node->getAllocator();
2560 }
2561
2562 OS << "allocate";
2563 // If we have any explicit modifiers.
2564 if (FirstModifier) {
2565 OS << "(";
2566 if (!FirstUnknown) {
2567 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: FirstAllocMod);
2568 OS << "(";
2569 }
2570 FirstModifier->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2571 if (!FirstUnknown)
2572 OS << ")";
2573 if (SecondModifier) {
2574 OS << ", ";
2575 if (!SecondUnknown) {
2576 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(),
2577 Type: SecondAllocMod);
2578 OS << "(";
2579 }
2580 SecondModifier->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2581 if (!SecondUnknown)
2582 OS << ")";
2583 }
2584 OS << ":";
2585 VisitOMPClauseList(Node, StartSym: ' ');
2586 } else {
2587 // No modifiers. Just print the variable list.
2588 VisitOMPClauseList(Node, StartSym: '(');
2589 }
2590 OS << ")";
2591}
2592
2593void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
2594 if (!Node->varlist_empty()) {
2595 OS << "private";
2596 VisitOMPClauseList(Node, StartSym: '(');
2597 OS << ")";
2598 }
2599}
2600
2601void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
2602 if (!Node->varlist_empty()) {
2603 OS << "firstprivate";
2604 VisitOMPClauseList(Node, StartSym: '(');
2605 OS << ")";
2606 }
2607}
2608
2609void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
2610 if (!Node->varlist_empty()) {
2611 OS << "lastprivate";
2612 OpenMPLastprivateModifier LPKind = Node->getKind();
2613 if (LPKind != OMPC_LASTPRIVATE_unknown) {
2614 OS << "("
2615 << getOpenMPSimpleClauseTypeName(Kind: OMPC_lastprivate, Type: Node->getKind())
2616 << ":";
2617 }
2618 VisitOMPClauseList(Node, StartSym: LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
2619 OS << ")";
2620 }
2621}
2622
2623void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
2624 if (!Node->varlist_empty()) {
2625 OS << "shared";
2626 VisitOMPClauseList(Node, StartSym: '(');
2627 OS << ")";
2628 }
2629}
2630
2631void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
2632 if (!Node->varlist_empty()) {
2633 OS << "reduction(";
2634 if (Node->getModifierLoc().isValid())
2635 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_reduction, Type: Node->getModifier())
2636 << ", ";
2637 NestedNameSpecifier Qualifier =
2638 Node->getQualifierLoc().getNestedNameSpecifier();
2639 OverloadedOperatorKind OOK =
2640 Node->getNameInfo().getName().getCXXOverloadedOperator();
2641 if (!Qualifier && OOK != OO_None) {
2642 // Print reduction identifier in C format
2643 OS << getOperatorSpelling(Operator: OOK);
2644 } else {
2645 // Use C++ format
2646 Qualifier.print(OS, Policy);
2647 OS << Node->getNameInfo();
2648 }
2649 OS << ":";
2650 VisitOMPClauseList(Node, StartSym: ' ');
2651 OS << ")";
2652 }
2653}
2654
2655void OMPClausePrinter::VisitOMPTaskReductionClause(
2656 OMPTaskReductionClause *Node) {
2657 if (!Node->varlist_empty()) {
2658 OS << "task_reduction(";
2659 NestedNameSpecifier Qualifier =
2660 Node->getQualifierLoc().getNestedNameSpecifier();
2661 OverloadedOperatorKind OOK =
2662 Node->getNameInfo().getName().getCXXOverloadedOperator();
2663 if (!Qualifier && OOK != OO_None) {
2664 // Print reduction identifier in C format
2665 OS << getOperatorSpelling(Operator: OOK);
2666 } else {
2667 // Use C++ format
2668 Qualifier.print(OS, Policy);
2669 OS << Node->getNameInfo();
2670 }
2671 OS << ":";
2672 VisitOMPClauseList(Node, StartSym: ' ');
2673 OS << ")";
2674 }
2675}
2676
2677void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
2678 if (!Node->varlist_empty()) {
2679 OS << "in_reduction(";
2680 NestedNameSpecifier Qualifier =
2681 Node->getQualifierLoc().getNestedNameSpecifier();
2682 OverloadedOperatorKind OOK =
2683 Node->getNameInfo().getName().getCXXOverloadedOperator();
2684 if (!Qualifier && OOK != OO_None) {
2685 // Print reduction identifier in C format
2686 OS << getOperatorSpelling(Operator: OOK);
2687 } else {
2688 // Use C++ format
2689 Qualifier.print(OS, Policy);
2690 OS << Node->getNameInfo();
2691 }
2692 OS << ":";
2693 VisitOMPClauseList(Node, StartSym: ' ');
2694 OS << ")";
2695 }
2696}
2697
2698void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
2699 if (!Node->varlist_empty()) {
2700 OS << "linear";
2701 VisitOMPClauseList(Node, StartSym: '(');
2702 if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {
2703 OS << ": ";
2704 }
2705 if (Node->getModifierLoc().isValid()) {
2706 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_linear, Type: Node->getModifier());
2707 }
2708 if (Node->getStep() != nullptr) {
2709 if (Node->getModifierLoc().isValid()) {
2710 OS << ", ";
2711 }
2712 OS << "step(";
2713 Node->getStep()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2714 OS << ")";
2715 }
2716 OS << ")";
2717 }
2718}
2719
2720void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
2721 if (!Node->varlist_empty()) {
2722 OS << "aligned";
2723 VisitOMPClauseList(Node, StartSym: '(');
2724 if (Node->getAlignment() != nullptr) {
2725 OS << ": ";
2726 Node->getAlignment()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2727 }
2728 OS << ")";
2729 }
2730}
2731
2732void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
2733 if (!Node->varlist_empty()) {
2734 OS << "copyin";
2735 VisitOMPClauseList(Node, StartSym: '(');
2736 OS << ")";
2737 }
2738}
2739
2740void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
2741 if (!Node->varlist_empty()) {
2742 OS << "copyprivate";
2743 VisitOMPClauseList(Node, StartSym: '(');
2744 OS << ")";
2745 }
2746}
2747
2748void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
2749 if (!Node->varlist_empty()) {
2750 VisitOMPClauseList(Node, StartSym: '(');
2751 OS << ")";
2752 }
2753}
2754
2755void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
2756 OS << "(";
2757 Node->getDepobj()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2758 OS << ")";
2759}
2760
2761void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
2762 OS << "depend(";
2763 if (Expr *DepModifier = Node->getModifier()) {
2764 DepModifier->printPretty(OS, Helper: nullptr, Policy);
2765 OS << ", ";
2766 }
2767 OpenMPDependClauseKind DepKind = Node->getDependencyKind();
2768 OpenMPDependClauseKind PrintKind = DepKind;
2769 bool IsOmpAllMemory = false;
2770 if (PrintKind == OMPC_DEPEND_outallmemory) {
2771 PrintKind = OMPC_DEPEND_out;
2772 IsOmpAllMemory = true;
2773 } else if (PrintKind == OMPC_DEPEND_inoutallmemory) {
2774 PrintKind = OMPC_DEPEND_inout;
2775 IsOmpAllMemory = true;
2776 }
2777 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: PrintKind);
2778 if (!Node->varlist_empty() || IsOmpAllMemory)
2779 OS << " :";
2780 VisitOMPClauseList(Node, StartSym: ' ');
2781 if (IsOmpAllMemory) {
2782 OS << (Node->varlist_empty() ? " " : ",");
2783 OS << "omp_all_memory";
2784 }
2785 OS << ")";
2786}
2787
2788template <typename T>
2789static void PrintMapper(raw_ostream &OS, T *Node,
2790 const PrintingPolicy &Policy) {
2791 OS << '(';
2792 NestedNameSpecifier MapperNNS =
2793 Node->getMapperQualifierLoc().getNestedNameSpecifier();
2794 MapperNNS.print(OS, Policy);
2795 OS << Node->getMapperIdInfo() << ')';
2796}
2797
2798template <typename T>
2799static void PrintIterator(raw_ostream &OS, T *Node,
2800 const PrintingPolicy &Policy) {
2801 if (Expr *IteratorModifier = Node->getIteratorModifier())
2802 IteratorModifier->printPretty(OS, Helper: nullptr, Policy);
2803}
2804
2805void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
2806 if (!Node->varlist_empty()) {
2807 OS << "map(";
2808 if (Node->getMapType() != OMPC_MAP_unknown) {
2809 for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
2810 if (Node->getMapTypeModifier(Cnt: I) != OMPC_MAP_MODIFIER_unknown) {
2811 if (Node->getMapTypeModifier(Cnt: I) == OMPC_MAP_MODIFIER_iterator) {
2812 PrintIterator(OS, Node, Policy);
2813 } else {
2814 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_map,
2815 Type: Node->getMapTypeModifier(Cnt: I));
2816 if (Node->getMapTypeModifier(Cnt: I) == OMPC_MAP_MODIFIER_mapper)
2817 PrintMapper(OS, Node, Policy);
2818 }
2819 OS << ',';
2820 }
2821 }
2822 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_map, Type: Node->getMapType());
2823 OS << ':';
2824 }
2825 VisitOMPClauseList(Node, StartSym: ' ');
2826 OS << ")";
2827 }
2828}
2829
2830template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {
2831 if (Node->varlist_empty())
2832 return;
2833 OS << getOpenMPClauseName(Node->getClauseKind());
2834 unsigned ModifierCount = 0;
2835 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2836 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)
2837 ++ModifierCount;
2838 }
2839 if (ModifierCount) {
2840 OS << '(';
2841 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2842 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {
2843 if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_iterator) {
2844 PrintIterator(OS, Node, Policy);
2845 } else {
2846 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
2847 Node->getMotionModifier(I));
2848 if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)
2849 PrintMapper(OS, Node, Policy);
2850 if (I < ModifierCount - 1)
2851 OS << ", ";
2852 }
2853 }
2854 }
2855 OS << ':';
2856 VisitOMPClauseList(Node, ' ');
2857 } else {
2858 VisitOMPClauseList(Node, '(');
2859 }
2860 OS << ")";
2861}
2862
2863void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
2864 VisitOMPMotionClause(Node);
2865}
2866
2867void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
2868 VisitOMPMotionClause(Node);
2869}
2870
2871void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
2872 OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
2873 Kind: OMPC_dist_schedule, Type: Node->getDistScheduleKind());
2874 if (auto *E = Node->getChunkSize()) {
2875 OS << ", ";
2876 E->printPretty(OS, Helper: nullptr, Policy);
2877 }
2878 OS << ")";
2879}
2880
2881void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
2882 OS << "defaultmap(";
2883 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_defaultmap,
2884 Type: Node->getDefaultmapModifier());
2885 if (Node->getDefaultmapKind() != OMPC_DEFAULTMAP_unknown) {
2886 OS << ": ";
2887 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_defaultmap,
2888 Type: Node->getDefaultmapKind());
2889 }
2890 OS << ")";
2891}
2892
2893void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
2894 if (!Node->varlist_empty()) {
2895 OS << "use_device_ptr";
2896 if (Node->getFallbackModifier() != OMPC_USE_DEVICE_PTR_FALLBACK_unknown) {
2897 OS << "("
2898 << getOpenMPSimpleClauseTypeName(Kind: OMPC_use_device_ptr,
2899 Type: Node->getFallbackModifier())
2900 << ":";
2901 VisitOMPClauseList(Node, StartSym: ' ');
2902 } else {
2903 VisitOMPClauseList(Node, StartSym: '(');
2904 }
2905 OS << ")";
2906 }
2907}
2908
2909void OMPClausePrinter::VisitOMPUseDeviceAddrClause(
2910 OMPUseDeviceAddrClause *Node) {
2911 if (!Node->varlist_empty()) {
2912 OS << "use_device_addr";
2913 VisitOMPClauseList(Node, StartSym: '(');
2914 OS << ")";
2915 }
2916}
2917
2918void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
2919 if (!Node->varlist_empty()) {
2920 OS << "is_device_ptr";
2921 VisitOMPClauseList(Node, StartSym: '(');
2922 OS << ")";
2923 }
2924}
2925
2926void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {
2927 if (!Node->varlist_empty()) {
2928 OS << "has_device_addr";
2929 VisitOMPClauseList(Node, StartSym: '(');
2930 OS << ")";
2931 }
2932}
2933
2934void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
2935 if (!Node->varlist_empty()) {
2936 OS << "nontemporal";
2937 VisitOMPClauseList(Node, StartSym: '(');
2938 OS << ")";
2939 }
2940}
2941
2942void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
2943 OS << "order(";
2944 if (Node->getModifier() != OMPC_ORDER_MODIFIER_unknown) {
2945 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_order, Type: Node->getModifier());
2946 OS << ": ";
2947 }
2948 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_order, Type: Node->getKind()) << ")";
2949}
2950
2951void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
2952 if (!Node->varlist_empty()) {
2953 OS << "inclusive";
2954 VisitOMPClauseList(Node, StartSym: '(');
2955 OS << ")";
2956 }
2957}
2958
2959void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
2960 if (!Node->varlist_empty()) {
2961 OS << "exclusive";
2962 VisitOMPClauseList(Node, StartSym: '(');
2963 OS << ")";
2964 }
2965}
2966
2967void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
2968 OMPUsesAllocatorsClause *Node) {
2969 if (Node->getNumberOfAllocators() == 0)
2970 return;
2971 OS << "uses_allocators(";
2972 for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {
2973 OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);
2974 Data.Allocator->printPretty(OS, Helper: nullptr, Policy);
2975 if (Data.AllocatorTraits) {
2976 OS << "(";
2977 Data.AllocatorTraits->printPretty(OS, Helper: nullptr, Policy);
2978 OS << ")";
2979 }
2980 if (I < E - 1)
2981 OS << ",";
2982 }
2983 OS << ")";
2984}
2985
2986void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
2987 if (Node->varlist_empty())
2988 return;
2989 OS << "affinity";
2990 char StartSym = '(';
2991 if (Expr *Modifier = Node->getModifier()) {
2992 OS << "(";
2993 Modifier->printPretty(OS, Helper: nullptr, Policy);
2994 OS << " :";
2995 StartSym = ' ';
2996 }
2997 VisitOMPClauseList(Node, StartSym);
2998 OS << ")";
2999}
3000
3001void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
3002 OS << "filter(";
3003 Node->getThreadID()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
3004 OS << ")";
3005}
3006
3007void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
3008 OS << "bind("
3009 << getOpenMPSimpleClauseTypeName(Kind: OMPC_bind, Type: unsigned(Node->getBindKind()))
3010 << ")";
3011}
3012
3013void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
3014 OMPXDynCGroupMemClause *Node) {
3015 OS << "ompx_dyn_cgroup_mem(";
3016 Node->getSize()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
3017 OS << ")";
3018}
3019
3020void OMPClausePrinter::VisitOMPDynGroupprivateClause(
3021 OMPDynGroupprivateClause *Node) {
3022 OS << "dyn_groupprivate(";
3023 if (Node->getDynGroupprivateModifier() != OMPC_DYN_GROUPPRIVATE_unknown) {
3024 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_dyn_groupprivate,
3025 Type: Node->getDynGroupprivateModifier());
3026 if (Node->getDynGroupprivateFallbackModifier() !=
3027 OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown) {
3028 OS << ", ";
3029 OS << getOpenMPSimpleClauseTypeName(
3030 Kind: OMPC_dyn_groupprivate, Type: Node->getDynGroupprivateFallbackModifier());
3031 }
3032 OS << ": ";
3033 }
3034 Node->getSize()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
3035 OS << ')';
3036}
3037
3038void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {
3039 OS << "doacross(";
3040 OpenMPDoacrossClauseModifier DepType = Node->getDependenceType();
3041
3042 switch (DepType) {
3043 case OMPC_DOACROSS_source:
3044 OS << "source:";
3045 break;
3046 case OMPC_DOACROSS_sink:
3047 OS << "sink:";
3048 break;
3049 case OMPC_DOACROSS_source_omp_cur_iteration:
3050 OS << "source: omp_cur_iteration";
3051 break;
3052 case OMPC_DOACROSS_sink_omp_cur_iteration:
3053 OS << "sink: omp_cur_iteration - 1";
3054 break;
3055 default:
3056 llvm_unreachable("unknown docaross modifier");
3057 }
3058 VisitOMPClauseList(Node, StartSym: ' ');
3059 OS << ")";
3060}
3061
3062void OMPClausePrinter::VisitOMPXAttributeClause(OMPXAttributeClause *Node) {
3063 OS << "ompx_attribute(";
3064 bool IsFirst = true;
3065 for (auto &Attr : Node->getAttrs()) {
3066 if (!IsFirst)
3067 OS << ", ";
3068 Attr->printPretty(OS, Policy);
3069 IsFirst = false;
3070 }
3071 OS << ")";
3072}
3073
3074void OMPClausePrinter::VisitOMPXBareClause(OMPXBareClause *Node) {
3075 OS << "ompx_bare";
3076}
3077
3078void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
3079 VariantMatchInfo &VMI) const {
3080 for (const OMPTraitSet &Set : Sets) {
3081 for (const OMPTraitSelector &Selector : Set.Selectors) {
3082
3083 // User conditions are special as we evaluate the condition here.
3084 if (Selector.Kind == TraitSelector::user_condition) {
3085 assert(Selector.ScoreOrCondition &&
3086 "Ill-formed user condition, expected condition expression!");
3087 assert(Selector.Properties.size() == 1 &&
3088 Selector.Properties.front().Kind ==
3089 TraitProperty::user_condition_unknown &&
3090 "Ill-formed user condition, expected unknown trait property!");
3091
3092 if (std::optional<APSInt> CondVal =
3093 Selector.ScoreOrCondition->getIntegerConstantExpr(Ctx: ASTCtx))
3094 VMI.addTrait(Property: CondVal->isZero() ? TraitProperty::user_condition_false
3095 : TraitProperty::user_condition_true,
3096 RawString: "<condition>");
3097 else
3098 VMI.addTrait(Property: TraitProperty::user_condition_false, RawString: "<condition>");
3099 continue;
3100 }
3101
3102 std::optional<llvm::APSInt> Score;
3103 llvm::APInt *ScorePtr = nullptr;
3104 if (Selector.ScoreOrCondition) {
3105 if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(Ctx: ASTCtx)))
3106 ScorePtr = &*Score;
3107 else
3108 VMI.addTrait(Property: TraitProperty::user_condition_false,
3109 RawString: "<non-constant-score>");
3110 }
3111
3112 for (const OMPTraitProperty &Property : Selector.Properties)
3113 VMI.addTrait(Set: Set.Kind, Property: Property.Kind, RawString: Property.RawString, Score: ScorePtr);
3114
3115 if (Set.Kind != TraitSet::construct)
3116 continue;
3117
3118 // TODO: This might not hold once we implement SIMD properly.
3119 assert(Selector.Properties.size() == 1 &&
3120 Selector.Properties.front().Kind ==
3121 getOpenMPContextTraitPropertyForSelector(
3122 Selector.Kind) &&
3123 "Ill-formed construct selector!");
3124 }
3125 }
3126}
3127
3128void OMPTraitInfo::print(llvm::raw_ostream &OS,
3129 const PrintingPolicy &Policy) const {
3130 bool FirstSet = true;
3131 for (const OMPTraitSet &Set : Sets) {
3132 if (!FirstSet)
3133 OS << ", ";
3134 FirstSet = false;
3135 OS << getOpenMPContextTraitSetName(Kind: Set.Kind) << "={";
3136
3137 bool FirstSelector = true;
3138 for (const OMPTraitSelector &Selector : Set.Selectors) {
3139 if (!FirstSelector)
3140 OS << ", ";
3141 FirstSelector = false;
3142 OS << getOpenMPContextTraitSelectorName(Kind: Selector.Kind);
3143
3144 bool AllowsTraitScore = false;
3145 bool RequiresProperty = false;
3146 isValidTraitSelectorForTraitSet(
3147 Selector: Selector.Kind, Set: Set.Kind, AllowsTraitScore, RequiresProperty);
3148
3149 if (!RequiresProperty)
3150 continue;
3151
3152 OS << "(";
3153 if (Selector.Kind == TraitSelector::user_condition) {
3154 if (Selector.ScoreOrCondition)
3155 Selector.ScoreOrCondition->printPretty(OS, Helper: nullptr, Policy);
3156 else
3157 OS << "...";
3158 } else {
3159
3160 if (Selector.ScoreOrCondition) {
3161 OS << "score(";
3162 Selector.ScoreOrCondition->printPretty(OS, Helper: nullptr, Policy);
3163 OS << "): ";
3164 }
3165
3166 bool FirstProperty = true;
3167 for (const OMPTraitProperty &Property : Selector.Properties) {
3168 if (!FirstProperty)
3169 OS << ", ";
3170 FirstProperty = false;
3171 OS << getOpenMPContextTraitPropertyName(Kind: Property.Kind,
3172 RawString: Property.RawString);
3173 }
3174 }
3175 OS << ")";
3176 }
3177 OS << "}";
3178 }
3179}
3180
3181std::string OMPTraitInfo::getMangledName() const {
3182 std::string MangledName;
3183 llvm::raw_string_ostream OS(MangledName);
3184 for (const OMPTraitSet &Set : Sets) {
3185 OS << '$' << 'S' << unsigned(Set.Kind);
3186 for (const OMPTraitSelector &Selector : Set.Selectors) {
3187
3188 bool AllowsTraitScore = false;
3189 bool RequiresProperty = false;
3190 isValidTraitSelectorForTraitSet(
3191 Selector: Selector.Kind, Set: Set.Kind, AllowsTraitScore, RequiresProperty);
3192 OS << '$' << 's' << unsigned(Selector.Kind);
3193
3194 if (!RequiresProperty ||
3195 Selector.Kind == TraitSelector::user_condition)
3196 continue;
3197
3198 for (const OMPTraitProperty &Property : Selector.Properties)
3199 OS << '$' << 'P'
3200 << getOpenMPContextTraitPropertyName(Kind: Property.Kind,
3201 RawString: Property.RawString);
3202 }
3203 }
3204 return MangledName;
3205}
3206
3207OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
3208 unsigned long U;
3209 do {
3210 if (!MangledName.consume_front(Prefix: "$S"))
3211 break;
3212 if (MangledName.consumeInteger(Radix: 10, Result&: U))
3213 break;
3214 Sets.push_back(Elt: OMPTraitSet());
3215 OMPTraitSet &Set = Sets.back();
3216 Set.Kind = TraitSet(U);
3217 do {
3218 if (!MangledName.consume_front(Prefix: "$s"))
3219 break;
3220 if (MangledName.consumeInteger(Radix: 10, Result&: U))
3221 break;
3222 Set.Selectors.push_back(Elt: OMPTraitSelector());
3223 OMPTraitSelector &Selector = Set.Selectors.back();
3224 Selector.Kind = TraitSelector(U);
3225 do {
3226 if (!MangledName.consume_front(Prefix: "$P"))
3227 break;
3228 Selector.Properties.push_back(Elt: OMPTraitProperty());
3229 OMPTraitProperty &Property = Selector.Properties.back();
3230 std::pair<StringRef, StringRef> PropRestPair = MangledName.split(Separator: '$');
3231 Property.RawString = PropRestPair.first;
3232 Property.Kind = getOpenMPContextTraitPropertyKind(
3233 Set: Set.Kind, Selector: Selector.Kind, Str: PropRestPair.first);
3234 MangledName = MangledName.drop_front(N: PropRestPair.first.size());
3235 } while (true);
3236 } while (true);
3237 } while (true);
3238}
3239
3240llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
3241 const OMPTraitInfo &TI) {
3242 LangOptions LO;
3243 PrintingPolicy Policy(LO);
3244 TI.print(OS, Policy);
3245 return OS;
3246}
3247llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
3248 const OMPTraitInfo *TI) {
3249 return TI ? OS << *TI : OS;
3250}
3251
3252TargetOMPContext::TargetOMPContext(
3253 ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
3254 const FunctionDecl *CurrentFunctionDecl,
3255 ArrayRef<llvm::omp::TraitProperty> ConstructTraits, int DeviceNum)
3256 : OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
3257 ASTCtx.getTargetInfo().getTriple(),
3258 ASTCtx.getLangOpts().OMPTargetTriples.empty()
3259 ? llvm::Triple()
3260 : ASTCtx.getLangOpts().OMPTargetTriples[0],
3261 DeviceNum),
3262 FeatureValidityCheck([&](StringRef FeatureName) {
3263 return ASTCtx.getTargetInfo().isValidFeatureName(Feature: FeatureName);
3264 }),
3265 DiagUnknownTrait(std::move(DiagUnknownTrait)) {
3266 ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);
3267
3268 for (llvm::omp::TraitProperty Property : ConstructTraits)
3269 addTrait(Property);
3270}
3271
3272bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
3273 auto It = FeatureMap.find(Key: RawString);
3274 if (It != FeatureMap.end())
3275 return It->second;
3276 if (!FeatureValidityCheck(RawString))
3277 DiagUnknownTrait(RawString);
3278 return false;
3279}
3280