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