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