clang 24.0.0git
OpenMPClause.cpp
Go to the documentation of this file.
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
15#include "clang/AST/Attr.h"
16#include "clang/AST/Decl.h"
18#include "clang/AST/Expr.h"
20#include "clang/Basic/LLVM.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
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
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
62 auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
63 return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
64}
65
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
194 auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));
195 return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
196}
197
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.
303 if (!S)
304 return nullptr;
305 if (auto *DS = dyn_cast<DeclStmt>(S)) {
306 assert(DS->isSingleDecl() && "Only single expression must be captured.");
307 if (auto *OED = dyn_cast<OMPCapturedExprDecl>(DS->getSingleDecl()))
308 return OED->getInitAddress();
309 }
310 return nullptr;
311}
312
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
326 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
327 return child_range(C, C + 1);
328 return child_range(&Grainsize, &Grainsize + 1);
329}
330
332 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
333 return child_range(C, C + 1);
334 return child_range(&NumTasks, &NumTasks + 1);
335}
336
342
344 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
345 return child_range(C, C + 1);
346 return child_range(&Priority, &Priority + 1);
347}
348
350 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
351 return child_range(C, C + 1);
352 return children();
353}
354
356 if (Stmt **C = getAddrOfExprAsWritten(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(totalSizeToAlloc<Expr *>(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(I, nullptr);
371 Clause->setLoopCounter(I, nullptr);
372 }
373 return Clause;
374}
375
376OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C,
377 unsigned NumLoops) {
378 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
379 auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
380 for (unsigned I = 0; I < NumLoops; ++I) {
381 Clause->setLoopNumIterations(I, nullptr);
382 Clause->setLoopCounter(I, 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(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,
422 void *Mem =
423 C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
424 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(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
439 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(VL, 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(totalSizeToAlloc<Expr *>(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(totalSizeToAlloc<Expr *>(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(VL, 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(VL, getPrivateCopies().end());
480}
481
482OMPFirstprivateClause *
483OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
484 SourceLocation LParenLoc, SourceLocation EndLoc,
486 ArrayRef<Expr *> InitVL, Stmt *PreInit) {
487 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(PreInit);
494 return Clause;
495}
496
497OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
498 unsigned N) {
499 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(PrivateCopies, 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(SrcExprs, 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(DstExprs, 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(AssignmentOps, getDestinationExprs().end());
528}
529
530OMPLastprivateClause *OMPLastprivateClause::Create(
531 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
533 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
535 SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {
536 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(PreInit);
544 Clause->setPostUpdateExpr(PostUpdate);
545 return Clause;
546}
547
548OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
549 unsigned N) {
550 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(totalSizeToAlloc<Expr *>(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(totalSizeToAlloc<Expr *>(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(PL, 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(IL, 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(UL, 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(FL, 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(UE, 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,
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(totalSizeToAlloc<Expr *>(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(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
622 nullptr);
623 std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
624 nullptr);
625 std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),
626 nullptr);
627 Clause->setStep(Step);
628 Clause->setCalcStep(CalcStep);
629 Clause->setPreInitStmt(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(totalSizeToAlloc<Expr *>(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(getUsedExprs(), nullptr)));
647}
648
649OMPAlignedClause *
651 SourceLocation LParenLoc, SourceLocation ColonLoc,
652 SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
653 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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
662 unsigned NumVars) {
663 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(SrcExprs, 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(DstExprs, 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(AssignmentOps, getDestinationExprs().end());
693}
694
695OMPCopyinClause *OMPCopyinClause::Create(
696 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
698 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
699 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(totalSizeToAlloc<Expr *>(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(SrcExprs, 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(DstExprs, 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(AssignmentOps, getDestinationExprs().end());
733}
734
735OMPCopyprivateClause *OMPCopyprivateClause::Create(
736 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
738 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
739 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(totalSizeToAlloc<Expr *>(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(Privates, 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(LHSExprs, 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(RHSExprs, 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(ReductionOps, 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(Ops, 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(CopyArrayTemps, 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(CopyArrayElems, getInscanCopyArrayTemps().end());
806}
807
808OMPReductionClause *OMPReductionClause::Create(
809 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
810 SourceLocation ModifierLoc, SourceLocation EndLoc, SourceLocation ColonLoc,
812 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
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(totalSizeToAlloc<Expr *, bool>(
820 (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size(), 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(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,
850 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, bool>(
851 (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N, 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(Privates, 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(LHSExprs, 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(RHSExprs, 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(ReductionOps, getRHSExprs().end());
882}
883
884OMPTaskReductionClause *OMPTaskReductionClause::Create(
885 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
887 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
889 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
890 Expr *PostUpdate) {
891 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(PreInit);
900 Clause->setPostUpdateExpr(PostUpdate);
901 return Clause;
902}
903
904OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
905 unsigned N) {
906 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(Privates, 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(LHSExprs, 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(RHSExprs, 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(ReductionOps, 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(TaskgroupDescriptors, getReductionOps().end());
943}
944
945OMPInReductionClause *OMPInReductionClause::Create(
946 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
948 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
950 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
951 ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
952 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(PreInit);
962 Clause->setPostUpdateExpr(PostUpdate);
963 return Clause;
964}
965
966OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
967 unsigned N) {
968 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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, Sizes.size());
978 Clause->setLocStart(StartLoc);
979 Clause->setLParenLoc(LParenLoc);
980 Clause->setLocEnd(EndLoc);
981 Clause->setSizesRefs(Sizes);
982 return Clause;
983}
984
986 unsigned NumSizes) {
987 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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, 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
1006 unsigned NumCounts) {
1007 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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, Args.size());
1017 Clause->setLocStart(StartLoc);
1018 Clause->setLParenLoc(LParenLoc);
1019 Clause->setLocEnd(EndLoc);
1020 Clause->setArgRefs(Args);
1021 return Clause;
1022}
1023
1025 unsigned NumLoops) {
1026 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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
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
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(totalSizeToAlloc<Expr *>(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
1098 unsigned N) {
1099 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(totalSizeToAlloc<Expr *>(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(totalSizeToAlloc<Expr *>(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
1131 return new (C) OMPDepobjClause();
1132}
1133
1136 SourceLocation LParenLoc, SourceLocation EndLoc,
1137 DependDataTy Data, Expr *DepModifier,
1138 ArrayRef<Expr *> VL, unsigned NumLoops) {
1139 void *Mem = C.Allocate(
1140 totalSizeToAlloc<Expr *>(VL.size() + /*depend-modifier*/ 1 + NumLoops),
1141 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(I, nullptr);
1152 return Clause;
1153}
1154
1155OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,
1156 unsigned NumLoops) {
1157 void *Mem =
1158 C.Allocate(totalSizeToAlloc<Expr *>(N + /*depend-modifier*/ 1 + NumLoops),
1159 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(getVarRefs().end(), NumLoop + 1);
1170 *It = Cnt;
1171}
1172
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(getVarRefs().end(), 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(getVarRefs().end(), NumLoop + 1);
1190 return *It;
1191}
1192
1193void OMPDependClause::setModifier(Expr *DepModifier) {
1194 *getVarRefs().end() = DepModifier;
1195}
1196Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); }
1197
1199 MappableExprComponentListsRef ComponentLists) {
1200 unsigned TotalNum = 0u;
1201 for (auto &C : ComponentLists)
1202 TotalNum += C.size();
1203 return TotalNum;
1204}
1205
1207 ArrayRef<const ValueDecl *> Declarations) {
1209 for (const ValueDecl *D : Declarations) {
1210 const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
1211 UniqueDecls.insert(VD);
1212 }
1213 return UniqueDecls.size();
1214}
1215
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>(Exp))
1225
1226 // For array-sections, we need to find the type of one element of
1227 // the section.
1228 const auto *OASE = cast<ArraySectionExpr>(Exp);
1229
1230 QualType BaseType = ArraySectionExpr::getBaseOriginalType(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>>
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(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>(CurExpr))
1273 continue;
1274
1275 // Keep going until we reach an Expr of pointer type.
1276 QualType CurType = getComponentExprElementType(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
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) {
1296 Sizes.NumVars = Vars.size();
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 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1314 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1316 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
1332 const OMPMappableExprListSizeTy &Sizes) {
1333 void *Mem = C.Allocate(
1334 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1336 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1338 Sizes.NumComponents));
1339 OMPMapClause *Clause = new (Mem) OMPMapClause(Sizes);
1340 Clause->setIteratorModifier(nullptr);
1341 return Clause;
1342}
1343
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) {
1352 Sizes.NumVars = Vars.size();
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 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1370 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1372 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
1385 const OMPMappableExprListSizeTy &Sizes) {
1386 void *Mem = C.Allocate(
1387 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1389 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1391 Sizes.NumComponents));
1392 OMPToClause *Clause = new (Mem) OMPToClause(Sizes);
1393 Clause->setIteratorModifier(nullptr);
1394 return Clause;
1395}
1396
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) {
1405 Sizes.NumVars = Vars.size();
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 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1423 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1425 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
1440 const OMPMappableExprListSizeTy &Sizes) {
1441 void *Mem = C.Allocate(
1442 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1444 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1446 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(VL, 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(VL, getPrivateCopies().end());
1462}
1463
1464OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
1465 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1467 ArrayRef<ValueDecl *> Declarations,
1468 MappableExprComponentListsRef ComponentLists,
1469 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
1470 SourceLocation FallbackModifierLoc) {
1472 Sizes.NumVars = Vars.size();
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 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1490 3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1492 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
1506 const OMPMappableExprListSizeTy &Sizes) {
1507 void *Mem = C.Allocate(
1508 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1510 3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1512 Sizes.NumComponents));
1513 return new (Mem) OMPUseDevicePtrClause(Sizes);
1514}
1515
1518 ArrayRef<Expr *> Vars,
1519 ArrayRef<ValueDecl *> Declarations,
1520 MappableExprComponentListsRef ComponentLists) {
1522 Sizes.NumVars = Vars.size();
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 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1540 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1542 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
1553 const OMPMappableExprListSizeTy &Sizes) {
1554 void *Mem = C.Allocate(
1555 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1557 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1559 Sizes.NumComponents));
1560 return new (Mem) OMPUseDeviceAddrClause(Sizes);
1561}
1562
1565 ArrayRef<Expr *> Vars,
1566 ArrayRef<ValueDecl *> Declarations,
1567 MappableExprComponentListsRef ComponentLists) {
1569 Sizes.NumVars = Vars.size();
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 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1587 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1589 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
1600 const OMPMappableExprListSizeTy &Sizes) {
1601 void *Mem = C.Allocate(
1602 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1604 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1606 Sizes.NumComponents));
1607 return new (Mem) OMPIsDevicePtrClause(Sizes);
1608}
1609
1612 ArrayRef<Expr *> Vars,
1613 ArrayRef<ValueDecl *> Declarations,
1614 MappableExprComponentListsRef ComponentLists) {
1616 Sizes.NumVars = Vars.size();
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 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1634 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1636 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
1647 const OMPMappableExprListSizeTy &Sizes) {
1648 void *Mem = C.Allocate(
1649 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1651 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1653 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(totalSizeToAlloc<Expr *>(2 * VL.size()));
1664 auto *Clause =
1665 new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
1666 Clause->setVarRefs(VL);
1667 return Clause;
1668}
1669
1671 unsigned N) {
1672 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
1673 return new (Mem) OMPNontemporalClause(N);
1674}
1675
1677 assert(VL.size() == varlist_size() && "Number of private references is not "
1678 "the same as the preallocated buffer");
1679 llvm::copy(VL, 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(totalSizeToAlloc<Expr *>(VL.size()));
1688 auto *Clause =
1689 new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1690 Clause->setVarRefs(VL);
1691 return Clause;
1692}
1693
1695 unsigned N) {
1696 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(totalSizeToAlloc<Expr *>(VL.size()));
1706 auto *Clause =
1707 new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1708 Clause->setVarRefs(VL);
1709 return Clause;
1710}
1711
1713 unsigned N) {
1714 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1715 return new (Mem) OMPExclusiveClause(N);
1716}
1717
1718void OMPUsesAllocatorsClause::setAllocatorsData(
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)] =
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
1745 Data.Allocator =
1746 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1747 static_cast<int>(ExprOffsets::Allocator)];
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
1763 SourceLocation LParenLoc, SourceLocation EndLoc,
1765 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
1766 static_cast<int>(ExprOffsets::Total) * Data.size(),
1767 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
1776 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
1777 static_cast<int>(ExprOffsets::Total) * N,
1778 static_cast<int>(ParenLocsOffsets::Total) * N));
1779 return new (Mem) OMPUsesAllocatorsClause(N);
1780}
1781
1784 SourceLocation LParenLoc, SourceLocation ColonLoc,
1785 SourceLocation EndLoc, Expr *Modifier,
1786 ArrayRef<Expr *> Locators) {
1787 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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
1796 unsigned N) {
1797 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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 totalSizeToAlloc<Expr *, unsigned>(1 + NumPrefs + NumAttrs, 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
1838 unsigned NumPrefs,
1839 unsigned NumAttrs) {
1840 void *Mem = C.Allocate(
1841 totalSizeToAlloc<Expr *, unsigned>(1 + NumPrefs + NumAttrs, 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(Attrs, getTrailingObjects<Expr *>() + varlist_size());
1861}
1862
1863OMPBindClause *
1865 SourceLocation KLoc, SourceLocation StartLoc,
1866 SourceLocation LParenLoc, SourceLocation EndLoc) {
1867 return new (C) OMPBindClause(K, KLoc, StartLoc, LParenLoc, EndLoc);
1868}
1869
1871 return new (C) OMPBindClause();
1872}
1873
1876 SourceLocation LParenLoc, SourceLocation EndLoc,
1878 SourceLocation DepLoc, SourceLocation ColonLoc,
1879 ArrayRef<Expr *> VL, unsigned NumLoops) {
1880 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + NumLoops),
1881 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(I, nullptr);
1890 return Clause;
1891}
1892
1894 unsigned N,
1895 unsigned NumLoops) {
1896 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + NumLoops),
1897 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(getVarRefs().end(), NumLoop);
1904 *It = Cnt;
1905}
1906
1908 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1909 auto *It = std::next(getVarRefs().end(), 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(getVarRefs().end(), NumLoop);
1916 return *It;
1917}
1918
1919OMPAbsentClause *OMPAbsentClause::Create(const ASTContext &C,
1921 SourceLocation Loc,
1922 SourceLocation LLoc,
1923 SourceLocation RLoc) {
1924 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(DKVec.size()),
1925 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(totalSizeToAlloc<OpenMPDirectiveKind>(K),
1933 alignof(OMPAbsentClause));
1934 return new (Mem) OMPAbsentClause(K);
1935}
1936
1937OMPContainsClause *OMPContainsClause::Create(
1940 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(DKVec.size()),
1941 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(totalSizeToAlloc<OpenMPDirectiveKind>(K),
1950 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,
1958 Expr *ModifierExpr, SourceLocation ModifierLoc, Stmt *PreInit) {
1959 // Reserve space for an extra modifier expression.
1960 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(PreInit, CaptureRegion);
1968 return Clause;
1969}
1970
1972 unsigned N) {
1973 // Reserve space for an extra modifier expression.
1974 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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,
1982 Expr *ModifierExpr, SourceLocation ModifierLoc, Stmt *PreInit) {
1983 // Reserve space for an extra modifier expression.
1984 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(PreInit, CaptureRegion);
1992 return Clause;
1993}
1994
1996 unsigned N) {
1997 // Reserve space for an extra modifier expression.
1998 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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(Node->getNameModifier(), Version) << ": ";
2010 Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
2011 OS << ")";
2012}
2013
2014void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
2015 OS << "final(";
2016 Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
2017 OS << ")";
2018}
2019
2020void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
2021 OS << "num_threads(";
2023 if (Modifier != OMPC_NUMTHREADS_unknown) {
2024 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
2025 << ": ";
2026 }
2027 Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
2028 OS << ")";
2029}
2030
2031void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
2032 OS << "align(";
2033 Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
2034 OS << ")";
2035}
2036
2037void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
2038 OS << "safelen(";
2039 Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
2040 OS << ")";
2041}
2042
2043void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
2044 OS << "simdlen(";
2045 Node->getSimdlen()->printPretty(OS, nullptr, Policy, 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, nullptr, Policy, 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(llvm::seq<unsigned>(Refs.size()), OS, [&](unsigned I) {
2066 if (FillIdx && I == *FillIdx)
2067 OS << "omp_fill";
2068 else
2069 Refs[I]->printPretty(OS, nullptr, Policy, 0);
2070 });
2071 OS << ")";
2072}
2073
2074void OMPClausePrinter::VisitOMPPermutationClause(OMPPermutationClause *Node) {
2075 OS << "permutation(";
2076 llvm::interleaveComma(Node->getArgsRefs(), OS, [&](const Expr *E) {
2077 E->printPretty(OS, nullptr, Policy, 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, nullptr, Policy, 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, nullptr, Policy, 0);
2103 OS << ",";
2104 Count->printPretty(OS, nullptr, Policy, 0);
2105 OS << ")";
2106 }
2107}
2108
2109void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
2110 OS << "allocator(";
2111 Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
2112 OS << ")";
2113}
2114
2115void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
2116 OS << "collapse(";
2117 Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
2118 OS << ")";
2119}
2120
2121void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
2122 OS << "detach(";
2123 Node->getEventHandler()->printPretty(OS, nullptr, Policy, 0);
2124 OS << ")";
2125}
2126
2127void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
2128 OS << "default("
2129 << getOpenMPSimpleClauseTypeName(OMPC_default,
2130 unsigned(Node->getDefaultKind()));
2131 if (Version >= 60 && Node->getDefaultVC() != OMPC_DEFAULT_VC_all) {
2132 OS << ":"
2134 }
2135
2136 OS << ")";
2137}
2138
2139void OMPClausePrinter::VisitOMPThreadsetClause(OMPThreadsetClause *Node) {
2140 OS << "threadset("
2141 << getOpenMPSimpleClauseTypeName(OMPC_threadset,
2142 unsigned(Node->getThreadsetKind()))
2143 << ")";
2144}
2145
2146void OMPClausePrinter::VisitOMPTransparentClause(OMPTransparentClause *Node) {
2147 OS << "transparent(";
2148 if (Node->getImpexType())
2149 Node->getImpexType()->printPretty(OS, nullptr, Policy, 0);
2150 else
2151 OS << "omp_impex";
2152 OS << ")";
2153}
2154
2155void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
2156 OS << "proc_bind("
2157 << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
2158 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(OMPC_atomic_default_mem_order,
2184 Node->getAtomicDefaultMemOrderKind())
2185 << ")";
2186}
2187
2188void OMPClausePrinter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {
2189 OS << "self_maps";
2190}
2191
2192void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
2193 OS << "at(" << getOpenMPSimpleClauseTypeName(OMPC_at, Node->getAtKind())
2194 << ")";
2195}
2196
2197void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
2198 OS << "severity("
2199 << getOpenMPSimpleClauseTypeName(OMPC_severity, Node->getSeverityKind())
2200 << ")";
2201}
2202
2203void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
2204 OS << "message(";
2205 if (Expr *E = Node->getMessageString())
2206 E->printPretty(OS, 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(OMPC_schedule,
2214 Node->getFirstScheduleModifier());
2215 if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
2216 OS << ", ";
2217 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
2218 Node->getSecondScheduleModifier());
2219 }
2220 OS << ": ";
2221 }
2222 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
2223 if (auto *E = Node->getChunkSize()) {
2224 OS << ", ";
2225 E->printPretty(OS, 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, nullptr, Policy, 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, nullptr, Policy, 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(Node->getClauseKind(),
2269 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 << "(";
2287 Node->getClauseKind(), 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, Version);
2299 First = false;
2300 }
2301 OS << ")";
2302}
2303
2304void OMPClausePrinter::VisitOMPHoldsClause(OMPHoldsClause *Node) {
2305 OS << "holds(";
2306 Node->getExpr()->printPretty(OS, nullptr, Policy, 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, 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(Node->getClauseKind(), Modifier)
2373 << ": ";
2374 }
2375 Node->getDevice()->printPretty(OS, nullptr, Policy, 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, nullptr, Policy, 0);
2387 if (Node->getModifier() == OMPC_NUMTEAMS_dims)
2388 OS << ")";
2389 VisitOMPClauseList(Node, ':');
2390 } else {
2391 VisitOMPClauseList(Node, '(');
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, nullptr, Policy, 0);
2403 OS << ")";
2404 VisitOMPClauseList(Node, ':');
2405 } else {
2406 VisitOMPClauseList(Node, '(');
2407 }
2408 OS << ")";
2409 }
2410}
2411
2412void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
2413 OS << "priority(";
2414 Node->getPriority()->printPretty(OS, nullptr, Policy, 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(Node->getClauseKind(), Modifier)
2423 << ": ";
2424 }
2425 Node->getGrainsize()->printPretty(OS, nullptr, Policy, 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(Node->getClauseKind(), Modifier)
2434 << ": ";
2435 }
2436 Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
2437 OS << ")";
2438}
2439
2440void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
2441 OS << "hint(";
2442 Node->getHint()->printPretty(OS, nullptr, Policy, 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(Node->prefs(), OS, [&](OMPInitClause::PrefView P) {
2453 OS << "{";
2454 if (P.Fr) {
2455 OS << "fr(";
2456 P.Fr->printPretty(OS, nullptr, Policy);
2457 OS << ")";
2458 if (!P.Attrs.empty())
2459 OS << ", ";
2460 }
2461 if (!P.Attrs.empty()) {
2462 OS << "attr(";
2463 llvm::interleaveComma(P.Attrs, OS, [&](const Expr *A) {
2464 A->printPretty(OS, nullptr, Policy);
2465 });
2466 OS << ")";
2467 }
2468 OS << "}";
2469 });
2470 } else {
2471 llvm::interleave(
2472 Node->prefs(), OS,
2473 [&](OMPInitClause::PrefView P) {
2474 if (P.Fr)
2475 P.Fr->printPretty(OS, nullptr, Policy);
2476 },
2477 ",");
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, nullptr, Policy);
2490 OS << ")";
2491}
2492
2493void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
2494 OS << "use(";
2495 Node->getInteropVar()->printPretty(OS, 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, 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, nullptr, Policy, 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, nullptr, Policy, 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(Node->getClauseKind(), FirstAllocMod);
2568 OS << "(";
2569 }
2570 FirstModifier->printPretty(OS, nullptr, Policy, 0);
2571 if (!FirstUnknown)
2572 OS << ")";
2573 if (SecondModifier) {
2574 OS << ", ";
2575 if (!SecondUnknown) {
2577 SecondAllocMod);
2578 OS << "(";
2579 }
2580 SecondModifier->printPretty(OS, nullptr, Policy, 0);
2581 if (!SecondUnknown)
2582 OS << ")";
2583 }
2584 OS << ":";
2585 VisitOMPClauseList(Node, ' ');
2586 } else {
2587 // No modifiers. Just print the variable list.
2588 VisitOMPClauseList(Node, '(');
2589 }
2590 OS << ")";
2591}
2592
2593void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
2594 if (!Node->varlist_empty()) {
2595 OS << "private";
2596 VisitOMPClauseList(Node, '(');
2597 OS << ")";
2598 }
2599}
2600
2601void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
2602 if (!Node->varlist_empty()) {
2603 OS << "firstprivate";
2604 VisitOMPClauseList(Node, '(');
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(OMPC_lastprivate, Node->getKind())
2616 << ":";
2617 }
2618 VisitOMPClauseList(Node, 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, '(');
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(OMPC_reduction, Node->getModifier())
2636 << ", ";
2638 Node->getQualifierLoc().getNestedNameSpecifier();
2640 Node->getNameInfo().getName().getCXXOverloadedOperator();
2641 if (!Qualifier && OOK != OO_None) {
2642 // Print reduction identifier in C format
2643 OS << getOperatorSpelling(OOK);
2644 } else {
2645 // Use C++ format
2646 Qualifier.print(OS, Policy);
2647 OS << Node->getNameInfo();
2648 }
2649 OS << ":";
2650 VisitOMPClauseList(Node, ' ');
2651 OS << ")";
2652 }
2653}
2654
2655void OMPClausePrinter::VisitOMPTaskReductionClause(
2656 OMPTaskReductionClause *Node) {
2657 if (!Node->varlist_empty()) {
2658 OS << "task_reduction(";
2660 Node->getQualifierLoc().getNestedNameSpecifier();
2662 Node->getNameInfo().getName().getCXXOverloadedOperator();
2663 if (!Qualifier && OOK != OO_None) {
2664 // Print reduction identifier in C format
2665 OS << getOperatorSpelling(OOK);
2666 } else {
2667 // Use C++ format
2668 Qualifier.print(OS, Policy);
2669 OS << Node->getNameInfo();
2670 }
2671 OS << ":";
2672 VisitOMPClauseList(Node, ' ');
2673 OS << ")";
2674 }
2675}
2676
2677void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
2678 if (!Node->varlist_empty()) {
2679 OS << "in_reduction(";
2681 Node->getQualifierLoc().getNestedNameSpecifier();
2683 Node->getNameInfo().getName().getCXXOverloadedOperator();
2684 if (!Qualifier && OOK != OO_None) {
2685 // Print reduction identifier in C format
2686 OS << getOperatorSpelling(OOK);
2687 } else {
2688 // Use C++ format
2689 Qualifier.print(OS, Policy);
2690 OS << Node->getNameInfo();
2691 }
2692 OS << ":";
2693 VisitOMPClauseList(Node, ' ');
2694 OS << ")";
2695 }
2696}
2697
2698void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
2699 if (!Node->varlist_empty()) {
2700 OS << "linear";
2701 VisitOMPClauseList(Node, '(');
2702 if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {
2703 OS << ": ";
2704 }
2705 if (Node->getModifierLoc().isValid()) {
2706 OS << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
2707 }
2708 if (Node->getStep() != nullptr) {
2709 if (Node->getModifierLoc().isValid()) {
2710 OS << ", ";
2711 }
2712 OS << "step(";
2713 Node->getStep()->printPretty(OS, nullptr, Policy, 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, '(');
2724 if (Node->getAlignment() != nullptr) {
2725 OS << ": ";
2726 Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
2727 }
2728 OS << ")";
2729 }
2730}
2731
2732void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
2733 if (!Node->varlist_empty()) {
2734 OS << "copyin";
2735 VisitOMPClauseList(Node, '(');
2736 OS << ")";
2737 }
2738}
2739
2740void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
2741 if (!Node->varlist_empty()) {
2742 OS << "copyprivate";
2743 VisitOMPClauseList(Node, '(');
2744 OS << ")";
2745 }
2746}
2747
2748void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
2749 if (!Node->varlist_empty()) {
2750 VisitOMPClauseList(Node, '(');
2751 OS << ")";
2752 }
2753}
2754
2755void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
2756 OS << "(";
2757 Node->getDepobj()->printPretty(OS, nullptr, Policy, 0);
2758 OS << ")";
2759}
2760
2761void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
2762 OS << "depend(";
2763 if (Expr *DepModifier = Node->getModifier()) {
2764 DepModifier->printPretty(OS, 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(Node->getClauseKind(), PrintKind);
2778 if (!Node->varlist_empty() || IsOmpAllMemory)
2779 OS << " :";
2780 VisitOMPClauseList(Node, ' ');
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, 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) {
2811 if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator) {
2812 PrintIterator(OS, Node, Policy);
2813 } else {
2815 Node->getMapTypeModifier(I));
2816 if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper)
2817 PrintMapper(OS, Node, Policy);
2818 }
2819 OS << ',';
2820 }
2821 }
2822 OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
2823 OS << ':';
2824 }
2825 VisitOMPClauseList(Node, ' ');
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 OMPC_dist_schedule, Node->getDistScheduleKind());
2874 if (auto *E = Node->getChunkSize()) {
2875 OS << ", ";
2876 E->printPretty(OS, nullptr, Policy);
2877 }
2878 OS << ")";
2879}
2880
2881void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
2882 OS << "defaultmap(";
2883 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
2884 Node->getDefaultmapModifier());
2886 OS << ": ";
2887 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
2888 Node->getDefaultmapKind());
2889 }
2890 OS << ")";
2891}
2892
2893void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
2894 if (!Node->varlist_empty()) {
2895 OS << "use_device_ptr";
2897 OS << "("
2898 << getOpenMPSimpleClauseTypeName(OMPC_use_device_ptr,
2899 Node->getFallbackModifier())
2900 << ":";
2901 VisitOMPClauseList(Node, ' ');
2902 } else {
2903 VisitOMPClauseList(Node, '(');
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, '(');
2914 OS << ")";
2915 }
2916}
2917
2918void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
2919 if (!Node->varlist_empty()) {
2920 OS << "is_device_ptr";
2921 VisitOMPClauseList(Node, '(');
2922 OS << ")";
2923 }
2924}
2925
2926void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {
2927 if (!Node->varlist_empty()) {
2928 OS << "has_device_addr";
2929 VisitOMPClauseList(Node, '(');
2930 OS << ")";
2931 }
2932}
2933
2934void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
2935 if (!Node->varlist_empty()) {
2936 OS << "nontemporal";
2937 VisitOMPClauseList(Node, '(');
2938 OS << ")";
2939 }
2940}
2941
2942void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
2943 OS << "order(";
2945 OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getModifier());
2946 OS << ": ";
2947 }
2948 OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind()) << ")";
2949}
2950
2951void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
2952 if (!Node->varlist_empty()) {
2953 OS << "inclusive";
2954 VisitOMPClauseList(Node, '(');
2955 OS << ")";
2956 }
2957}
2958
2959void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
2960 if (!Node->varlist_empty()) {
2961 OS << "exclusive";
2962 VisitOMPClauseList(Node, '(');
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, nullptr, Policy);
2975 if (Data.AllocatorTraits) {
2976 OS << "(";
2977 Data.AllocatorTraits->printPretty(OS, 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, 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, nullptr, Policy, 0);
3004 OS << ")";
3005}
3006
3007void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
3008 OS << "bind("
3009 << getOpenMPSimpleClauseTypeName(OMPC_bind, unsigned(Node->getBindKind()))
3010 << ")";
3011}
3012
3013void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
3014 OMPXDynCGroupMemClause *Node) {
3015 OS << "ompx_dyn_cgroup_mem(";
3016 Node->getSize()->printPretty(OS, nullptr, Policy, 0);
3017 OS << ")";
3018}
3019
3020void OMPClausePrinter::VisitOMPDynGroupprivateClause(
3021 OMPDynGroupprivateClause *Node) {
3022 OS << "dyn_groupprivate(";
3024 OS << getOpenMPSimpleClauseTypeName(OMPC_dyn_groupprivate,
3028 OS << ", ";
3030 OMPC_dyn_groupprivate, Node->getDynGroupprivateFallbackModifier());
3031 }
3032 OS << ": ";
3033 }
3034 Node->getSize()->printPretty(OS, nullptr, Policy, 0);
3035 OS << ')';
3036}
3037
3038void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {
3039 OS << "doacross(";
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, ' ');
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
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(ASTCtx))
3094 VMI.addTrait(CondVal->isZero() ? TraitProperty::user_condition_false
3095 : TraitProperty::user_condition_true,
3096 "<condition>");
3097 else
3098 VMI.addTrait(TraitProperty::user_condition_false, "<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(ASTCtx)))
3106 ScorePtr = &*Score;
3107 else
3108 VMI.addTrait(TraitProperty::user_condition_false,
3109 "<non-constant-score>");
3110 }
3111
3112 for (const OMPTraitProperty &Property : Selector.Properties)
3113 VMI.addTrait(Set.Kind, Property.Kind, Property.RawString, 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(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(Selector.Kind);
3143
3144 bool AllowsTraitScore = false;
3145 bool RequiresProperty = false;
3146 isValidTraitSelectorForTraitSet(
3147 Selector.Kind, 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, nullptr, Policy);
3156 else
3157 OS << "...";
3158 } else {
3159
3160 if (Selector.ScoreOrCondition) {
3161 OS << "score(";
3162 Selector.ScoreOrCondition->printPretty(OS, 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(Property.Kind,
3172 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.Kind, 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(Property.Kind,
3201 Property.RawString);
3202 }
3203 }
3204 return MangledName;
3205}
3206
3207OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
3208 unsigned long U;
3209 do {
3210 if (!MangledName.consume_front("$S"))
3211 break;
3212 if (MangledName.consumeInteger(10, U))
3213 break;
3214 Sets.push_back(OMPTraitSet());
3215 OMPTraitSet &Set = Sets.back();
3216 Set.Kind = TraitSet(U);
3217 do {
3218 if (!MangledName.consume_front("$s"))
3219 break;
3220 if (MangledName.consumeInteger(10, U))
3221 break;
3222 Set.Selectors.push_back(OMPTraitSelector());
3223 OMPTraitSelector &Selector = Set.Selectors.back();
3224 Selector.Kind = TraitSelector(U);
3225 do {
3226 if (!MangledName.consume_front("$P"))
3227 break;
3228 Selector.Properties.push_back(OMPTraitProperty());
3229 OMPTraitProperty &Property = Selector.Properties.back();
3230 std::pair<StringRef, StringRef> PropRestPair = MangledName.split('$');
3231 Property.RawString = PropRestPair.first;
3232 Property.Kind = getOpenMPContextTraitPropertyKind(
3233 Set.Kind, Selector.Kind, PropRestPair.first);
3234 MangledName = MangledName.drop_front(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
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(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(RawString);
3274 if (It != FeatureMap.end())
3275 return It->second;
3276 if (!FeatureValidityCheck(RawString))
3277 DiagUnknownTrait(RawString);
3278 return false;
3279}
Defines the clang::ASTContext interface.
This file defines OpenMP nodes for declarative directives.
unsigned IsFirst
Indicates that this is the first token of the file.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static StringRef getTriple(const Command &Job)
static Stmt ** getAddrOfExprAsWritten(Stmt *S)
Gets the address of the original, non-captured, expression used in the clause as the preinitializer.
static void PrintIterator(raw_ostream &OS, T *Node, const PrintingPolicy &Policy)
static void PrintMapper(raw_ostream &OS, T *Node, const PrintingPolicy &Policy)
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
This represents clause 'affinity' in the 'pragma omp task'-based directives.
static OMPAffinityClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Creates clause with a modifier a list of locator items.
Expr * getModifier()
Gets affinity modifier.
static OMPAffinityClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N locator items.
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
static OMPAlignedClause * CreateEmpty(const ASTContext &C, unsigned NumVars)
Creates an empty clause with the place for NumVars variables.
Expr * getAlignment()
Returns alignment.
static OMPBindClause * Create(const ASTContext &C, OpenMPBindClauseKind K, SourceLocation KLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'bind' clause with kind K ('teams', 'parallel', or 'thread').
static OMPBindClause * CreateEmpty(const ASTContext &C)
Build an empty 'bind' clause.
OpenMPBindClauseKind getBindKind() const
Returns kind of the clause.
Class that represents a component of a mappable expression. E.g. for an expression S....
static unsigned getUniqueDeclarationsTotalNumber(ArrayRef< const ValueDecl * > Declarations)
static unsigned getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists)
ArrayRef< MappableExprComponentList > MappableExprComponentListsRef
static std::pair< const Expr *, std::optional< size_t > > findAttachPtrExpr(MappableExprComponentListRef Components, OpenMPDirectiveKind CurDirKind)
Find the attach pointer expression from a list of mappable expression components.
static QualType getComponentExprElementType(const Expr *Exp)
Get the type of an element of a ComponentList Expr Exp.
ArrayRef< MappableComponent > MappableExprComponentListRef
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
static OMPCopyinClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
static OMPCopyprivateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
OpenMPDefaultmapClauseKind getDefaultmapKind() const
Get kind of the clause.
OpenMPDefaultmapClauseModifier getDefaultmapModifier() const
Get the modifier of the clause.
This represents implicit clause 'depend' for the 'pragma omp task' directive.
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, DependDataTy Data, Expr *DepModifier, ArrayRef< Expr * > VL, unsigned NumLoops)
Creates clause with a list of variables VL.
Expr * getModifier()
Return optional depend modifier.
Expr * getLoopData(unsigned NumLoop)
Get the loop data.
void setLoopData(unsigned NumLoop, Expr *Cnt)
Set the loop data for the depend clauses with 'sink|source' kind of dependency.
static OMPDependClause * CreateEmpty(const ASTContext &C, unsigned N, unsigned NumLoops)
Creates an empty clause with N variables.
OpenMPDependClauseKind getDependencyKind() const
Get dependency type.
static OMPDepobjClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Depobj)
Creates clause.
Expr * getDepobj()
Returns depobj expression associated with the clause.
static OMPDepobjClause * CreateEmpty(const ASTContext &C)
Creates an empty clause.
Expr * getInteropVar() const
Returns the interop variable.
Expr * getEventHandler() const
Returns event-handler expression.
This represents 'device' clause in the 'pragma omp ...' directive.
OpenMPDeviceClauseModifier getModifier() const
Gets modifier.
Expr * getDevice()
Return device number.
This represents 'dist_schedule' clause in the 'pragma omp ...' directive.
Expr * getChunkSize()
Get chunk size.
OpenMPDistScheduleClauseKind getDistScheduleKind() const
Get kind of the clause.
This represents the 'doacross' clause for the 'pragma omp ordered' directive.
void setLoopData(unsigned NumLoop, Expr *Cnt)
Set the loop data.
OpenMPDoacrossClauseModifier getDependenceType() const
Get dependence type.
Expr * getLoopData(unsigned NumLoop)
Get the loop data.
static OMPDoacrossClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VL, unsigned NumLoops)
Creates clause with a list of expressions VL.
static OMPDoacrossClause * CreateEmpty(const ASTContext &C, unsigned N, unsigned NumLoops)
Creates an empty clause with N expressions.
This represents 'dyn_groupprivate' clause in 'pragma omp target ...' and 'pragma omp teams ....
Expr * getSize()
Get size.
OpenMPDynGroupprivateClauseFallbackModifier getDynGroupprivateFallbackModifier() const
Get the second modifier of the clause.
OpenMPDynGroupprivateClauseModifier getDynGroupprivateModifier() const
Get the first modifier of the clause.
static OMPExclusiveClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
static OMPExclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This represents 'filter' clause in the 'pragma omp ...' directive.
Expr * getThreadID() const
Return thread identifier.
static OMPFlushClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This represents clause 'from' in the 'pragma omp ...' directives.
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, Expr *IteratorExpr, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
static OMPFromClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
This represents 'grainsize' clause in the 'pragma omp ...' directive.
OpenMPGrainsizeClauseModifier getModifier() const
Gets modifier.
Expr * getGrainsize() const
Return safe iteration space distance.
child_range used_children()
This represents clause 'has_device_ptr' in the 'pragma omp ...' directives.
static OMPHasDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPHasDeviceAddrClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
Expr * getHint() const
Returns number of threads.
static OMPInclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static OMPInclusiveClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
bool getIsTarget() const
Returns true is interop-type 'target' is used.
static OMPInitClause * CreateEmpty(const ASTContext &C, unsigned NumPrefs, unsigned NumAttrs)
Creates an empty clause sized for NumPrefs pref-specs and NumAttrs total attr() exprs across them.
bool hasPreferAttrs() const
Returns true if OMP 6.0 {fr/attr} syntax is used.
Expr * getInteropVar()
Returns the interop variable.
static OMPInitClause * Create(const ASTContext &C, Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Creates a fully specified clause.
bool getIsTargetSync() const
Returns true is interop-type 'targetsync' is used.
auto prefs() const
Returns a range of PrefView objects, one per preference-specification, each carrying the fr() express...
This represents clause 'is_device_ptr' in the 'pragma omp ...' directives.
static OMPIsDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPIsDevicePtrClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
This represents clause 'map' in the 'pragma omp ...' directives.
OpenMPMapClauseKind getMapType() const LLVM_READONLY
Fetches mapping kind for the clause.
OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY
Fetches the map-type-modifier at 'Cnt' index of array of modifiers.
static OMPMapClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
static OMPMapClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars original expressions, NumUniqueDeclarations declar...
This represents 'nocontext' clause in the 'pragma omp ...' directive.
Expr * getCondition() const
Returns condition.
child_range used_children()
static OMPNontemporalClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
static OMPNontemporalClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
void setPrivateRefs(ArrayRef< Expr * > VL)
Sets the list of references to private copies created in private clauses.
This represents 'novariants' clause in the 'pragma omp ...' directive.
Expr * getCondition() const
Returns condition.
child_range used_children()
This represents 'num_tasks' clause in the 'pragma omp ...' directive.
OpenMPNumTasksClauseModifier getModifier() const
Gets modifier.
child_range used_children()
Expr * getNumTasks() const
Return safe iteration space distance.
This represents 'num_teams' clause in the 'pragma omp ...' directive.
OpenMPNumTeamsClauseModifier getModifier() const
Get the modifier.
static OMPNumTeamsClause * Create(const ASTContext &C, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, OpenMPNumTeamsClauseModifier Modifier, Expr *ModifierExpr, SourceLocation ModifierLoc, Stmt *PreInit)
Creates clause with a list of variables VL.
const Expr * getModifierExpr() const
Get the expression of the modifier.
static OMPNumTeamsClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
OpenMPOrderClauseKind getKind() const
Returns kind of the clause.
OpenMPOrderClauseModifier getModifier() const
Returns Modifier of the clause.
This represents 'priority' clause in the 'pragma omp ...' directive.
child_range used_children()
Expr * getPriority()
Return Priority number.
This represents 'thread_limit' clause in the 'pragma omp ...' directive.
static OMPThreadLimitClause * Create(const ASTContext &C, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, OpenMPThreadLimitClauseModifier Modifier, Expr *ModifierExpr, SourceLocation ModifierLoc, Stmt *PreInit)
Creates clause with a list of variables VL.
const Expr * getModifierExpr() const
Get the expression of the modifier.
OpenMPThreadLimitClauseModifier getModifier() const
Get the modifier.
static OMPThreadLimitClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
static OMPToClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
static OMPToClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, Expr *IteratorModifier, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
std::string getMangledName() const
Return a string representation identifying this context selector.
friend class ASTContext
void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const
Print a human readable representation into OS.
void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const
Create a variant match info object from this trait info object.
llvm::SmallVector< OMPTraitSet, 2 > Sets
The outermost level of selector sets.
Expr * getInteropVar() const
Returns the interop variable.
This represents clause 'use_device_addr' in the 'pragma omp ...' directives.
static OMPUseDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPUseDeviceAddrClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
This represents clause 'use_device_ptr' in the 'pragma omp ...' directives.
static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< Expr * > PrivateVars, ArrayRef< Expr * > Inits, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, OpenMPUseDevicePtrFallbackModifier FallbackModifier, SourceLocation FallbackModifierLoc)
Creates clause with a list of variables Vars.
OpenMPUseDevicePtrFallbackModifier getFallbackModifier() const
Get the fallback modifier for the clause.
static OMPUseDevicePtrClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
This represents clause 'uses_allocators' in the 'pragma omp target'-based directives.
OMPUsesAllocatorsClause::Data getAllocatorData(unsigned I) const
Returns data for the specified allocator.
static OMPUsesAllocatorsClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N allocators.
static OMPUsesAllocatorsClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< OMPUsesAllocatorsClause::Data > Data)
Creates clause with a list of allocators Data.
unsigned getNumberOfAllocators() const
Returns number of allocators associated with the clause.
ArrayRef< const Attr * > getAttrs() const
Returned the attributes parsed from this clause.
This represents 'ompx_dyn_cgroup_mem' clause in the 'pragma omp target ...' directive.
Expr * getSize()
Return the size expression.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:927
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition Expr.cpp:5405
Attr - This represents one attribute.
Definition Attr.h:46
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const
This represents one expression.
Definition Expr.h:112
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:2029
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
This represents the 'align' clause in the 'pragma omp allocate' directive.
Expr * getAlignment() const
Returns alignment.
static OMPAlignClause * Create(const ASTContext &C, Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'align' clause with the given alignment.
This represents clause 'allocate' in the 'pragma omp ...' directives.
static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc, OpenMPAllocateClauseModifier Modifier1, SourceLocation Modifier1Loc, OpenMPAllocateClauseModifier Modifier2, SourceLocation Modifier2Loc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
OpenMPAllocateClauseModifier getSecondAllocateModifier() const
Get the second modifier of the clause.
Expr * getAlignment() const
Returns the alignment expression or nullptr, if no alignment specified.
OpenMPAllocateClauseModifier getFirstAllocateModifier() const
Get the first modifier of the clause.
Expr * getAllocator() const
Returns the allocator expression or nullptr, if no allocator is specified.
static OMPAllocateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
This represents 'allocator' clause in the 'pragma omp ...' directive.
Expr * getAllocator() const
Returns allocator.
static OMPClauseWithPostUpdate * get(OMPClause *C)
OMPClauseWithPostUpdate(const OMPClause *This)
const Stmt * getPreInitStmt() const
Get pre-initialization statement for the clause.
OMPClauseWithPreInit(const OMPClause *This)
static OMPClauseWithPreInit * get(OMPClause *C)
This is a basic class for representing single OpenMP clause.
child_range used_children()
Get the iterator range for the expressions used in the clauses.
llvm::iterator_range< child_iterator > child_range
child_range children()
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
This represents 'collapse' clause in the 'pragma omp ...' directive.
Expr * getNumForLoops() const
Return the number of associated for-loops.
This represents the 'counts' clause in the 'pragma omp split' directive.
std::optional< unsigned > getOmpFillIndex() const
static OMPCountsClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Counts, std::optional< unsigned > FillIdx, SourceLocation FillLoc)
Build a 'counts' AST node.
static OMPCountsClause * CreateEmpty(const ASTContext &C, unsigned NumCounts)
Build an empty 'counts' AST node for deserialization.
MutableArrayRef< Expr * > getCountsRefs()
Returns the count expressions.
This represents 'default' clause in the 'pragma omp ...' directive.
llvm::omp::DefaultKind getDefaultKind() const
Returns kind of the clause.
OpenMPDefaultClauseVariableCategory getDefaultVC() const
This represents 'final' clause in the 'pragma omp ...' directive.
child_range used_children()
Expr * getCondition() const
Returns condition.
Representation of the 'full' clause of the 'pragma omp unroll' directive.
static OMPFullClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Build an AST node for a 'full' clause.
static OMPFullClause * CreateEmpty(const ASTContext &C)
Build an empty 'full' AST node for deserialization.
This represents 'if' clause in the 'pragma omp ...' directive.
child_range used_children()
Expr * getCondition() const
Returns condition.
OpenMPDirectiveKind getNameModifier() const
Return directive name modifier associated with the clause.
This class represents the 'looprange' clause in the 'pragma omp fuse' directive.
Expr * getFirst() const
Get looprange 'first' expression.
static OMPLoopRangeClause * CreateEmpty(const ASTContext &C)
Build an empty 'looprange' clause node.
static OMPLoopRangeClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation FirstLoc, SourceLocation CountLoc, SourceLocation EndLoc, Expr *First, Expr *Count)
Build a 'looprange' clause AST node.
Expr * getCount() const
Get looprange 'count' expression.
This represents 'num_threads' clause in the 'pragma omp ...' directive.
OpenMPNumThreadsClauseModifier getModifier() const
Gets modifier.
Expr * getNumThreads() const
Returns number of threads.
llvm::iterator_range< child_iterator > child_range
Representation of the 'partial' clause of the 'pragma omp unroll' directive.
static OMPPartialClause * CreateEmpty(const ASTContext &C)
Build an empty 'partial' AST node for deserialization.
static OMPPartialClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Factor)
Build an AST node for a 'partial' clause.
Expr * getFactor() const
Returns the argument of the clause or nullptr if not set.
This class represents the 'permutation' clause in the 'pragma omp interchange' directive.
MutableArrayRef< Expr * > getArgsRefs()
Returns the permutation index expressions.
static OMPPermutationClause * CreateEmpty(const ASTContext &C, unsigned NumLoops)
Build an empty 'permutation' AST node for deserialization.
static OMPPermutationClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Args)
Build a 'permutation' clause AST node.
This represents 'safelen' clause in the 'pragma omp ...' directive.
Expr * getSafelen() const
Return safe iteration space distance.
This represents 'simdlen' clause in the 'pragma omp ...' directive.
Expr * getSimdlen() const
Return safe iteration space distance.
This represents the 'sizes' clause in the 'pragma omp tile' directive.
static OMPSizesClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Sizes)
Build a 'sizes' AST node.
MutableArrayRef< Expr * > getSizesRefs()
Returns the tile size expressions.
static OMPSizesClause * CreateEmpty(const ASTContext &C, unsigned NumSizes)
Build an empty 'sizes' AST node for deserialization.
This represents 'threadset' clause in the 'pragma omp task ...' directive.
OpenMPThreadsetKind getThreadsetKind() const
Returns kind of the clause.
A (possibly-)qualified type.
Definition TypeBase.h:938
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8674
QualType getCanonicalType() const
Definition TypeBase.h:8541
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
Stmt - This represents one statement.
Definition Stmt.h:85
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
The base class of the type hierarchy.
Definition TypeBase.h:1876
bool isPointerType() const
Definition TypeBase.h:8726
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:789
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
Defines the clang::TargetInfo interface.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
OpenMPOriginalSharingModifier
OpenMP 6.0 original sharing modifiers.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
Privates[]
This class represents the 'transparent' clause in the 'pragma omp task' directive.
bool isa(CodeGen::Address addr)
Definition Address.h:330
MutableArrayRef< Expr * > getFinals()
Sets the list of final update expressions for linear variables.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ OMPC_ORDER_MODIFIER_unknown
MutableArrayRef< Expr * > getPrivates()
Finals[]; Step; CalcStep; }.
OpenMPReductionClauseModifier
OpenMP modifiers for 'reduction' clause.
@ DeviceNum
'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.
@ OMPC_SCHEDULE_MODIFIER_unknown
Definition OpenMPKinds.h:40
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
OpenMPNumTeamsClauseModifier
@ OMPC_NUMTEAMS_unknown
Expr * Cond
};
OpenMPDoacrossClauseModifier
OpenMP dependence types for 'doacross' clause.
static constexpr unsigned NumberOfOMPMapClauseModifiers
Number of allowed map-type-modifiers.
Definition OpenMPKinds.h:88
@ OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
const FunctionProtoType * T
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
@ OMPC_LASTPRIVATE_unknown
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
Definition OpenMPKinds.h:55
OpenMPGrainsizeClauseModifier
@ OMPC_GRAINSIZE_unknown
OpenMPNumTasksClauseModifier
@ OMPC_NUMTASKS_unknown
OpenMPUseDevicePtrFallbackModifier
OpenMP 6.1 use_device_ptr fallback modifier.
@ OMPC_USE_DEVICE_PTR_FALLBACK_unknown
MutableArrayRef< Expr * > getUsedExprs()
Gets the list of used expressions for linear variables.
static constexpr unsigned NumberOfOMPMotionModifiers
Number of allowed motion-modifiers.
@ OMPC_MOTION_MODIFIER_unknown
Definition OpenMPKinds.h:96
@ OMPC_DEFAULTMAP_unknown
OpenMPAllocateClauseModifier
OpenMP modifiers for 'allocate' clause.
@ OMPC_ALLOCATE_unknown
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition OpenMPKinds.h:63
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
Definition OpenMPKinds.h:25
@ OMPC_DYN_GROUPPRIVATE_unknown
MutableArrayRef< Expr * > getUpdates()
Sets the list of update expressions for linear variables.
OpenMPThreadLimitClauseModifier
MutableArrayRef< Expr * > getInits()
OpenMPNumThreadsClauseModifier
@ OMPC_NUMTHREADS_unknown
child_range children()
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
U cast(CodeGen::Address addr)
Definition Address.h:327
const char * getOpenMPDefaultVariableCategoryName(unsigned VC)
OpenMPDeviceClauseModifier
OpenMP modifiers for 'device' clause.
Definition OpenMPKinds.h:48
@ OMPC_DEVICE_unknown
Definition OpenMPKinds.h:51
@ OMPC_MAP_MODIFIER_unknown
Definition OpenMPKinds.h:80
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition OpenMPKinds.h:71
@ OMPC_MAP_unknown
Definition OpenMPKinds.h:75
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
int const char * function
Definition c++config.h:31
ArrayRef< Expr * > Attrs
attr() string-literal expressions. Empty for fr-only or OMP 5.1 flat specs.
This structure contains all sizes needed for by an OMPMappableExprListClause.
unsigned NumComponents
Total number of expression components.
unsigned NumUniqueDeclarations
Number of unique base declarations.
unsigned NumVars
Number of expressions listed.
unsigned NumComponentLists
Number of component lists.
Data for list of allocators.
Expr * AllocatorTraits
Allocator traits.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
TargetOMPContext(ASTContext &ASTCtx, std::function< void(StringRef)> &&DiagUnknownTrait, const FunctionDecl *CurrentFunctionDecl, ArrayRef< llvm::omp::TraitProperty > ConstructTraits, int DeviceNum)
bool matchesISATrait(StringRef RawString) const override
See llvm::omp::OMPContext::matchesISATrait.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
llvm::SmallVector< OMPInteropPref, 4 > Prefs
One entry of a prefer_type list.
llvm::SmallVector< Expr *, 2 > Attrs
This structure contains most locations needed for by an OMPVarListClause.
Describes how types, statements, expressions, and declarations should be printed.