clang 22.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"
19#include "clang/Basic/LLVM.h"
22#include "llvm/ADT/SmallPtrSet.h"
23#include "llvm/Support/ErrorHandling.h"
24#include <algorithm>
25#include <cassert>
26#include <optional>
27
28using namespace clang;
29using namespace llvm;
30using namespace omp;
31
33 switch (getClauseKind()) {
34 default:
35 break;
36#define GEN_CLANG_CLAUSE_CLASS
37#define CLAUSE_CLASS(Enum, Str, Class) \
38 case Enum: \
39 return static_cast<Class *>(this)->children();
40#include "llvm/Frontend/OpenMP/OMP.inc"
41 }
42 llvm_unreachable("unknown OMPClause");
43}
44
46 switch (getClauseKind()) {
47#define GEN_CLANG_CLAUSE_CLASS
48#define CLAUSE_CLASS(Enum, Str, Class) \
49 case Enum: \
50 return static_cast<Class *>(this)->used_children();
51#define CLAUSE_NO_CLASS(Enum, Str) \
52 case Enum: \
53 break;
54#include "llvm/Frontend/OpenMP/OMP.inc"
55 }
56 llvm_unreachable("unknown OMPClause");
57}
58
60 auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
61 return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
62}
63
65 switch (C->getClauseKind()) {
66 case OMPC_schedule:
67 return static_cast<const OMPScheduleClause *>(C);
68 case OMPC_dist_schedule:
69 return static_cast<const OMPDistScheduleClause *>(C);
70 case OMPC_firstprivate:
71 return static_cast<const OMPFirstprivateClause *>(C);
72 case OMPC_lastprivate:
73 return static_cast<const OMPLastprivateClause *>(C);
74 case OMPC_reduction:
75 return static_cast<const OMPReductionClause *>(C);
76 case OMPC_task_reduction:
77 return static_cast<const OMPTaskReductionClause *>(C);
78 case OMPC_in_reduction:
79 return static_cast<const OMPInReductionClause *>(C);
80 case OMPC_linear:
81 return static_cast<const OMPLinearClause *>(C);
82 case OMPC_if:
83 return static_cast<const OMPIfClause *>(C);
84 case OMPC_num_threads:
85 return static_cast<const OMPNumThreadsClause *>(C);
86 case OMPC_num_teams:
87 return static_cast<const OMPNumTeamsClause *>(C);
88 case OMPC_thread_limit:
89 return static_cast<const OMPThreadLimitClause *>(C);
90 case OMPC_device:
91 return static_cast<const OMPDeviceClause *>(C);
92 case OMPC_grainsize:
93 return static_cast<const OMPGrainsizeClause *>(C);
94 case OMPC_num_tasks:
95 return static_cast<const OMPNumTasksClause *>(C);
96 case OMPC_final:
97 return static_cast<const OMPFinalClause *>(C);
98 case OMPC_priority:
99 return static_cast<const OMPPriorityClause *>(C);
100 case OMPC_novariants:
101 return static_cast<const OMPNovariantsClause *>(C);
102 case OMPC_nocontext:
103 return static_cast<const OMPNocontextClause *>(C);
104 case OMPC_filter:
105 return static_cast<const OMPFilterClause *>(C);
106 case OMPC_ompx_dyn_cgroup_mem:
107 return static_cast<const OMPXDynCGroupMemClause *>(C);
108 case OMPC_dyn_groupprivate:
109 return static_cast<const OMPDynGroupprivateClause *>(C);
110 case OMPC_message:
111 return static_cast<const OMPMessageClause *>(C);
112 case OMPC_default:
113 case OMPC_proc_bind:
114 case OMPC_safelen:
115 case OMPC_simdlen:
116 case OMPC_sizes:
117 case OMPC_allocator:
118 case OMPC_allocate:
119 case OMPC_collapse:
120 case OMPC_private:
121 case OMPC_shared:
122 case OMPC_aligned:
123 case OMPC_copyin:
124 case OMPC_copyprivate:
125 case OMPC_ordered:
126 case OMPC_nowait:
127 case OMPC_untied:
128 case OMPC_mergeable:
129 case OMPC_threadset:
130 case OMPC_threadprivate:
131 case OMPC_groupprivate:
132 case OMPC_flush:
133 case OMPC_depobj:
134 case OMPC_read:
135 case OMPC_write:
136 case OMPC_update:
137 case OMPC_capture:
138 case OMPC_compare:
139 case OMPC_fail:
140 case OMPC_seq_cst:
141 case OMPC_acq_rel:
142 case OMPC_acquire:
143 case OMPC_release:
144 case OMPC_relaxed:
145 case OMPC_depend:
146 case OMPC_threads:
147 case OMPC_simd:
148 case OMPC_map:
149 case OMPC_nogroup:
150 case OMPC_hint:
151 case OMPC_defaultmap:
152 case OMPC_unknown:
153 case OMPC_uniform:
154 case OMPC_to:
155 case OMPC_from:
156 case OMPC_use_device_ptr:
157 case OMPC_use_device_addr:
158 case OMPC_is_device_ptr:
159 case OMPC_has_device_addr:
160 case OMPC_unified_address:
161 case OMPC_unified_shared_memory:
162 case OMPC_reverse_offload:
163 case OMPC_dynamic_allocators:
164 case OMPC_atomic_default_mem_order:
165 case OMPC_self_maps:
166 case OMPC_at:
167 case OMPC_severity:
168 case OMPC_device_type:
169 case OMPC_match:
170 case OMPC_nontemporal:
171 case OMPC_order:
172 case OMPC_destroy:
173 case OMPC_detach:
174 case OMPC_inclusive:
175 case OMPC_exclusive:
176 case OMPC_uses_allocators:
177 case OMPC_affinity:
178 case OMPC_when:
179 case OMPC_bind:
180 case OMPC_ompx_bare:
181 break;
182 default:
183 break;
184 }
185
186 return nullptr;
187}
188
190 auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));
191 return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
192}
193
195 switch (C->getClauseKind()) {
196 case OMPC_lastprivate:
197 return static_cast<const OMPLastprivateClause *>(C);
198 case OMPC_reduction:
199 return static_cast<const OMPReductionClause *>(C);
200 case OMPC_task_reduction:
201 return static_cast<const OMPTaskReductionClause *>(C);
202 case OMPC_in_reduction:
203 return static_cast<const OMPInReductionClause *>(C);
204 case OMPC_linear:
205 return static_cast<const OMPLinearClause *>(C);
206 case OMPC_schedule:
207 case OMPC_dist_schedule:
208 case OMPC_firstprivate:
209 case OMPC_default:
210 case OMPC_proc_bind:
211 case OMPC_if:
212 case OMPC_final:
213 case OMPC_num_threads:
214 case OMPC_safelen:
215 case OMPC_simdlen:
216 case OMPC_sizes:
217 case OMPC_allocator:
218 case OMPC_allocate:
219 case OMPC_collapse:
220 case OMPC_private:
221 case OMPC_shared:
222 case OMPC_aligned:
223 case OMPC_copyin:
224 case OMPC_copyprivate:
225 case OMPC_ordered:
226 case OMPC_nowait:
227 case OMPC_untied:
228 case OMPC_mergeable:
229 case OMPC_threadprivate:
230 case OMPC_groupprivate:
231 case OMPC_flush:
232 case OMPC_depobj:
233 case OMPC_read:
234 case OMPC_write:
235 case OMPC_update:
236 case OMPC_capture:
237 case OMPC_compare:
238 case OMPC_fail:
239 case OMPC_seq_cst:
240 case OMPC_acq_rel:
241 case OMPC_acquire:
242 case OMPC_release:
243 case OMPC_relaxed:
244 case OMPC_depend:
245 case OMPC_device:
246 case OMPC_threads:
247 case OMPC_simd:
248 case OMPC_map:
249 case OMPC_num_teams:
250 case OMPC_thread_limit:
251 case OMPC_priority:
252 case OMPC_grainsize:
253 case OMPC_nogroup:
254 case OMPC_num_tasks:
255 case OMPC_hint:
256 case OMPC_defaultmap:
257 case OMPC_unknown:
258 case OMPC_uniform:
259 case OMPC_to:
260 case OMPC_from:
261 case OMPC_use_device_ptr:
262 case OMPC_use_device_addr:
263 case OMPC_is_device_ptr:
264 case OMPC_has_device_addr:
265 case OMPC_unified_address:
266 case OMPC_unified_shared_memory:
267 case OMPC_reverse_offload:
268 case OMPC_dynamic_allocators:
269 case OMPC_atomic_default_mem_order:
270 case OMPC_self_maps:
271 case OMPC_at:
272 case OMPC_severity:
273 case OMPC_message:
274 case OMPC_device_type:
275 case OMPC_match:
276 case OMPC_nontemporal:
277 case OMPC_order:
278 case OMPC_destroy:
279 case OMPC_novariants:
280 case OMPC_nocontext:
281 case OMPC_detach:
282 case OMPC_inclusive:
283 case OMPC_exclusive:
284 case OMPC_uses_allocators:
285 case OMPC_affinity:
286 case OMPC_when:
287 case OMPC_bind:
288 break;
289 default:
290 break;
291 }
292
293 return nullptr;
294}
295
296/// Gets the address of the original, non-captured, expression used in the
297/// clause as the preinitializer.
299 if (!S)
300 return nullptr;
301 if (auto *DS = dyn_cast<DeclStmt>(S)) {
302 assert(DS->isSingleDecl() && "Only single expression must be captured.");
303 if (auto *OED = dyn_cast<OMPCapturedExprDecl>(DS->getSingleDecl()))
304 return OED->getInitAddress();
305 }
306 return nullptr;
307}
308
311 return child_range(C, C + 1);
312 return child_range(&Condition, &Condition + 1);
313}
314
316 if (Condition)
317 return child_range(&Condition, &Condition + 1);
318 return children();
319}
320
323 return child_range(C, C + 1);
324 return child_range(&Grainsize, &Grainsize + 1);
325}
326
329 return child_range(C, C + 1);
330 return child_range(&NumTasks, &NumTasks + 1);
331}
332
338
341 return child_range(C, C + 1);
342 return child_range(&Priority, &Priority + 1);
343}
344
350
356
357OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,
358 unsigned NumLoops,
359 SourceLocation StartLoc,
360 SourceLocation LParenLoc,
361 SourceLocation EndLoc) {
362 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
363 auto *Clause =
364 new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);
365 for (unsigned I = 0; I < NumLoops; ++I) {
366 Clause->setLoopNumIterations(I, nullptr);
367 Clause->setLoopCounter(I, nullptr);
368 }
369 return Clause;
370}
371
373 unsigned NumLoops) {
374 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
375 auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
376 for (unsigned I = 0; I < NumLoops; ++I) {
377 Clause->setLoopNumIterations(I, nullptr);
378 Clause->setLoopCounter(I, nullptr);
379 }
380 return Clause;
381}
382
384 Expr *NumIterations) {
385 assert(NumLoop < NumberOfLoops && "out of loops number.");
386 getTrailingObjects()[NumLoop] = NumIterations;
387}
388
390 return getTrailingObjects(NumberOfLoops);
391}
392
393void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {
394 assert(NumLoop < NumberOfLoops && "out of loops number.");
395 getTrailingObjects()[NumberOfLoops + NumLoop] = Counter;
396}
397
399 assert(NumLoop < NumberOfLoops && "out of loops number.");
400 return getTrailingObjects()[NumberOfLoops + NumLoop];
401}
402
403const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
404 assert(NumLoop < NumberOfLoops && "out of loops number.");
405 return getTrailingObjects()[NumberOfLoops + NumLoop];
406}
407
408OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C,
409 SourceLocation StartLoc,
410 SourceLocation EndLoc) {
411 return new (C) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/false);
412}
413
416 SourceLocation LParenLoc, SourceLocation ArgumentLoc,
418 void *Mem =
419 C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
420 alignof(OMPUpdateClause));
421 auto *Clause =
422 new (Mem) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/true);
423 Clause->setLParenLoc(LParenLoc);
424 Clause->setArgumentLoc(ArgumentLoc);
425 Clause->setDependencyKind(DK);
426 return Clause;
427}
428
430 bool IsExtended) {
431 if (!IsExtended)
432 return new (C) OMPUpdateClause(/*IsExtended=*/false);
433 void *Mem =
434 C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
435 alignof(OMPUpdateClause));
436 auto *Clause = new (Mem) OMPUpdateClause(/*IsExtended=*/true);
437 Clause->IsExtended = true;
438 return Clause;
439}
440
441void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
442 assert(VL.size() == varlist_size() &&
443 "Number of private copies is not the same as the preallocated buffer");
444 llvm::copy(VL, varlist_end());
445}
446
449 SourceLocation LParenLoc, SourceLocation EndLoc,
450 ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
451 // Allocate space for private variables and initializer expressions.
452 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
453 OMPPrivateClause *Clause =
454 new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
455 Clause->setVarRefs(VL);
456 Clause->setPrivateCopies(PrivateVL);
457 return Clause;
458}
459
461 unsigned N) {
462 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
463 return new (Mem) OMPPrivateClause(N);
464}
465
466void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
467 assert(VL.size() == varlist_size() &&
468 "Number of private copies is not the same as the preallocated buffer");
469 llvm::copy(VL, varlist_end());
470}
471
472void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
473 assert(VL.size() == varlist_size() &&
474 "Number of inits is not the same as the preallocated buffer");
475 llvm::copy(VL, getPrivateCopies().end());
476}
477
480 SourceLocation LParenLoc, SourceLocation EndLoc,
482 ArrayRef<Expr *> InitVL, Stmt *PreInit) {
483 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));
484 OMPFirstprivateClause *Clause =
485 new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
486 Clause->setVarRefs(VL);
487 Clause->setPrivateCopies(PrivateVL);
488 Clause->setInits(InitVL);
489 Clause->setPreInitStmt(PreInit);
490 return Clause;
491}
492
493OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
494 unsigned N) {
495 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));
496 return new (Mem) OMPFirstprivateClause(N);
497}
498
500 assert(PrivateCopies.size() == varlist_size() &&
501 "Number of private copies is not the same as the preallocated buffer");
502 llvm::copy(PrivateCopies, varlist_end());
503}
504
505void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
506 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
507 "not the same as the "
508 "preallocated buffer");
509 llvm::copy(SrcExprs, getPrivateCopies().end());
510}
511
512void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
513 assert(DstExprs.size() == varlist_size() && "Number of destination "
514 "expressions is not the same as "
515 "the preallocated buffer");
516 llvm::copy(DstExprs, getSourceExprs().end());
517}
518
519void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
520 assert(AssignmentOps.size() == varlist_size() &&
521 "Number of assignment expressions is not the same as the preallocated "
522 "buffer");
523 llvm::copy(AssignmentOps, getDestinationExprs().end());
524}
525
526OMPLastprivateClause *OMPLastprivateClause::Create(
527 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
529 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
531 SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {
532 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
533 OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(
534 StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());
535 Clause->setVarRefs(VL);
536 Clause->setSourceExprs(SrcExprs);
537 Clause->setDestinationExprs(DstExprs);
538 Clause->setAssignmentOps(AssignmentOps);
539 Clause->setPreInitStmt(PreInit);
540 Clause->setPostUpdateExpr(PostUpdate);
541 return Clause;
542}
543
544OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
545 unsigned N) {
546 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
547 return new (Mem) OMPLastprivateClause(N);
548}
549
550OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
551 SourceLocation StartLoc,
552 SourceLocation LParenLoc,
553 SourceLocation EndLoc,
554 ArrayRef<Expr *> VL) {
555 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
556 OMPSharedClause *Clause =
557 new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
558 Clause->setVarRefs(VL);
559 return Clause;
560}
561
562OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
563 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
564 return new (Mem) OMPSharedClause(N);
565}
566
567void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
568 assert(PL.size() == varlist_size() &&
569 "Number of privates is not the same as the preallocated buffer");
570 llvm::copy(PL, varlist_end());
571}
572
573void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
574 assert(IL.size() == varlist_size() &&
575 "Number of inits is not the same as the preallocated buffer");
576 llvm::copy(IL, getPrivates().end());
577}
578
580 assert(UL.size() == varlist_size() &&
581 "Number of updates is not the same as the preallocated buffer");
582 llvm::copy(UL, getInits().end());
583}
584
586 assert(FL.size() == varlist_size() &&
587 "Number of final updates is not the same as the preallocated buffer");
588 llvm::copy(FL, getUpdates().end());
589}
590
592 assert(
593 UE.size() == varlist_size() + 1 &&
594 "Number of used expressions is not the same as the preallocated buffer");
595 llvm::copy(UE, getFinals().end() + 2);
596}
597
598OMPLinearClause *OMPLinearClause::Create(
599 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
600 OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
601 SourceLocation ColonLoc, SourceLocation StepModifierLoc,
603 ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
604 Expr *PostUpdate) {
605 // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
606 // (Step and CalcStep), list of used expression + step.
607 void *Mem =
608 C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));
609 OMPLinearClause *Clause =
610 new (Mem) OMPLinearClause(StartLoc, LParenLoc, Modifier, ModifierLoc,
611 ColonLoc, StepModifierLoc, EndLoc, VL.size());
612 Clause->setVarRefs(VL);
613 Clause->setPrivates(PL);
614 Clause->setInits(IL);
615 // Fill update and final expressions with zeroes, they are provided later,
616 // after the directive construction.
617 std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
618 nullptr);
619 std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
620 nullptr);
621 std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),
622 nullptr);
623 Clause->setStep(Step);
624 Clause->setCalcStep(CalcStep);
625 Clause->setPreInitStmt(PreInit);
626 Clause->setPostUpdateExpr(PostUpdate);
627 return Clause;
628}
629
631 unsigned NumVars) {
632 // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
633 // (Step and CalcStep), list of used expression + step.
634 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2 + NumVars +1));
635 return new (Mem) OMPLinearClause(NumVars);
636}
637
639 // Range includes only non-nullptr elements.
640 return child_range(
641 reinterpret_cast<Stmt **>(getUsedExprs().begin()),
642 reinterpret_cast<Stmt **>(llvm::find(getUsedExprs(), nullptr)));
643}
644
647 SourceLocation LParenLoc, SourceLocation ColonLoc,
648 SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
649 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
650 OMPAlignedClause *Clause = new (Mem)
651 OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
652 Clause->setVarRefs(VL);
653 Clause->setAlignment(A);
654 return Clause;
655}
656
658 unsigned NumVars) {
659 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));
660 return new (Mem) OMPAlignedClause(NumVars);
661}
662
663OMPAlignClause *OMPAlignClause::Create(const ASTContext &C, Expr *A,
664 SourceLocation StartLoc,
665 SourceLocation LParenLoc,
666 SourceLocation EndLoc) {
667 return new (C) OMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
668}
669
670void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
671 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
672 "not the same as the "
673 "preallocated buffer");
674 llvm::copy(SrcExprs, varlist_end());
675}
676
677void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
678 assert(DstExprs.size() == varlist_size() && "Number of destination "
679 "expressions is not the same as "
680 "the preallocated buffer");
681 llvm::copy(DstExprs, getSourceExprs().end());
682}
683
684void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
685 assert(AssignmentOps.size() == varlist_size() &&
686 "Number of assignment expressions is not the same as the preallocated "
687 "buffer");
688 llvm::copy(AssignmentOps, getDestinationExprs().end());
689}
690
691OMPCopyinClause *OMPCopyinClause::Create(
692 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
694 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
695 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
696 OMPCopyinClause *Clause =
697 new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
698 Clause->setVarRefs(VL);
699 Clause->setSourceExprs(SrcExprs);
700 Clause->setDestinationExprs(DstExprs);
701 Clause->setAssignmentOps(AssignmentOps);
702 return Clause;
703}
704
705OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
706 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
707 return new (Mem) OMPCopyinClause(N);
708}
709
710void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
711 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
712 "not the same as the "
713 "preallocated buffer");
714 llvm::copy(SrcExprs, varlist_end());
715}
716
717void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
718 assert(DstExprs.size() == varlist_size() && "Number of destination "
719 "expressions is not the same as "
720 "the preallocated buffer");
721 llvm::copy(DstExprs, getSourceExprs().end());
722}
723
724void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
725 assert(AssignmentOps.size() == varlist_size() &&
726 "Number of assignment expressions is not the same as the preallocated "
727 "buffer");
728 llvm::copy(AssignmentOps, getDestinationExprs().end());
729}
730
731OMPCopyprivateClause *OMPCopyprivateClause::Create(
732 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
734 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
735 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
736 OMPCopyprivateClause *Clause =
737 new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
738 Clause->setVarRefs(VL);
739 Clause->setSourceExprs(SrcExprs);
740 Clause->setDestinationExprs(DstExprs);
741 Clause->setAssignmentOps(AssignmentOps);
742 return Clause;
743}
744
745OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
746 unsigned N) {
747 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
748 return new (Mem) OMPCopyprivateClause(N);
749}
750
751void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
752 assert(Privates.size() == varlist_size() &&
753 "Number of private copies is not the same as the preallocated buffer");
754 llvm::copy(Privates, varlist_end());
755}
756
757void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
758 assert(
759 LHSExprs.size() == varlist_size() &&
760 "Number of LHS expressions is not the same as the preallocated buffer");
761 llvm::copy(LHSExprs, getPrivates().end());
762}
763
764void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
765 assert(
766 RHSExprs.size() == varlist_size() &&
767 "Number of RHS expressions is not the same as the preallocated buffer");
768 llvm::copy(RHSExprs, getLHSExprs().end());
769}
770
771void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
772 assert(ReductionOps.size() == varlist_size() && "Number of reduction "
773 "expressions is not the same "
774 "as the preallocated buffer");
775 llvm::copy(ReductionOps, getRHSExprs().end());
776}
777
778void OMPReductionClause::setInscanCopyOps(ArrayRef<Expr *> Ops) {
779 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
780 assert(Ops.size() == varlist_size() && "Number of copy "
781 "expressions is not the same "
782 "as the preallocated buffer");
783 llvm::copy(Ops, getReductionOps().end());
784}
785
786void OMPReductionClause::setInscanCopyArrayTemps(
787 ArrayRef<Expr *> CopyArrayTemps) {
788 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
789 assert(CopyArrayTemps.size() == varlist_size() &&
790 "Number of copy temp expressions is not the same as the preallocated "
791 "buffer");
792 llvm::copy(CopyArrayTemps, getInscanCopyOps().end());
793}
794
795void OMPReductionClause::setInscanCopyArrayElems(
796 ArrayRef<Expr *> CopyArrayElems) {
797 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
798 assert(CopyArrayElems.size() == varlist_size() &&
799 "Number of copy temp expressions is not the same as the preallocated "
800 "buffer");
801 llvm::copy(CopyArrayElems, getInscanCopyArrayTemps().end());
802}
803
804OMPReductionClause *OMPReductionClause::Create(
805 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
806 SourceLocation ModifierLoc, SourceLocation EndLoc, SourceLocation ColonLoc,
808 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
809 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
810 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
811 ArrayRef<Expr *> CopyOps, ArrayRef<Expr *> CopyArrayTemps,
812 ArrayRef<Expr *> CopyArrayElems, Stmt *PreInit, Expr *PostUpdate,
813 ArrayRef<bool> IsPrivateVarReduction,
814 OpenMPOriginalSharingModifier OrignalSharingModifier) {
815 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, bool>(
816 (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size(), VL.size()));
817 auto *Clause = new (Mem) OMPReductionClause(
818 StartLoc, LParenLoc, ModifierLoc, EndLoc, ColonLoc, Modifier,
819 OrignalSharingModifier, VL.size(), QualifierLoc, NameInfo);
820 Clause->setVarRefs(VL);
821 Clause->setPrivates(Privates);
822 Clause->setLHSExprs(LHSExprs);
823 Clause->setRHSExprs(RHSExprs);
824 Clause->setReductionOps(ReductionOps);
825 Clause->setPreInitStmt(PreInit);
826 Clause->setPostUpdateExpr(PostUpdate);
827 Clause->setPrivateVariableReductionFlags(IsPrivateVarReduction);
828 if (Modifier == OMPC_REDUCTION_inscan) {
829 Clause->setInscanCopyOps(CopyOps);
830 Clause->setInscanCopyArrayTemps(CopyArrayTemps);
831 Clause->setInscanCopyArrayElems(CopyArrayElems);
832 } else {
833 assert(CopyOps.empty() &&
834 "copy operations are expected in inscan reductions only.");
835 assert(CopyArrayTemps.empty() &&
836 "copy array temps are expected in inscan reductions only.");
837 assert(CopyArrayElems.empty() &&
838 "copy array temps are expected in inscan reductions only.");
839 }
840 return Clause;
841}
842
846 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, bool>(
847 (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N, N));
848 auto *Clause = new (Mem) OMPReductionClause(N);
849 Clause->setModifier(Modifier);
850 return Clause;
851}
852
853void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
854 assert(Privates.size() == varlist_size() &&
855 "Number of private copies is not the same as the preallocated buffer");
856 llvm::copy(Privates, varlist_end());
857}
858
859void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
860 assert(
861 LHSExprs.size() == varlist_size() &&
862 "Number of LHS expressions is not the same as the preallocated buffer");
863 llvm::copy(LHSExprs, getPrivates().end());
864}
865
866void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
867 assert(
868 RHSExprs.size() == varlist_size() &&
869 "Number of RHS expressions is not the same as the preallocated buffer");
870 llvm::copy(RHSExprs, getLHSExprs().end());
871}
872
873void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
874 assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
875 "expressions is not the same "
876 "as the preallocated buffer");
877 llvm::copy(ReductionOps, getRHSExprs().end());
878}
879
880OMPTaskReductionClause *OMPTaskReductionClause::Create(
881 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
883 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
884 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
885 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
886 Expr *PostUpdate) {
887 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
888 OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
889 StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
890 Clause->setVarRefs(VL);
891 Clause->setPrivates(Privates);
892 Clause->setLHSExprs(LHSExprs);
893 Clause->setRHSExprs(RHSExprs);
894 Clause->setReductionOps(ReductionOps);
895 Clause->setPreInitStmt(PreInit);
896 Clause->setPostUpdateExpr(PostUpdate);
897 return Clause;
898}
899
900OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
901 unsigned N) {
902 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
903 return new (Mem) OMPTaskReductionClause(N);
904}
905
906void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
907 assert(Privates.size() == varlist_size() &&
908 "Number of private copies is not the same as the preallocated buffer");
909 llvm::copy(Privates, varlist_end());
910}
911
912void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
913 assert(
914 LHSExprs.size() == varlist_size() &&
915 "Number of LHS expressions is not the same as the preallocated buffer");
916 llvm::copy(LHSExprs, getPrivates().end());
917}
918
919void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
920 assert(
921 RHSExprs.size() == varlist_size() &&
922 "Number of RHS expressions is not the same as the preallocated buffer");
923 llvm::copy(RHSExprs, getLHSExprs().end());
924}
925
926void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
927 assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
928 "expressions is not the same "
929 "as the preallocated buffer");
930 llvm::copy(ReductionOps, getRHSExprs().end());
931}
932
933void OMPInReductionClause::setTaskgroupDescriptors(
934 ArrayRef<Expr *> TaskgroupDescriptors) {
935 assert(TaskgroupDescriptors.size() == varlist_size() &&
936 "Number of in reduction descriptors is not the same as the "
937 "preallocated buffer");
938 llvm::copy(TaskgroupDescriptors, getReductionOps().end());
939}
940
941OMPInReductionClause *OMPInReductionClause::Create(
942 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
944 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
945 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
946 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
947 ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
948 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));
949 OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
950 StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
951 Clause->setVarRefs(VL);
952 Clause->setPrivates(Privates);
953 Clause->setLHSExprs(LHSExprs);
954 Clause->setRHSExprs(RHSExprs);
955 Clause->setReductionOps(ReductionOps);
956 Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
957 Clause->setPreInitStmt(PreInit);
958 Clause->setPostUpdateExpr(PostUpdate);
959 return Clause;
960}
961
962OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
963 unsigned N) {
964 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));
965 return new (Mem) OMPInReductionClause(N);
966}
967
968OMPSizesClause *OMPSizesClause::Create(const ASTContext &C,
969 SourceLocation StartLoc,
970 SourceLocation LParenLoc,
971 SourceLocation EndLoc,
972 ArrayRef<Expr *> Sizes) {
973 OMPSizesClause *Clause = CreateEmpty(C, Sizes.size());
974 Clause->setLocStart(StartLoc);
975 Clause->setLParenLoc(LParenLoc);
976 Clause->setLocEnd(EndLoc);
977 Clause->setSizesRefs(Sizes);
978 return Clause;
979}
980
982 unsigned NumSizes) {
983 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumSizes));
984 return new (Mem) OMPSizesClause(NumSizes);
985}
986
987OMPPermutationClause *OMPPermutationClause::Create(const ASTContext &C,
988 SourceLocation StartLoc,
989 SourceLocation LParenLoc,
990 SourceLocation EndLoc,
991 ArrayRef<Expr *> Args) {
992 OMPPermutationClause *Clause = CreateEmpty(C, Args.size());
993 Clause->setLocStart(StartLoc);
994 Clause->setLParenLoc(LParenLoc);
995 Clause->setLocEnd(EndLoc);
996 Clause->setArgRefs(Args);
997 return Clause;
998}
999
1001 unsigned NumLoops) {
1002 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumLoops));
1003 return new (Mem) OMPPermutationClause(NumLoops);
1004}
1005
1006OMPFullClause *OMPFullClause::Create(const ASTContext &C,
1007 SourceLocation StartLoc,
1008 SourceLocation EndLoc) {
1009 OMPFullClause *Clause = CreateEmpty(C);
1010 Clause->setLocStart(StartLoc);
1011 Clause->setLocEnd(EndLoc);
1012 return Clause;
1013}
1014
1016 return new (C) OMPFullClause();
1017}
1018
1019OMPPartialClause *OMPPartialClause::Create(const ASTContext &C,
1020 SourceLocation StartLoc,
1021 SourceLocation LParenLoc,
1022 SourceLocation EndLoc,
1023 Expr *Factor) {
1024 OMPPartialClause *Clause = CreateEmpty(C);
1025 Clause->setLocStart(StartLoc);
1026 Clause->setLParenLoc(LParenLoc);
1027 Clause->setLocEnd(EndLoc);
1028 Clause->setFactor(Factor);
1029 return Clause;
1030}
1031
1032OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
1033 return new (C) OMPPartialClause();
1034}
1035
1038 SourceLocation LParenLoc, SourceLocation FirstLoc,
1039 SourceLocation CountLoc, SourceLocation EndLoc,
1040 Expr *First, Expr *Count) {
1041 OMPLoopRangeClause *Clause = CreateEmpty(C);
1042 Clause->setLocStart(StartLoc);
1043 Clause->setLParenLoc(LParenLoc);
1044 Clause->setFirstLoc(FirstLoc);
1045 Clause->setCountLoc(CountLoc);
1046 Clause->setLocEnd(EndLoc);
1047 Clause->setFirst(First);
1048 Clause->setCount(Count);
1049 return Clause;
1050}
1051
1052OMPLoopRangeClause *OMPLoopRangeClause::CreateEmpty(const ASTContext &C) {
1053 return new (C) OMPLoopRangeClause();
1054}
1055
1056OMPAllocateClause *OMPAllocateClause::Create(
1057 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
1058 Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc,
1059 OpenMPAllocateClauseModifier Modifier1, SourceLocation Modifier1Loc,
1060 OpenMPAllocateClauseModifier Modifier2, SourceLocation Modifier2Loc,
1061 SourceLocation EndLoc, ArrayRef<Expr *> VL) {
1062
1063 // Allocate space for private variables and initializer expressions.
1064 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1065 auto *Clause = new (Mem) OMPAllocateClause(
1066 StartLoc, LParenLoc, Allocator, Alignment, ColonLoc, Modifier1,
1067 Modifier1Loc, Modifier2, Modifier2Loc, EndLoc, VL.size());
1068
1069 Clause->setVarRefs(VL);
1070 return Clause;
1071}
1072
1074 unsigned N) {
1075 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1076 return new (Mem) OMPAllocateClause(N);
1077}
1078
1079OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
1080 SourceLocation StartLoc,
1081 SourceLocation LParenLoc,
1082 SourceLocation EndLoc,
1083 ArrayRef<Expr *> VL) {
1084 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
1085 OMPFlushClause *Clause =
1086 new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
1087 Clause->setVarRefs(VL);
1088 return Clause;
1089}
1090
1091OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
1092 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1093 return new (Mem) OMPFlushClause(N);
1094}
1095
1096OMPDepobjClause *OMPDepobjClause::Create(const ASTContext &C,
1097 SourceLocation StartLoc,
1098 SourceLocation LParenLoc,
1099 SourceLocation RParenLoc,
1100 Expr *Depobj) {
1101 auto *Clause = new (C) OMPDepobjClause(StartLoc, LParenLoc, RParenLoc);
1102 Clause->setDepobj(Depobj);
1103 return Clause;
1104}
1105
1107 return new (C) OMPDepobjClause();
1108}
1109
1112 SourceLocation LParenLoc, SourceLocation EndLoc,
1113 DependDataTy Data, Expr *DepModifier,
1114 ArrayRef<Expr *> VL, unsigned NumLoops) {
1115 void *Mem = C.Allocate(
1116 totalSizeToAlloc<Expr *>(VL.size() + /*depend-modifier*/ 1 + NumLoops),
1117 alignof(OMPDependClause));
1118 OMPDependClause *Clause = new (Mem)
1119 OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
1120 Clause->setDependencyKind(Data.DepKind);
1121 Clause->setDependencyLoc(Data.DepLoc);
1122 Clause->setColonLoc(Data.ColonLoc);
1123 Clause->setOmpAllMemoryLoc(Data.OmpAllMemoryLoc);
1124 Clause->setModifier(DepModifier);
1125 Clause->setVarRefs(VL);
1126 for (unsigned I = 0 ; I < NumLoops; ++I)
1127 Clause->setLoopData(I, nullptr);
1128 return Clause;
1129}
1130
1131OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,
1132 unsigned NumLoops) {
1133 void *Mem =
1134 C.Allocate(totalSizeToAlloc<Expr *>(N + /*depend-modifier*/ 1 + NumLoops),
1135 alignof(OMPDependClause));
1136 return new (Mem) OMPDependClause(N, NumLoops);
1137}
1138
1139void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
1140 assert((getDependencyKind() == OMPC_DEPEND_sink ||
1141 getDependencyKind() == OMPC_DEPEND_source) &&
1142 NumLoop < NumLoops &&
1143 "Expected sink or source depend + loop index must be less number of "
1144 "loops.");
1145 auto *It = std::next(getVarRefs().end(), NumLoop + 1);
1146 *It = Cnt;
1147}
1148
1150 assert((getDependencyKind() == OMPC_DEPEND_sink ||
1151 getDependencyKind() == OMPC_DEPEND_source) &&
1152 NumLoop < NumLoops &&
1153 "Expected sink or source depend + loop index must be less number of "
1154 "loops.");
1155 auto *It = std::next(getVarRefs().end(), NumLoop + 1);
1156 return *It;
1157}
1158
1159const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {
1160 assert((getDependencyKind() == OMPC_DEPEND_sink ||
1161 getDependencyKind() == OMPC_DEPEND_source) &&
1162 NumLoop < NumLoops &&
1163 "Expected sink or source depend + loop index must be less number of "
1164 "loops.");
1165 const auto *It = std::next(getVarRefs().end(), NumLoop + 1);
1166 return *It;
1167}
1168
1169void OMPDependClause::setModifier(Expr *DepModifier) {
1170 *getVarRefs().end() = DepModifier;
1171}
1173
1175 MappableExprComponentListsRef ComponentLists) {
1176 unsigned TotalNum = 0u;
1177 for (auto &C : ComponentLists)
1178 TotalNum += C.size();
1179 return TotalNum;
1180}
1181
1183 ArrayRef<const ValueDecl *> Declarations) {
1185 for (const ValueDecl *D : Declarations) {
1186 const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
1187 UniqueDecls.insert(VD);
1188 }
1189 return UniqueDecls.size();
1190}
1191
1194 assert(!isa<OMPArrayShapingExpr>(Exp) &&
1195 "Cannot get element-type from array-shaping expr.");
1196
1197 // Unless we are handling array-section expressions, including
1198 // array-subscripts, derefs, we can rely on getType.
1199 if (!isa<ArraySectionExpr>(Exp))
1201
1202 // For array-sections, we need to find the type of one element of
1203 // the section.
1204 const auto *OASE = cast<ArraySectionExpr>(Exp);
1205
1206 QualType BaseType = ArraySectionExpr::getBaseOriginalType(OASE->getBase());
1207
1208 QualType ElemTy;
1209 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
1210 ElemTy = ATy->getElementType();
1211 else
1212 ElemTy = BaseType->getPointeeType();
1213
1214 ElemTy = ElemTy.getNonReferenceType().getCanonicalType();
1215 return ElemTy;
1216}
1217
1218std::pair<const Expr *, std::optional<size_t>>
1220 MappableExprComponentListRef Components, OpenMPDirectiveKind CurDirKind) {
1221
1222 // If we only have a single component, we have a map like "map(p)", which
1223 // cannot have a base-pointer.
1224 if (Components.size() < 2)
1225 return {nullptr, std::nullopt};
1226
1227 // Only check for non-contiguous sections on target_update, since we can
1228 // assume array-sections are contiguous on maps on other constructs, even if
1229 // we are not sure of it at compile-time, like for a[1:x][2].
1230 if (Components.back().isNonContiguous() && CurDirKind == OMPD_target_update)
1231 return {nullptr, std::nullopt};
1232
1233 // To find the attach base-pointer, we start with the second component,
1234 // stripping away one component at a time, until we reach a pointer Expr
1235 // (that is not a binary operator). The first such pointer should be the
1236 // attach base-pointer for the component list.
1237 for (auto [I, Component] : llvm::enumerate(Components)) {
1238 // Skip past the first component.
1239 if (I == 0)
1240 continue;
1241
1242 const Expr *CurExpr = Component.getAssociatedExpression();
1243 if (!CurExpr)
1244 break;
1245
1246 // If CurExpr is something like `p + 10`, we need to ignore it, since
1247 // we are looking for `p`.
1248 if (isa<BinaryOperator>(CurExpr))
1249 continue;
1250
1251 // Keep going until we reach an Expr of pointer type.
1252 QualType CurType = getComponentExprElementType(CurExpr);
1253 if (!CurType->isPointerType())
1254 continue;
1255
1256 // We have found a pointer Expr. This must be the attach pointer.
1257 return {CurExpr, Components.size() - I};
1258 }
1259
1260 return {nullptr, std::nullopt};
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<OpenMPMapModifierKind> MapModifiers,
1268 ArrayRef<SourceLocation> MapModifiersLoc,
1269 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
1270 OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
1272 Sizes.NumVars = Vars.size();
1274 Sizes.NumComponentLists = ComponentLists.size();
1275 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1276
1277 // We need to allocate:
1278 // 2 x NumVars x Expr* - we have an original list expression and an associated
1279 // user-defined mapper for each clause list entry.
1280 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1281 // with each component list.
1282 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1283 // number of lists for each unique declaration and the size of each component
1284 // list.
1285 // NumComponents x MappableComponent - the total of all the components in all
1286 // the lists.
1287 void *Mem = C.Allocate(
1288 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1290 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1292 Sizes.NumComponents));
1293 OMPMapClause *Clause = new (Mem)
1294 OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
1295 Type, TypeIsImplicit, TypeLoc, Locs, Sizes);
1296
1297 Clause->setVarRefs(Vars);
1298 Clause->setUDMapperRefs(UDMapperRefs);
1299 Clause->setIteratorModifier(IteratorModifier);
1300 Clause->setClauseInfo(Declarations, ComponentLists);
1301 Clause->setMapType(Type);
1302 Clause->setMapLoc(TypeLoc);
1303 return Clause;
1304}
1305
1308 const OMPMappableExprListSizeTy &Sizes) {
1309 void *Mem = C.Allocate(
1310 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1312 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1314 Sizes.NumComponents));
1315 OMPMapClause *Clause = new (Mem) OMPMapClause(Sizes);
1316 Clause->setIteratorModifier(nullptr);
1317 return Clause;
1318}
1319
1321 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1322 ArrayRef<ValueDecl *> Declarations,
1323 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1324 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
1325 ArrayRef<SourceLocation> MotionModifiersLoc,
1326 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1328 Sizes.NumVars = Vars.size();
1330 Sizes.NumComponentLists = ComponentLists.size();
1331 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1332
1333 // We need to allocate:
1334 // 2 x NumVars x Expr* - we have an original list expression and an associated
1335 // user-defined mapper for each clause list entry.
1336 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1337 // with each component list.
1338 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1339 // number of lists for each unique declaration and the size of each component
1340 // list.
1341 // NumComponents x MappableComponent - the total of all the components in all
1342 // the lists.
1343 void *Mem = C.Allocate(
1344 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1346 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1348 Sizes.NumComponents));
1349
1350 auto *Clause = new (Mem) OMPToClause(MotionModifiers, MotionModifiersLoc,
1351 UDMQualifierLoc, MapperId, Locs, Sizes);
1352
1353 Clause->setVarRefs(Vars);
1354 Clause->setUDMapperRefs(UDMapperRefs);
1355 Clause->setClauseInfo(Declarations, ComponentLists);
1356 return Clause;
1357}
1358
1360 const OMPMappableExprListSizeTy &Sizes) {
1361 void *Mem = C.Allocate(
1362 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1364 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1366 Sizes.NumComponents));
1367 return new (Mem) OMPToClause(Sizes);
1368}
1369
1371 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1372 ArrayRef<ValueDecl *> Declarations,
1373 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1374 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
1375 ArrayRef<SourceLocation> MotionModifiersLoc,
1376 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1378 Sizes.NumVars = Vars.size();
1380 Sizes.NumComponentLists = ComponentLists.size();
1381 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1382
1383 // We need to allocate:
1384 // 2 x NumVars x Expr* - we have an original list expression and an associated
1385 // user-defined mapper for each clause list entry.
1386 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1387 // with each component list.
1388 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1389 // number of lists for each unique declaration and the size of each component
1390 // list.
1391 // NumComponents x MappableComponent - the total of all the components in all
1392 // the lists.
1393 void *Mem = C.Allocate(
1394 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1396 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1398 Sizes.NumComponents));
1399
1400 auto *Clause =
1401 new (Mem) OMPFromClause(MotionModifiers, MotionModifiersLoc,
1402 UDMQualifierLoc, MapperId, Locs, Sizes);
1403
1404 Clause->setVarRefs(Vars);
1405 Clause->setUDMapperRefs(UDMapperRefs);
1406 Clause->setClauseInfo(Declarations, ComponentLists);
1407 return Clause;
1408}
1409
1412 const OMPMappableExprListSizeTy &Sizes) {
1413 void *Mem = C.Allocate(
1414 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1416 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1418 Sizes.NumComponents));
1419 return new (Mem) OMPFromClause(Sizes);
1420}
1421
1422void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
1423 assert(VL.size() == varlist_size() &&
1424 "Number of private copies is not the same as the preallocated buffer");
1425 llvm::copy(VL, varlist_end());
1426}
1427
1428void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
1429 assert(VL.size() == varlist_size() &&
1430 "Number of inits is not the same as the preallocated buffer");
1431 llvm::copy(VL, getPrivateCopies().end());
1432}
1433
1434OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
1435 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1436 ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
1437 ArrayRef<ValueDecl *> Declarations,
1438 MappableExprComponentListsRef ComponentLists) {
1440 Sizes.NumVars = Vars.size();
1442 Sizes.NumComponentLists = ComponentLists.size();
1443 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1444
1445 // We need to allocate:
1446 // NumVars x Expr* - we have an original list expression for each clause
1447 // list entry.
1448 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1449 // with each component list.
1450 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1451 // number of lists for each unique declaration and the size of each component
1452 // list.
1453 // NumComponents x MappableComponent - the total of all the components in all
1454 // the lists.
1455 void *Mem = C.Allocate(
1456 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1458 3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1460 Sizes.NumComponents));
1461
1462 OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
1463
1464 Clause->setVarRefs(Vars);
1465 Clause->setPrivateCopies(PrivateVars);
1466 Clause->setInits(Inits);
1467 Clause->setClauseInfo(Declarations, ComponentLists);
1468 return Clause;
1469}
1470
1473 const OMPMappableExprListSizeTy &Sizes) {
1474 void *Mem = C.Allocate(
1475 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1477 3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1479 Sizes.NumComponents));
1480 return new (Mem) OMPUseDevicePtrClause(Sizes);
1481}
1482
1485 ArrayRef<Expr *> Vars,
1486 ArrayRef<ValueDecl *> Declarations,
1487 MappableExprComponentListsRef ComponentLists) {
1489 Sizes.NumVars = Vars.size();
1491 Sizes.NumComponentLists = ComponentLists.size();
1492 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1493
1494 // We need to allocate:
1495 // 3 x NumVars x Expr* - we have an original list expression for each clause
1496 // list entry and an equal number of private copies and inits.
1497 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1498 // with each component list.
1499 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1500 // number of lists for each unique declaration and the size of each component
1501 // list.
1502 // NumComponents x MappableComponent - the total of all the components in all
1503 // the lists.
1504 void *Mem = C.Allocate(
1505 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1507 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1509 Sizes.NumComponents));
1510
1511 auto *Clause = new (Mem) OMPUseDeviceAddrClause(Locs, Sizes);
1512
1513 Clause->setVarRefs(Vars);
1514 Clause->setClauseInfo(Declarations, ComponentLists);
1515 return Clause;
1516}
1517
1520 const OMPMappableExprListSizeTy &Sizes) {
1521 void *Mem = C.Allocate(
1522 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1524 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1526 Sizes.NumComponents));
1527 return new (Mem) OMPUseDeviceAddrClause(Sizes);
1528}
1529
1532 ArrayRef<Expr *> Vars,
1533 ArrayRef<ValueDecl *> Declarations,
1534 MappableExprComponentListsRef ComponentLists) {
1536 Sizes.NumVars = Vars.size();
1538 Sizes.NumComponentLists = ComponentLists.size();
1539 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1540
1541 // We need to allocate:
1542 // NumVars x Expr* - we have an original list expression for each clause list
1543 // entry.
1544 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1545 // with each component list.
1546 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1547 // number of lists for each unique declaration and the size of each component
1548 // list.
1549 // NumComponents x MappableComponent - the total of all the components in all
1550 // the lists.
1551 void *Mem = C.Allocate(
1552 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1554 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1556 Sizes.NumComponents));
1557
1558 OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);
1559
1560 Clause->setVarRefs(Vars);
1561 Clause->setClauseInfo(Declarations, ComponentLists);
1562 return Clause;
1563}
1564
1567 const OMPMappableExprListSizeTy &Sizes) {
1568 void *Mem = C.Allocate(
1569 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1571 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1573 Sizes.NumComponents));
1574 return new (Mem) OMPIsDevicePtrClause(Sizes);
1575}
1576
1579 ArrayRef<Expr *> Vars,
1580 ArrayRef<ValueDecl *> Declarations,
1581 MappableExprComponentListsRef ComponentLists) {
1583 Sizes.NumVars = Vars.size();
1585 Sizes.NumComponentLists = ComponentLists.size();
1586 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1587
1588 // We need to allocate:
1589 // NumVars x Expr* - we have an original list expression for each clause list
1590 // entry.
1591 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1592 // with each component list.
1593 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1594 // number of lists for each unique declaration and the size of each component
1595 // list.
1596 // NumComponents x MappableComponent - the total of all the components in all
1597 // the lists.
1598 void *Mem = C.Allocate(
1599 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1601 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1603 Sizes.NumComponents));
1604
1605 auto *Clause = new (Mem) OMPHasDeviceAddrClause(Locs, Sizes);
1606
1607 Clause->setVarRefs(Vars);
1608 Clause->setClauseInfo(Declarations, ComponentLists);
1609 return Clause;
1610}
1611
1614 const OMPMappableExprListSizeTy &Sizes) {
1615 void *Mem = C.Allocate(
1616 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1618 Sizes.NumVars, Sizes.NumUniqueDeclarations,
1620 Sizes.NumComponents));
1621 return new (Mem) OMPHasDeviceAddrClause(Sizes);
1622}
1623
1624OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
1625 SourceLocation StartLoc,
1626 SourceLocation LParenLoc,
1627 SourceLocation EndLoc,
1628 ArrayRef<Expr *> VL) {
1629 // Allocate space for nontemporal variables + private references.
1630 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
1631 auto *Clause =
1632 new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
1633 Clause->setVarRefs(VL);
1634 return Clause;
1635}
1636
1638 unsigned N) {
1639 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
1640 return new (Mem) OMPNontemporalClause(N);
1641}
1642
1644 assert(VL.size() == varlist_size() && "Number of private references is not "
1645 "the same as the preallocated buffer");
1646 llvm::copy(VL, varlist_end());
1647}
1648
1649OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C,
1650 SourceLocation StartLoc,
1651 SourceLocation LParenLoc,
1652 SourceLocation EndLoc,
1653 ArrayRef<Expr *> VL) {
1654 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1655 auto *Clause =
1656 new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1657 Clause->setVarRefs(VL);
1658 return Clause;
1659}
1660
1662 unsigned N) {
1663 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1664 return new (Mem) OMPInclusiveClause(N);
1665}
1666
1667OMPExclusiveClause *OMPExclusiveClause::Create(const ASTContext &C,
1668 SourceLocation StartLoc,
1669 SourceLocation LParenLoc,
1670 SourceLocation EndLoc,
1671 ArrayRef<Expr *> VL) {
1672 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1673 auto *Clause =
1674 new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1675 Clause->setVarRefs(VL);
1676 return Clause;
1677}
1678
1680 unsigned N) {
1681 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1682 return new (Mem) OMPExclusiveClause(N);
1683}
1684
1685void OMPUsesAllocatorsClause::setAllocatorsData(
1687 assert(Data.size() == NumOfAllocators &&
1688 "Size of allocators data is not the same as the preallocated buffer.");
1689 for (unsigned I = 0, E = Data.size(); I < E; ++I) {
1690 const OMPUsesAllocatorsClause::Data &D = Data[I];
1691 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1692 static_cast<int>(ExprOffsets::Allocator)] =
1693 D.Allocator;
1694 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1695 static_cast<int>(
1696 ExprOffsets::AllocatorTraits)] =
1698 getTrailingObjects<
1699 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1700 static_cast<int>(ParenLocsOffsets::LParen)] =
1701 D.LParenLoc;
1702 getTrailingObjects<
1703 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1704 static_cast<int>(ParenLocsOffsets::RParen)] =
1705 D.RParenLoc;
1706 }
1707}
1708
1712 Data.Allocator =
1713 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1714 static_cast<int>(ExprOffsets::Allocator)];
1716 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1717 static_cast<int>(
1718 ExprOffsets::AllocatorTraits)];
1719 Data.LParenLoc = getTrailingObjects<
1720 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1721 static_cast<int>(ParenLocsOffsets::LParen)];
1722 Data.RParenLoc = getTrailingObjects<
1723 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1724 static_cast<int>(ParenLocsOffsets::RParen)];
1725 return Data;
1726}
1727
1730 SourceLocation LParenLoc, SourceLocation EndLoc,
1732 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
1733 static_cast<int>(ExprOffsets::Total) * Data.size(),
1734 static_cast<int>(ParenLocsOffsets::Total) * Data.size()));
1735 auto *Clause = new (Mem)
1736 OMPUsesAllocatorsClause(StartLoc, LParenLoc, EndLoc, Data.size());
1737 Clause->setAllocatorsData(Data);
1738 return Clause;
1739}
1740
1743 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
1744 static_cast<int>(ExprOffsets::Total) * N,
1745 static_cast<int>(ParenLocsOffsets::Total) * N));
1746 return new (Mem) OMPUsesAllocatorsClause(N);
1747}
1748
1751 SourceLocation LParenLoc, SourceLocation ColonLoc,
1752 SourceLocation EndLoc, Expr *Modifier,
1753 ArrayRef<Expr *> Locators) {
1754 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Locators.size() + 1));
1755 auto *Clause = new (Mem)
1756 OMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, Locators.size());
1757 Clause->setModifier(Modifier);
1758 Clause->setVarRefs(Locators);
1759 return Clause;
1760}
1761
1763 unsigned N) {
1764 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1));
1765 return new (Mem) OMPAffinityClause(N);
1766}
1767
1768OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar,
1769 OMPInteropInfo &InteropInfo,
1770 SourceLocation StartLoc,
1771 SourceLocation LParenLoc,
1772 SourceLocation VarLoc,
1773 SourceLocation EndLoc) {
1774
1775 void *Mem =
1776 C.Allocate(totalSizeToAlloc<Expr *>(InteropInfo.PreferTypes.size() + 1));
1777 auto *Clause = new (Mem) OMPInitClause(
1778 InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc, LParenLoc,
1779 VarLoc, EndLoc, InteropInfo.PreferTypes.size() + 1);
1780 Clause->setInteropVar(InteropVar);
1781 llvm::copy(InteropInfo.PreferTypes, Clause->getTrailingObjects() + 1);
1782 return Clause;
1783}
1784
1785OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {
1786 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1787 return new (Mem) OMPInitClause(N);
1788}
1789
1792 SourceLocation KLoc, SourceLocation StartLoc,
1793 SourceLocation LParenLoc, SourceLocation EndLoc) {
1794 return new (C) OMPBindClause(K, KLoc, StartLoc, LParenLoc, EndLoc);
1795}
1796
1798 return new (C) OMPBindClause();
1799}
1800
1803 SourceLocation LParenLoc, SourceLocation EndLoc,
1805 SourceLocation DepLoc, SourceLocation ColonLoc,
1806 ArrayRef<Expr *> VL, unsigned NumLoops) {
1807 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + NumLoops),
1808 alignof(OMPDoacrossClause));
1809 OMPDoacrossClause *Clause = new (Mem)
1810 OMPDoacrossClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
1811 Clause->setDependenceType(DepType);
1812 Clause->setDependenceLoc(DepLoc);
1813 Clause->setColonLoc(ColonLoc);
1814 Clause->setVarRefs(VL);
1815 for (unsigned I = 0; I < NumLoops; ++I)
1816 Clause->setLoopData(I, nullptr);
1817 return Clause;
1818}
1819
1821 unsigned N,
1822 unsigned NumLoops) {
1823 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + NumLoops),
1824 alignof(OMPDoacrossClause));
1825 return new (Mem) OMPDoacrossClause(N, NumLoops);
1826}
1827
1828void OMPDoacrossClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
1829 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1830 auto *It = std::next(getVarRefs().end(), NumLoop);
1831 *It = Cnt;
1832}
1833
1835 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1836 auto *It = std::next(getVarRefs().end(), NumLoop);
1837 return *It;
1838}
1839
1840const Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) const {
1841 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1842 const auto *It = std::next(getVarRefs().end(), NumLoop);
1843 return *It;
1844}
1845
1846OMPAbsentClause *OMPAbsentClause::Create(const ASTContext &C,
1848 SourceLocation Loc,
1849 SourceLocation LLoc,
1850 SourceLocation RLoc) {
1851 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(DKVec.size()),
1852 alignof(OMPAbsentClause));
1853 auto *AC = new (Mem) OMPAbsentClause(Loc, LLoc, RLoc, DKVec.size());
1854 AC->setDirectiveKinds(DKVec);
1855 return AC;
1856}
1857
1858OMPAbsentClause *OMPAbsentClause::CreateEmpty(const ASTContext &C, unsigned K) {
1859 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(K),
1860 alignof(OMPAbsentClause));
1861 return new (Mem) OMPAbsentClause(K);
1862}
1863
1864OMPContainsClause *OMPContainsClause::Create(
1867 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(DKVec.size()),
1868 alignof(OMPContainsClause));
1869 auto *CC = new (Mem) OMPContainsClause(Loc, LLoc, RLoc, DKVec.size());
1870 CC->setDirectiveKinds(DKVec);
1871 return CC;
1872}
1873
1875 unsigned K) {
1876 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(K),
1877 alignof(OMPContainsClause));
1878 return new (Mem) OMPContainsClause(K);
1879}
1880
1881OMPNumTeamsClause *OMPNumTeamsClause::Create(
1882 const ASTContext &C, OpenMPDirectiveKind CaptureRegion,
1883 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
1884 ArrayRef<Expr *> VL, Stmt *PreInit) {
1885 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1886 OMPNumTeamsClause *Clause =
1887 new (Mem) OMPNumTeamsClause(C, StartLoc, LParenLoc, EndLoc, VL.size());
1888 Clause->setVarRefs(VL);
1889 Clause->setPreInitStmt(PreInit, CaptureRegion);
1890 return Clause;
1891}
1892
1894 unsigned N) {
1895 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1896 return new (Mem) OMPNumTeamsClause(N);
1897}
1898
1899OMPThreadLimitClause *OMPThreadLimitClause::Create(
1900 const ASTContext &C, OpenMPDirectiveKind CaptureRegion,
1901 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
1902 ArrayRef<Expr *> VL, Stmt *PreInit) {
1903 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1904 OMPThreadLimitClause *Clause =
1905 new (Mem) OMPThreadLimitClause(C, StartLoc, LParenLoc, EndLoc, VL.size());
1906 Clause->setVarRefs(VL);
1907 Clause->setPreInitStmt(PreInit, CaptureRegion);
1908 return Clause;
1909}
1910
1912 unsigned N) {
1913 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1914 return new (Mem) OMPThreadLimitClause(N);
1915}
1916
1917//===----------------------------------------------------------------------===//
1918// OpenMP clauses printing methods
1919//===----------------------------------------------------------------------===//
1920
1921void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
1922 OS << "if(";
1923 if (Node->getNameModifier() != OMPD_unknown)
1924 OS << getOpenMPDirectiveName(Node->getNameModifier(), Version) << ": ";
1925 Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1926 OS << ")";
1927}
1928
1929void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
1930 OS << "final(";
1931 Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1932 OS << ")";
1933}
1934
1935void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
1936 OS << "num_threads(";
1938 if (Modifier != OMPC_NUMTHREADS_unknown) {
1939 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
1940 << ": ";
1941 }
1942 Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
1943 OS << ")";
1944}
1945
1946void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
1947 OS << "align(";
1948 Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
1949 OS << ")";
1950}
1951
1952void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
1953 OS << "safelen(";
1954 Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
1955 OS << ")";
1956}
1957
1958void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
1959 OS << "simdlen(";
1960 Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);
1961 OS << ")";
1962}
1963
1964void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {
1965 OS << "sizes(";
1966 bool First = true;
1967 for (auto *Size : Node->getSizesRefs()) {
1968 if (!First)
1969 OS << ", ";
1970 Size->printPretty(OS, nullptr, Policy, 0);
1971 First = false;
1972 }
1973 OS << ")";
1974}
1975
1976void OMPClausePrinter::VisitOMPPermutationClause(OMPPermutationClause *Node) {
1977 OS << "permutation(";
1978 llvm::interleaveComma(Node->getArgsRefs(), OS, [&](const Expr *E) {
1979 E->printPretty(OS, nullptr, Policy, 0);
1980 });
1981 OS << ")";
1982}
1983
1984void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }
1985
1986void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
1987 OS << "partial";
1988
1989 if (Expr *Factor = Node->getFactor()) {
1990 OS << '(';
1991 Factor->printPretty(OS, nullptr, Policy, 0);
1992 OS << ')';
1993 }
1994}
1995
1996void OMPClausePrinter::VisitOMPLoopRangeClause(OMPLoopRangeClause *Node) {
1997 OS << "looprange";
1998
1999 Expr *First = Node->getFirst();
2000 Expr *Count = Node->getCount();
2001
2002 if (First && Count) {
2003 OS << "(";
2004 First->printPretty(OS, nullptr, Policy, 0);
2005 OS << ",";
2006 Count->printPretty(OS, nullptr, Policy, 0);
2007 OS << ")";
2008 }
2009}
2010
2011void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
2012 OS << "allocator(";
2013 Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
2014 OS << ")";
2015}
2016
2017void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
2018 OS << "collapse(";
2019 Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
2020 OS << ")";
2021}
2022
2023void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
2024 OS << "detach(";
2025 Node->getEventHandler()->printPretty(OS, nullptr, Policy, 0);
2026 OS << ")";
2027}
2028
2029void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
2030 OS << "default("
2031 << getOpenMPSimpleClauseTypeName(OMPC_default,
2032 unsigned(Node->getDefaultKind()));
2033 if (Version >= 60 && Node->getDefaultVC() != OMPC_DEFAULT_VC_all) {
2034 OS << ":"
2036 }
2037
2038 OS << ")";
2039}
2040
2041void OMPClausePrinter::VisitOMPThreadsetClause(OMPThreadsetClause *Node) {
2042 OS << "threadset("
2043 << getOpenMPSimpleClauseTypeName(OMPC_threadset,
2044 unsigned(Node->getThreadsetKind()))
2045 << ")";
2046}
2047
2048void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
2049 OS << "proc_bind("
2050 << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
2051 unsigned(Node->getProcBindKind()))
2052 << ")";
2053}
2054
2055void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
2056 OS << "unified_address";
2057}
2058
2059void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
2061 OS << "unified_shared_memory";
2062}
2063
2064void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
2065 OS << "reverse_offload";
2066}
2067
2068void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
2070 OS << "dynamic_allocators";
2071}
2072
2073void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
2075 OS << "atomic_default_mem_order("
2076 << getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order,
2078 << ")";
2079}
2080
2081void OMPClausePrinter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {
2082 OS << "self_maps";
2083}
2084
2085void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
2086 OS << "at(" << getOpenMPSimpleClauseTypeName(OMPC_at, Node->getAtKind())
2087 << ")";
2088}
2089
2090void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
2091 OS << "severity("
2092 << getOpenMPSimpleClauseTypeName(OMPC_severity, Node->getSeverityKind())
2093 << ")";
2094}
2095
2096void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
2097 OS << "message(";
2098 if (Expr *E = Node->getMessageString())
2099 E->printPretty(OS, nullptr, Policy);
2100 OS << ")";
2101}
2102
2103void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
2104 OS << "schedule(";
2106 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
2107 Node->getFirstScheduleModifier());
2109 OS << ", ";
2110 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
2112 }
2113 OS << ": ";
2114 }
2115 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
2116 if (auto *E = Node->getChunkSize()) {
2117 OS << ", ";
2118 E->printPretty(OS, nullptr, Policy);
2119 }
2120 OS << ")";
2121}
2122
2123void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
2124 OS << "ordered";
2125 if (auto *Num = Node->getNumForLoops()) {
2126 OS << "(";
2127 Num->printPretty(OS, nullptr, Policy, 0);
2128 OS << ")";
2129 }
2130}
2131
2132void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *Node) {
2133 OS << "nowait";
2134 if (auto *Cond = Node->getCondition()) {
2135 OS << "(";
2136 Cond->printPretty(OS, nullptr, Policy, 0);
2137 OS << ")";
2138 }
2139}
2140
2141void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
2142 OS << "untied";
2143}
2144
2145void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
2146 OS << "nogroup";
2147}
2148
2149void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
2150 OS << "mergeable";
2151}
2152
2153void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
2154
2155void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
2156
2157void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
2158 OS << "update";
2159 if (Node->isExtended()) {
2160 OS << "(";
2162 Node->getDependencyKind());
2163 OS << ")";
2164 }
2165}
2166
2167void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
2168 OS << "capture";
2169}
2170
2171void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
2172 OS << "compare";
2173}
2174
2175void OMPClausePrinter::VisitOMPFailClause(OMPFailClause *Node) {
2176 OS << "fail";
2177 if (Node) {
2178 OS << "(";
2180 Node->getClauseKind(), static_cast<int>(Node->getFailParameter()));
2181 OS << ")";
2182 }
2183}
2184
2185void OMPClausePrinter::VisitOMPAbsentClause(OMPAbsentClause *Node) {
2186 OS << "absent(";
2187 bool First = true;
2188 for (auto &D : Node->getDirectiveKinds()) {
2189 if (!First)
2190 OS << ", ";
2191 OS << getOpenMPDirectiveName(D, Version);
2192 First = false;
2193 }
2194 OS << ")";
2195}
2196
2197void OMPClausePrinter::VisitOMPHoldsClause(OMPHoldsClause *Node) {
2198 OS << "holds(";
2199 Node->getExpr()->printPretty(OS, nullptr, Policy, 0);
2200 OS << ")";
2201}
2202
2203void OMPClausePrinter::VisitOMPContainsClause(OMPContainsClause *Node) {
2204 OS << "contains(";
2205 bool First = true;
2206 for (auto &D : Node->getDirectiveKinds()) {
2207 if (!First)
2208 OS << ", ";
2209 OS << getOpenMPDirectiveName(D, Version);
2210 First = false;
2211 }
2212 OS << ")";
2213}
2214
2215void OMPClausePrinter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {
2216 OS << "no_openmp";
2217}
2218
2219void OMPClausePrinter::VisitOMPNoOpenMPRoutinesClause(
2221 OS << "no_openmp_routines";
2222}
2223
2224void OMPClausePrinter::VisitOMPNoOpenMPConstructsClause(
2226 OS << "no_openmp_constructs";
2227}
2228
2229void OMPClausePrinter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {
2230 OS << "no_parallelism";
2231}
2232
2233void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
2234 OS << "seq_cst";
2235}
2236
2237void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
2238 OS << "acq_rel";
2239}
2240
2241void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
2242 OS << "acquire";
2243}
2244
2245void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
2246 OS << "release";
2247}
2248
2249void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
2250 OS << "relaxed";
2251}
2252
2253void OMPClausePrinter::VisitOMPWeakClause(OMPWeakClause *) { OS << "weak"; }
2254
2255void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
2256 OS << "threads";
2257}
2258
2259void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
2260
2261void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
2262 OS << "device(";
2263 OpenMPDeviceClauseModifier Modifier = Node->getModifier();
2264 if (Modifier != OMPC_DEVICE_unknown) {
2265 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
2266 << ": ";
2267 }
2268 Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
2269 OS << ")";
2270}
2271
2272void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
2273 if (!Node->varlist_empty()) {
2274 OS << "num_teams";
2275 VisitOMPClauseList(Node, '(');
2276 OS << ")";
2277 }
2278}
2279
2280void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
2281 if (!Node->varlist_empty()) {
2282 OS << "thread_limit";
2283 VisitOMPClauseList(Node, '(');
2284 OS << ")";
2285 }
2286}
2287
2288void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
2289 OS << "priority(";
2290 Node->getPriority()->printPretty(OS, nullptr, Policy, 0);
2291 OS << ")";
2292}
2293
2294void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
2295 OS << "grainsize(";
2296 OpenMPGrainsizeClauseModifier Modifier = Node->getModifier();
2297 if (Modifier != OMPC_GRAINSIZE_unknown) {
2298 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
2299 << ": ";
2300 }
2301 Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);
2302 OS << ")";
2303}
2304
2305void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
2306 OS << "num_tasks(";
2307 OpenMPNumTasksClauseModifier Modifier = Node->getModifier();
2308 if (Modifier != OMPC_NUMTASKS_unknown) {
2309 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
2310 << ": ";
2311 }
2312 Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
2313 OS << ")";
2314}
2315
2316void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
2317 OS << "hint(";
2318 Node->getHint()->printPretty(OS, nullptr, Policy, 0);
2319 OS << ")";
2320}
2321
2322void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
2323 OS << "init(";
2324 bool First = true;
2325 for (const Expr *E : Node->prefs()) {
2326 if (First)
2327 OS << "prefer_type(";
2328 else
2329 OS << ",";
2330 E->printPretty(OS, nullptr, Policy);
2331 First = false;
2332 }
2333 if (!First)
2334 OS << "), ";
2335 if (Node->getIsTarget())
2336 OS << "target";
2337 if (Node->getIsTargetSync()) {
2338 if (Node->getIsTarget())
2339 OS << ", ";
2340 OS << "targetsync";
2341 }
2342 OS << " : ";
2343 Node->getInteropVar()->printPretty(OS, nullptr, Policy);
2344 OS << ")";
2345}
2346
2347void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
2348 OS << "use(";
2349 Node->getInteropVar()->printPretty(OS, nullptr, Policy);
2350 OS << ")";
2351}
2352
2353void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {
2354 OS << "destroy";
2355 if (Expr *E = Node->getInteropVar()) {
2356 OS << "(";
2357 E->printPretty(OS, nullptr, Policy);
2358 OS << ")";
2359 }
2360}
2361
2362void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {
2363 OS << "novariants";
2364 if (Expr *E = Node->getCondition()) {
2365 OS << "(";
2366 E->printPretty(OS, nullptr, Policy, 0);
2367 OS << ")";
2368 }
2369}
2370
2371void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {
2372 OS << "nocontext";
2373 if (Expr *E = Node->getCondition()) {
2374 OS << "(";
2375 E->printPretty(OS, nullptr, Policy, 0);
2376 OS << ")";
2377 }
2378}
2379
2380template<typename T>
2381void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
2382 for (typename T::varlist_iterator I = Node->varlist_begin(),
2383 E = Node->varlist_end();
2384 I != E; ++I) {
2385 assert(*I && "Expected non-null Stmt");
2386 OS << (I == Node->varlist_begin() ? StartSym : ',');
2387 if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
2388 if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
2389 DRE->printPretty(OS, nullptr, Policy, 0);
2390 else
2391 DRE->getDecl()->printQualifiedName(OS);
2392 } else
2393 (*I)->printPretty(OS, nullptr, Policy, 0);
2394 }
2395}
2396
2397void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
2398 if (Node->varlist_empty())
2399 return;
2400
2401 Expr *FirstModifier = nullptr;
2402 Expr *SecondModifier = nullptr;
2403 auto FirstAllocMod = Node->getFirstAllocateModifier();
2404 auto SecondAllocMod = Node->getSecondAllocateModifier();
2405 bool FirstUnknown = FirstAllocMod == OMPC_ALLOCATE_unknown;
2406 bool SecondUnknown = SecondAllocMod == OMPC_ALLOCATE_unknown;
2407 if (FirstAllocMod == OMPC_ALLOCATE_allocator ||
2408 (FirstAllocMod == OMPC_ALLOCATE_unknown && Node->getAllocator())) {
2409 FirstModifier = Node->getAllocator();
2410 SecondModifier = Node->getAlignment();
2411 } else {
2412 FirstModifier = Node->getAlignment();
2413 SecondModifier = Node->getAllocator();
2414 }
2415
2416 OS << "allocate";
2417 // If we have any explicit modifiers.
2418 if (FirstModifier) {
2419 OS << "(";
2420 if (!FirstUnknown) {
2421 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), FirstAllocMod);
2422 OS << "(";
2423 }
2424 FirstModifier->printPretty(OS, nullptr, Policy, 0);
2425 if (!FirstUnknown)
2426 OS << ")";
2427 if (SecondModifier) {
2428 OS << ", ";
2429 if (!SecondUnknown) {
2431 SecondAllocMod);
2432 OS << "(";
2433 }
2434 SecondModifier->printPretty(OS, nullptr, Policy, 0);
2435 if (!SecondUnknown)
2436 OS << ")";
2437 }
2438 OS << ":";
2439 VisitOMPClauseList(Node, ' ');
2440 } else {
2441 // No modifiers. Just print the variable list.
2442 VisitOMPClauseList(Node, '(');
2443 }
2444 OS << ")";
2445}
2446
2447void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
2448 if (!Node->varlist_empty()) {
2449 OS << "private";
2450 VisitOMPClauseList(Node, '(');
2451 OS << ")";
2452 }
2453}
2454
2455void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
2456 if (!Node->varlist_empty()) {
2457 OS << "firstprivate";
2458 VisitOMPClauseList(Node, '(');
2459 OS << ")";
2460 }
2461}
2462
2463void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
2464 if (!Node->varlist_empty()) {
2465 OS << "lastprivate";
2466 OpenMPLastprivateModifier LPKind = Node->getKind();
2467 if (LPKind != OMPC_LASTPRIVATE_unknown) {
2468 OS << "("
2469 << getOpenMPSimpleClauseTypeName(OMPC_lastprivate, Node->getKind())
2470 << ":";
2471 }
2472 VisitOMPClauseList(Node, LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
2473 OS << ")";
2474 }
2475}
2476
2477void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
2478 if (!Node->varlist_empty()) {
2479 OS << "shared";
2480 VisitOMPClauseList(Node, '(');
2481 OS << ")";
2482 }
2483}
2484
2485void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
2486 if (!Node->varlist_empty()) {
2487 OS << "reduction(";
2488 if (Node->getModifierLoc().isValid())
2489 OS << getOpenMPSimpleClauseTypeName(OMPC_reduction, Node->getModifier())
2490 << ", ";
2491 NestedNameSpecifier Qualifier =
2495 if (!Qualifier && OOK != OO_None) {
2496 // Print reduction identifier in C format
2497 OS << getOperatorSpelling(OOK);
2498 } else {
2499 // Use C++ format
2500 Qualifier.print(OS, Policy);
2501 OS << Node->getNameInfo();
2502 }
2503 OS << ":";
2504 VisitOMPClauseList(Node, ' ');
2505 OS << ")";
2506 }
2507}
2508
2509void OMPClausePrinter::VisitOMPTaskReductionClause(
2510 OMPTaskReductionClause *Node) {
2511 if (!Node->varlist_empty()) {
2512 OS << "task_reduction(";
2513 NestedNameSpecifier Qualifier =
2517 if (!Qualifier && OOK != OO_None) {
2518 // Print reduction identifier in C format
2519 OS << getOperatorSpelling(OOK);
2520 } else {
2521 // Use C++ format
2522 Qualifier.print(OS, Policy);
2523 OS << Node->getNameInfo();
2524 }
2525 OS << ":";
2526 VisitOMPClauseList(Node, ' ');
2527 OS << ")";
2528 }
2529}
2530
2531void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
2532 if (!Node->varlist_empty()) {
2533 OS << "in_reduction(";
2534 NestedNameSpecifier Qualifier =
2538 if (!Qualifier && OOK != OO_None) {
2539 // Print reduction identifier in C format
2540 OS << getOperatorSpelling(OOK);
2541 } else {
2542 // Use C++ format
2543 Qualifier.print(OS, Policy);
2544 OS << Node->getNameInfo();
2545 }
2546 OS << ":";
2547 VisitOMPClauseList(Node, ' ');
2548 OS << ")";
2549 }
2550}
2551
2552void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
2553 if (!Node->varlist_empty()) {
2554 OS << "linear";
2555 VisitOMPClauseList(Node, '(');
2556 if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {
2557 OS << ": ";
2558 }
2559 if (Node->getModifierLoc().isValid()) {
2560 OS << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
2561 }
2562 if (Node->getStep() != nullptr) {
2563 if (Node->getModifierLoc().isValid()) {
2564 OS << ", ";
2565 }
2566 OS << "step(";
2567 Node->getStep()->printPretty(OS, nullptr, Policy, 0);
2568 OS << ")";
2569 }
2570 OS << ")";
2571 }
2572}
2573
2574void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
2575 if (!Node->varlist_empty()) {
2576 OS << "aligned";
2577 VisitOMPClauseList(Node, '(');
2578 if (Node->getAlignment() != nullptr) {
2579 OS << ": ";
2580 Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
2581 }
2582 OS << ")";
2583 }
2584}
2585
2586void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
2587 if (!Node->varlist_empty()) {
2588 OS << "copyin";
2589 VisitOMPClauseList(Node, '(');
2590 OS << ")";
2591 }
2592}
2593
2594void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
2595 if (!Node->varlist_empty()) {
2596 OS << "copyprivate";
2597 VisitOMPClauseList(Node, '(');
2598 OS << ")";
2599 }
2600}
2601
2602void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
2603 if (!Node->varlist_empty()) {
2604 VisitOMPClauseList(Node, '(');
2605 OS << ")";
2606 }
2607}
2608
2609void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
2610 OS << "(";
2611 Node->getDepobj()->printPretty(OS, nullptr, Policy, 0);
2612 OS << ")";
2613}
2614
2615void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
2616 OS << "depend(";
2617 if (Expr *DepModifier = Node->getModifier()) {
2618 DepModifier->printPretty(OS, nullptr, Policy);
2619 OS << ", ";
2620 }
2621 OpenMPDependClauseKind DepKind = Node->getDependencyKind();
2622 OpenMPDependClauseKind PrintKind = DepKind;
2623 bool IsOmpAllMemory = false;
2624 if (PrintKind == OMPC_DEPEND_outallmemory) {
2625 PrintKind = OMPC_DEPEND_out;
2626 IsOmpAllMemory = true;
2627 } else if (PrintKind == OMPC_DEPEND_inoutallmemory) {
2628 PrintKind = OMPC_DEPEND_inout;
2629 IsOmpAllMemory = true;
2630 }
2631 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), PrintKind);
2632 if (!Node->varlist_empty() || IsOmpAllMemory)
2633 OS << " :";
2634 VisitOMPClauseList(Node, ' ');
2635 if (IsOmpAllMemory) {
2636 OS << (Node->varlist_empty() ? " " : ",");
2637 OS << "omp_all_memory";
2638 }
2639 OS << ")";
2640}
2641
2642template <typename T>
2643static void PrintMapper(raw_ostream &OS, T *Node,
2644 const PrintingPolicy &Policy) {
2645 OS << '(';
2646 NestedNameSpecifier MapperNNS =
2647 Node->getMapperQualifierLoc().getNestedNameSpecifier();
2648 MapperNNS.print(OS, Policy);
2649 OS << Node->getMapperIdInfo() << ')';
2650}
2651
2652template <typename T>
2653static void PrintIterator(raw_ostream &OS, T *Node,
2654 const PrintingPolicy &Policy) {
2655 if (Expr *IteratorModifier = Node->getIteratorModifier())
2656 IteratorModifier->printPretty(OS, nullptr, Policy);
2657}
2658
2659void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
2660 if (!Node->varlist_empty()) {
2661 OS << "map(";
2662 if (Node->getMapType() != OMPC_MAP_unknown) {
2663 for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
2665 if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator) {
2666 PrintIterator(OS, Node, Policy);
2667 } else {
2668 OS << getOpenMPSimpleClauseTypeName(OMPC_map,
2669 Node->getMapTypeModifier(I));
2670 if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper)
2671 PrintMapper(OS, Node, Policy);
2672 }
2673 OS << ',';
2674 }
2675 }
2676 OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
2677 OS << ':';
2678 }
2679 VisitOMPClauseList(Node, ' ');
2680 OS << ")";
2681 }
2682}
2683
2684template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {
2685 if (Node->varlist_empty())
2686 return;
2687 OS << getOpenMPClauseName(Node->getClauseKind());
2688 unsigned ModifierCount = 0;
2689 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2690 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)
2691 ++ModifierCount;
2692 }
2693 if (ModifierCount) {
2694 OS << '(';
2695 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2696 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {
2697 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
2698 Node->getMotionModifier(I));
2699 if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)
2700 PrintMapper(OS, Node, Policy);
2701 if (I < ModifierCount - 1)
2702 OS << ", ";
2703 }
2704 }
2705 OS << ':';
2706 VisitOMPClauseList(Node, ' ');
2707 } else {
2708 VisitOMPClauseList(Node, '(');
2709 }
2710 OS << ")";
2711}
2712
2713void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
2714 VisitOMPMotionClause(Node);
2715}
2716
2717void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
2718 VisitOMPMotionClause(Node);
2719}
2720
2721void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
2722 OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
2723 OMPC_dist_schedule, Node->getDistScheduleKind());
2724 if (auto *E = Node->getChunkSize()) {
2725 OS << ", ";
2726 E->printPretty(OS, nullptr, Policy);
2727 }
2728 OS << ")";
2729}
2730
2731void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
2732 OS << "defaultmap(";
2733 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
2734 Node->getDefaultmapModifier());
2736 OS << ": ";
2737 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
2738 Node->getDefaultmapKind());
2739 }
2740 OS << ")";
2741}
2742
2743void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
2744 if (!Node->varlist_empty()) {
2745 OS << "use_device_ptr";
2746 VisitOMPClauseList(Node, '(');
2747 OS << ")";
2748 }
2749}
2750
2751void OMPClausePrinter::VisitOMPUseDeviceAddrClause(
2752 OMPUseDeviceAddrClause *Node) {
2753 if (!Node->varlist_empty()) {
2754 OS << "use_device_addr";
2755 VisitOMPClauseList(Node, '(');
2756 OS << ")";
2757 }
2758}
2759
2760void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
2761 if (!Node->varlist_empty()) {
2762 OS << "is_device_ptr";
2763 VisitOMPClauseList(Node, '(');
2764 OS << ")";
2765 }
2766}
2767
2768void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {
2769 if (!Node->varlist_empty()) {
2770 OS << "has_device_addr";
2771 VisitOMPClauseList(Node, '(');
2772 OS << ")";
2773 }
2774}
2775
2776void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
2777 if (!Node->varlist_empty()) {
2778 OS << "nontemporal";
2779 VisitOMPClauseList(Node, '(');
2780 OS << ")";
2781 }
2782}
2783
2784void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
2785 OS << "order(";
2787 OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getModifier());
2788 OS << ": ";
2789 }
2790 OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind()) << ")";
2791}
2792
2793void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
2794 if (!Node->varlist_empty()) {
2795 OS << "inclusive";
2796 VisitOMPClauseList(Node, '(');
2797 OS << ")";
2798 }
2799}
2800
2801void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
2802 if (!Node->varlist_empty()) {
2803 OS << "exclusive";
2804 VisitOMPClauseList(Node, '(');
2805 OS << ")";
2806 }
2807}
2808
2809void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
2811 if (Node->getNumberOfAllocators() == 0)
2812 return;
2813 OS << "uses_allocators(";
2814 for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {
2815 OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);
2816 Data.Allocator->printPretty(OS, nullptr, Policy);
2817 if (Data.AllocatorTraits) {
2818 OS << "(";
2819 Data.AllocatorTraits->printPretty(OS, nullptr, Policy);
2820 OS << ")";
2821 }
2822 if (I < E - 1)
2823 OS << ",";
2824 }
2825 OS << ")";
2826}
2827
2828void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
2829 if (Node->varlist_empty())
2830 return;
2831 OS << "affinity";
2832 char StartSym = '(';
2833 if (Expr *Modifier = Node->getModifier()) {
2834 OS << "(";
2835 Modifier->printPretty(OS, nullptr, Policy);
2836 OS << " :";
2837 StartSym = ' ';
2838 }
2839 VisitOMPClauseList(Node, StartSym);
2840 OS << ")";
2841}
2842
2843void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
2844 OS << "filter(";
2845 Node->getThreadID()->printPretty(OS, nullptr, Policy, 0);
2846 OS << ")";
2847}
2848
2849void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
2850 OS << "bind("
2851 << getOpenMPSimpleClauseTypeName(OMPC_bind, unsigned(Node->getBindKind()))
2852 << ")";
2853}
2854
2855void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
2856 OMPXDynCGroupMemClause *Node) {
2857 OS << "ompx_dyn_cgroup_mem(";
2858 Node->getSize()->printPretty(OS, nullptr, Policy, 0);
2859 OS << ")";
2860}
2861
2862void OMPClausePrinter::VisitOMPDynGroupprivateClause(
2864 OS << "dyn_groupprivate(";
2866 OS << getOpenMPSimpleClauseTypeName(OMPC_dyn_groupprivate,
2870 OS << ", ";
2872 OMPC_dyn_groupprivate, Node->getDynGroupprivateFallbackModifier());
2873 }
2874 OS << ": ";
2875 }
2876 Node->getSize()->printPretty(OS, nullptr, Policy, 0);
2877 OS << ')';
2878}
2879
2880void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {
2881 OS << "doacross(";
2883
2884 switch (DepType) {
2885 case OMPC_DOACROSS_source:
2886 OS << "source:";
2887 break;
2888 case OMPC_DOACROSS_sink:
2889 OS << "sink:";
2890 break;
2891 case OMPC_DOACROSS_source_omp_cur_iteration:
2892 OS << "source: omp_cur_iteration";
2893 break;
2894 case OMPC_DOACROSS_sink_omp_cur_iteration:
2895 OS << "sink: omp_cur_iteration - 1";
2896 break;
2897 default:
2898 llvm_unreachable("unknown docaross modifier");
2899 }
2900 VisitOMPClauseList(Node, ' ');
2901 OS << ")";
2902}
2903
2904void OMPClausePrinter::VisitOMPXAttributeClause(OMPXAttributeClause *Node) {
2905 OS << "ompx_attribute(";
2906 bool IsFirst = true;
2907 for (auto &Attr : Node->getAttrs()) {
2908 if (!IsFirst)
2909 OS << ", ";
2910 Attr->printPretty(OS, Policy);
2911 IsFirst = false;
2912 }
2913 OS << ")";
2914}
2915
2916void OMPClausePrinter::VisitOMPXBareClause(OMPXBareClause *Node) {
2917 OS << "ompx_bare";
2918}
2919
2921 VariantMatchInfo &VMI) const {
2922 for (const OMPTraitSet &Set : Sets) {
2923 for (const OMPTraitSelector &Selector : Set.Selectors) {
2924
2925 // User conditions are special as we evaluate the condition here.
2926 if (Selector.Kind == TraitSelector::user_condition) {
2927 assert(Selector.ScoreOrCondition &&
2928 "Ill-formed user condition, expected condition expression!");
2929 assert(Selector.Properties.size() == 1 &&
2930 Selector.Properties.front().Kind ==
2931 TraitProperty::user_condition_unknown &&
2932 "Ill-formed user condition, expected unknown trait property!");
2933
2934 if (std::optional<APSInt> CondVal =
2935 Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx))
2936 VMI.addTrait(CondVal->isZero() ? TraitProperty::user_condition_false
2937 : TraitProperty::user_condition_true,
2938 "<condition>");
2939 else
2940 VMI.addTrait(TraitProperty::user_condition_false, "<condition>");
2941 continue;
2942 }
2943
2944 std::optional<llvm::APSInt> Score;
2945 llvm::APInt *ScorePtr = nullptr;
2946 if (Selector.ScoreOrCondition) {
2947 if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx)))
2948 ScorePtr = &*Score;
2949 else
2950 VMI.addTrait(TraitProperty::user_condition_false,
2951 "<non-constant-score>");
2952 }
2953
2954 for (const OMPTraitProperty &Property : Selector.Properties)
2955 VMI.addTrait(Set.Kind, Property.Kind, Property.RawString, ScorePtr);
2956
2957 if (Set.Kind != TraitSet::construct)
2958 continue;
2959
2960 // TODO: This might not hold once we implement SIMD properly.
2961 assert(Selector.Properties.size() == 1 &&
2962 Selector.Properties.front().Kind ==
2963 getOpenMPContextTraitPropertyForSelector(
2964 Selector.Kind) &&
2965 "Ill-formed construct selector!");
2966 }
2967 }
2968}
2969
2970void OMPTraitInfo::print(llvm::raw_ostream &OS,
2971 const PrintingPolicy &Policy) const {
2972 bool FirstSet = true;
2973 for (const OMPTraitSet &Set : Sets) {
2974 if (!FirstSet)
2975 OS << ", ";
2976 FirstSet = false;
2977 OS << getOpenMPContextTraitSetName(Set.Kind) << "={";
2978
2979 bool FirstSelector = true;
2980 for (const OMPTraitSelector &Selector : Set.Selectors) {
2981 if (!FirstSelector)
2982 OS << ", ";
2983 FirstSelector = false;
2984 OS << getOpenMPContextTraitSelectorName(Selector.Kind);
2985
2986 bool AllowsTraitScore = false;
2987 bool RequiresProperty = false;
2988 isValidTraitSelectorForTraitSet(
2989 Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
2990
2991 if (!RequiresProperty)
2992 continue;
2993
2994 OS << "(";
2995 if (Selector.Kind == TraitSelector::user_condition) {
2996 if (Selector.ScoreOrCondition)
2997 Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
2998 else
2999 OS << "...";
3000 } else {
3001
3002 if (Selector.ScoreOrCondition) {
3003 OS << "score(";
3004 Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
3005 OS << "): ";
3006 }
3007
3008 bool FirstProperty = true;
3009 for (const OMPTraitProperty &Property : Selector.Properties) {
3010 if (!FirstProperty)
3011 OS << ", ";
3012 FirstProperty = false;
3013 OS << getOpenMPContextTraitPropertyName(Property.Kind,
3014 Property.RawString);
3015 }
3016 }
3017 OS << ")";
3018 }
3019 OS << "}";
3020 }
3021}
3022
3023std::string OMPTraitInfo::getMangledName() const {
3024 std::string MangledName;
3025 llvm::raw_string_ostream OS(MangledName);
3026 for (const OMPTraitSet &Set : Sets) {
3027 OS << '$' << 'S' << unsigned(Set.Kind);
3028 for (const OMPTraitSelector &Selector : Set.Selectors) {
3029
3030 bool AllowsTraitScore = false;
3031 bool RequiresProperty = false;
3032 isValidTraitSelectorForTraitSet(
3033 Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
3034 OS << '$' << 's' << unsigned(Selector.Kind);
3035
3036 if (!RequiresProperty ||
3037 Selector.Kind == TraitSelector::user_condition)
3038 continue;
3039
3040 for (const OMPTraitProperty &Property : Selector.Properties)
3041 OS << '$' << 'P'
3042 << getOpenMPContextTraitPropertyName(Property.Kind,
3043 Property.RawString);
3044 }
3045 }
3046 return MangledName;
3047}
3048
3049OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
3050 unsigned long U;
3051 do {
3052 if (!MangledName.consume_front("$S"))
3053 break;
3054 if (MangledName.consumeInteger(10, U))
3055 break;
3056 Sets.push_back(OMPTraitSet());
3057 OMPTraitSet &Set = Sets.back();
3058 Set.Kind = TraitSet(U);
3059 do {
3060 if (!MangledName.consume_front("$s"))
3061 break;
3062 if (MangledName.consumeInteger(10, U))
3063 break;
3064 Set.Selectors.push_back(OMPTraitSelector());
3065 OMPTraitSelector &Selector = Set.Selectors.back();
3066 Selector.Kind = TraitSelector(U);
3067 do {
3068 if (!MangledName.consume_front("$P"))
3069 break;
3070 Selector.Properties.push_back(OMPTraitProperty());
3071 OMPTraitProperty &Property = Selector.Properties.back();
3072 std::pair<StringRef, StringRef> PropRestPair = MangledName.split('$');
3073 Property.RawString = PropRestPair.first;
3074 Property.Kind = getOpenMPContextTraitPropertyKind(
3075 Set.Kind, Selector.Kind, PropRestPair.first);
3076 MangledName = MangledName.drop_front(PropRestPair.first.size());
3077 } while (true);
3078 } while (true);
3079 } while (true);
3080}
3081
3082llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
3083 const OMPTraitInfo &TI) {
3084 LangOptions LO;
3085 PrintingPolicy Policy(LO);
3086 TI.print(OS, Policy);
3087 return OS;
3088}
3089llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
3090 const OMPTraitInfo *TI) {
3091 return TI ? OS << *TI : OS;
3092}
3093
3095 ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
3096 const FunctionDecl *CurrentFunctionDecl,
3097 ArrayRef<llvm::omp::TraitProperty> ConstructTraits, int DeviceNum)
3098 : OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
3099 ASTCtx.getTargetInfo().getTriple(),
3100 ASTCtx.getLangOpts().OMPTargetTriples.empty()
3101 ? llvm::Triple()
3102 : ASTCtx.getLangOpts().OMPTargetTriples[0],
3103 DeviceNum),
3104 FeatureValidityCheck([&](StringRef FeatureName) {
3105 return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);
3106 }),
3107 DiagUnknownTrait(std::move(DiagUnknownTrait)) {
3108 ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);
3109
3110 for (llvm::omp::TraitProperty Property : ConstructTraits)
3111 addTrait(Property);
3112}
3113
3114bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
3115 auto It = FeatureMap.find(RawString);
3116 if (It != FeatureMap.end())
3117 return It->second;
3118 if (!FeatureValidityCheck(RawString))
3119 DiagUnknownTrait(RawString);
3120 return false;
3121}
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 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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:220
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:903
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:5266
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
This represents one expression.
Definition Expr.h:112
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:2000
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.
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
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 'absent' clause in the 'pragma omp assume' directive.
static OMPAbsentClause * CreateEmpty(const ASTContext &C, unsigned NumKinds)
static OMPAbsentClause * Create(const ASTContext &C, ArrayRef< OpenMPDirectiveKind > DKVec, SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc)
This represents 'acq_rel' clause in the 'pragma omp atomic|flush' directives.
This represents 'acquire' clause in the 'pragma omp atomic|flush' directives.
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.
This represents the 'align' clause in the 'pragma omp allocate' directive.
Expr * getAlignment() const
Returns alignment.
static OMPAlignClause * Create(const ASTContext &C, Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'align' clause with the given alignment.
This represents clause 'aligned' in the 'pragma omp ...' directives.
Expr * getAlignment()
Returns alignment.
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.
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.
This represents 'at' clause in the 'pragma omp error' directive.
OpenMPAtClauseKind getAtKind() const
Returns kind of the clause.
This represents 'atomic_default_mem_order' clause in the 'pragma omp requires' directive.
OpenMPAtomicDefaultMemOrderClauseKind getAtomicDefaultMemOrderKind() const
Returns kind of the clause.
This represents 'bind' clause in the 'pragma omp ...' directives.
OpenMPBindClauseKind getBindKind() const
Returns kind of the clause.
static OMPBindClause * Create(const ASTContext &C, OpenMPBindClauseKind K, SourceLocation KLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'bind' clause with kind K ('teams', 'parallel', or 'thread').
static OMPBindClause * CreateEmpty(const ASTContext &C)
Build an empty 'bind' clause.
This represents 'capture' clause in the 'pragma omp atomic' directive.
Class that represents a component of a mappable expression.
ArrayRef< MappableExprComponentList > MappableExprComponentListsRef
static unsigned getUniqueDeclarationsTotalNumber(ArrayRef< const ValueDecl * > Declarations)
static unsigned getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists)
ArrayRef< MappableComponent > MappableExprComponentListRef
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.
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 'compare' clause in the 'pragma omp atomic' directive.
This represents the 'contains' clause in the 'pragma omp assume' directive.
static OMPContainsClause * CreateEmpty(const ASTContext &C, unsigned NumKinds)
static OMPContainsClause * Create(const ASTContext &C, ArrayRef< OpenMPDirectiveKind > DKVec, SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc)
This represents clause 'copyin' in the 'pragma omp ...' directives.
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.
This represents clause 'copyprivate' in the 'pragma omp ...' directives.
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.
This represents 'default' clause in the 'pragma omp ...' directive.
llvm::omp::DefaultKind getDefaultKind() const
Returns kind of the clause.
OpenMPDefaultClauseVariableCategory getDefaultVC() const
This represents 'defaultmap' clause in the 'pragma omp ...' directive.
OpenMPDefaultmapClauseModifier getDefaultmapModifier() const
Get the modifier of the clause.
OpenMPDefaultmapClauseKind getDefaultmapKind() const
Get kind 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.
This represents implicit clause 'depobj' for the 'pragma omp depobj' directive.
static OMPDepobjClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Depobj)
Creates clause.
static OMPDepobjClause * CreateEmpty(const ASTContext &C)
Creates an empty clause.
Expr * getDepobj()
Returns depobj expression associated with the clause.
This represents 'destroy' clause in the 'pragma omp depobj' directive or the 'pragma omp interop' dir...
Expr * getInteropVar() const
Returns the interop variable.
This represents 'detach' clause in the 'pragma omp task' directive.
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.
MutableArrayRef< OpenMPDirectiveKind > getDirectiveKinds()
This represents 'dist_schedule' clause in the 'pragma omp ...' directive.
OpenMPDistScheduleClauseKind getDistScheduleKind() const
Get kind of the clause.
Expr * getChunkSize()
Get chunk size.
This represents the 'doacross' clause for the 'pragma omp ordered' directive.
void setLoopData(unsigned NumLoop, Expr *Cnt)
Set the loop data.
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.
OpenMPDoacrossClauseModifier getDependenceType() const
Get dependence type.
This represents 'dyn_groupprivate' clause in 'pragma omp target ...' and 'pragma omp teams ....
OpenMPDynGroupprivateClauseFallbackModifier getDynGroupprivateFallbackModifier() const
Get the second modifier of the clause.
OpenMPDynGroupprivateClauseModifier getDynGroupprivateModifier() const
Get the first modifier of the clause.
This represents 'dynamic_allocators' clause in the 'pragma omp requires' directive.
This represents clause 'exclusive' in the 'pragma omp scan' directive.
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 'fail' clause in the 'pragma omp atomic' directive.
OpenMPClauseKind getFailParameter() const
Gets the parameter (type memory-order-clause) in Fail clause.
This represents 'filter' clause in the 'pragma omp ...' directive.
Expr * getThreadID() const
Return thread identifier.
This represents 'final' clause in the 'pragma omp ...' directive.
child_range used_children()
Expr * getCondition() const
Returns condition.
This represents clause 'firstprivate' in the 'pragma omp ...' directives.
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
static OMPFirstprivateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
This represents implicit clause 'flush' for the 'pragma omp flush' directive.
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 * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Representation of the 'full' clause of the 'pragma omp unroll' directive.
static OMPFullClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Build an AST node for a 'full' clause.
static OMPFullClause * CreateEmpty(const ASTContext &C)
Build an empty 'full' AST node for deserialization.
This represents 'grainsize' clause in the 'pragma omp ...' directive.
Expr * getGrainsize() const
Return safe iteration space distance.
OpenMPGrainsizeClauseModifier getModifier() const
Gets modifier.
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.
This represents 'hint' clause in the 'pragma omp ...' directive.
Expr * getHint() const
Returns number of threads.
This represents the 'holds' clause in the 'pragma omp assume' directive.
Expr * getExpr() const
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 represents clause 'in_reduction' in the 'pragma omp task' directives.
static OMPInReductionClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
NestedNameSpecifierLoc getQualifierLoc() const
Gets the nested name specifier.
const DeclarationNameInfo & getNameInfo() const
Gets the name info for specified reduction identifier.
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
This represents clause 'inclusive' in the 'pragma omp scan' directive.
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.
This represents the 'init' clause in 'pragma omp ...' directives.
bool getIsTarget() const
Returns true is interop-type 'target' is used.
bool getIsTargetSync() const
Returns true is interop-type 'targetsync' is used.
static OMPInitClause * Create(const ASTContext &C, Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Creates a fully specified clause.
static OMPInitClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N expressions.
Expr * getInteropVar()
Returns the interop variable.
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 'lastprivate' in the 'pragma omp ...' directives.
static OMPLastprivateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
void setPrivateCopies(ArrayRef< Expr * > PrivateCopies)
Set list of helper expressions, required for generation of private copies of original lastprivate var...
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
OpenMPLastprivateModifier getKind() const
Lastprivate kind.
This represents clause 'linear' in the 'pragma omp ...' directives.
child_range used_children()
SourceLocation getModifierLoc() const
Return modifier location.
static OMPLinearClause * CreateEmpty(const ASTContext &C, unsigned NumVars)
Creates an empty clause with the place for NumVars variables.
Expr * getStep()
Returns linear step.
void setUpdates(ArrayRef< Expr * > UL)
Sets the list of update expressions for linear variables.
void setFinals(ArrayRef< Expr * > FL)
Sets the list of final update expressions for linear variables.
void setUsedExprs(ArrayRef< Expr * > UE)
Sets the list of used expressions for the linear clause.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation StepModifierLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
OpenMPLinearClauseKind getModifier() const
Return modifier.
This class represents the 'looprange' clause in the 'pragma omp fuse' directive.
Expr * getFirst() const
Get looprange 'first' expression.
static OMPLoopRangeClause * CreateEmpty(const ASTContext &C)
Build an empty 'looprange' clause node.
static OMPLoopRangeClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation FirstLoc, SourceLocation CountLoc, SourceLocation EndLoc, Expr *First, Expr *Count)
Build a 'looprange' clause AST node.
Expr * getCount() const
Get looprange 'count' expression.
This represents clause 'map' in the 'pragma omp ...' directives.
OpenMPMapClauseKind getMapType() const LLVM_READONLY
Fetches mapping kind for the clause.
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...
OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY
Fetches the map-type-modifier at 'Cnt' index of array of modifiers.
This represents 'mergeable' clause in the 'pragma omp ...' directive.
This represents the 'message' clause in the 'pragma omp error' and the 'pragma omp parallel' directiv...
Expr * getMessageString() const
Returns message string of the clause.
This represents the 'no_openmp' clause in the 'pragma omp assume' directive.
This represents the 'no_openmp_constructs' clause in the.
This represents the 'no_openmp_routines' clause in the 'pragma omp assume' directive.
This represents the 'no_parallelism' clause in the 'pragma omp assume' directive.
This represents 'nocontext' clause in the 'pragma omp ...' directive.
Expr * getCondition() const
Returns condition.
This represents 'nogroup' clause in the 'pragma omp ...' directive.
This represents clause 'nontemporal' in the 'pragma omp ...' directives.
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.
This represents 'nowait' 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.
Expr * getNumTasks() const
Return safe iteration space distance.
OpenMPNumTasksClauseModifier getModifier() const
Gets modifier.
This represents 'num_teams' clause in the 'pragma omp ...' directive.
static OMPNumTeamsClause * Create(const ASTContext &C, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, Stmt *PreInit)
Creates clause with a list of variables VL.
static OMPNumTeamsClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
This represents 'num_threads' clause in the 'pragma omp ...' directive.
OpenMPNumThreadsClauseModifier getModifier() const
Gets modifier.
Expr * getNumThreads() const
Returns number of threads.
llvm::iterator_range< child_iterator > child_range
This represents 'order' clause in the 'pragma omp ...' directive.
OpenMPOrderClauseKind getKind() const
Returns kind of the clause.
OpenMPOrderClauseModifier getModifier() const
Returns Modifier of the clause.
This represents 'ordered' clause in the 'pragma omp ...' directive.
void setLoopCounter(unsigned NumLoop, Expr *Counter)
Set loop counter for the specified loop.
Expr * getNumForLoops() const
Return the number of associated for-loops.
void setLoopNumIterations(unsigned NumLoop, Expr *NumIterations)
Set number of iterations for the specified loop.
ArrayRef< Expr * > getLoopNumIterations() const
Get number of iterations for all the loops.
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'ordered' clause.
static OMPOrderedClause * CreateEmpty(const ASTContext &C, unsigned NumLoops)
Build an empty clause.
Expr * getLoopCounter(unsigned NumLoop)
Get loops counter for the specified loop.
Representation of the 'partial' clause of the 'pragma omp unroll' directive.
static OMPPartialClause * CreateEmpty(const ASTContext &C)
Build an empty 'partial' AST node for deserialization.
static OMPPartialClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Factor)
Build an AST node for a 'partial' clause.
Expr * getFactor() const
Returns the argument of the clause or nullptr if not set.
This class represents the 'permutation' clause in the 'pragma omp interchange' directive.
MutableArrayRef< Expr * > getArgsRefs()
Returns the permutation index expressions.
static OMPPermutationClause * CreateEmpty(const ASTContext &C, unsigned NumLoops)
Build an empty 'permutation' AST node for deserialization.
static OMPPermutationClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Args)
Build a 'permutation' clause AST node.
This represents 'priority' clause in the 'pragma omp ...' directive.
Expr * getPriority()
Return Priority number.
This represents clause 'private' in the 'pragma omp ...' directives.
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL)
Creates clause with a list of variables VL.
static OMPPrivateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
This represents 'proc_bind' clause in the 'pragma omp ...' directive.
llvm::omp::ProcBindKind getProcBindKind() const
Returns kind of the clause.
This represents 'read' clause in the 'pragma omp atomic' directive.
This represents clause 'reduction' in the 'pragma omp ...' directives.
const DeclarationNameInfo & getNameInfo() const
Gets the name info for specified reduction identifier.
static OMPReductionClause * CreateEmpty(const ASTContext &C, unsigned N, OpenMPReductionClauseModifier Modifier)
Creates an empty clause with the place for N variables.
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > CopyOps, ArrayRef< Expr * > CopyArrayTemps, ArrayRef< Expr * > CopyArrayElems, Stmt *PreInit, Expr *PostUpdate, ArrayRef< bool > IsPrivateVarReduction, OpenMPOriginalSharingModifier OriginalSharingModifier)
Creates clause with a list of variables VL.
NestedNameSpecifierLoc getQualifierLoc() const
Gets the nested name specifier.
OpenMPReductionClauseModifier getModifier() const
Returns modifier.
SourceLocation getModifierLoc() const
Returns modifier location.
This represents 'relaxed' clause in the 'pragma omp atomic' directives.
This represents 'release' clause in the 'pragma omp atomic|flush' directives.
This represents 'reverse_offload' clause in the 'pragma omp requires' directive.
This represents 'simd' clause in the 'pragma omp ...' directive.
This represents 'safelen' clause in the 'pragma omp ...' directive.
Expr * getSafelen() const
Return safe iteration space distance.
This represents 'schedule' clause in the 'pragma omp ...' directive.
OpenMPScheduleClauseKind getScheduleKind() const
Get kind of the clause.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
Expr * getChunkSize()
Get chunk size.
This represents 'self_maps' clause in the 'pragma omp requires' directive.
This represents 'seq_cst' clause in the 'pragma omp atomic|flush' directives.
This represents the 'severity' clause in the 'pragma omp error' and the 'pragma omp parallel' directi...
OpenMPSeverityClauseKind getSeverityKind() const
Returns kind of the clause.
This represents clause 'shared' in the 'pragma omp ...' directives.
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static OMPSharedClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
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 clause 'task_reduction' in the 'pragma omp taskgroup' directives.
NestedNameSpecifierLoc getQualifierLoc() const
Gets the nested name specifier.
const DeclarationNameInfo & getNameInfo() const
Gets the name info for specified reduction identifier.
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static OMPTaskReductionClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
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, Stmt *PreInit)
Creates clause with a list of variables VL.
static OMPThreadLimitClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
This represents 'threads' clause in the 'pragma omp ...' directive.
This represents 'threadset' clause in the 'pragma omp task ...' directive.
OpenMPThreadsetKind getThreadsetKind() const
Returns kind of the clause.
This represents clause 'to' in the 'pragma omp ...' directives.
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, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...
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.
This represents 'unified_address' clause in the 'pragma omp requires' directive.
This represents 'unified_shared_memory' clause in the 'pragma omp requires' directive.
This represents 'untied' clause in the 'pragma omp ...' directive.
This represents 'update' clause in the 'pragma omp atomic' directive.
OpenMPDependClauseKind getDependencyKind() const
Gets the dependence kind in clause for 'depobj' directive.
static OMPUpdateClause * CreateEmpty(const ASTContext &C, bool IsExtended)
Creates an empty clause with the place for N variables.
static OMPUpdateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates clause for 'atomic' directive.
bool isExtended() const
Checks if the clause is the extended clauses for 'depobj' directive.
This represents the 'use' clause in 'pragma omp ...' directives.
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)
Creates clause with a list of variables Vars.
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.
unsigned getNumberOfAllocators() const
Returns number of allocators associated with the clause.
static OMPUsesAllocatorsClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< OMPUsesAllocatorsClause::Data > Data)
Creates clause with a list of allocators Data.
MutableArrayRef< Expr * > getVarRefs()
This represents 'weak' clause in the 'pragma omp atomic' directives.
This represents 'write' clause in the 'pragma omp atomic' directive.
This represents 'ompx_attribute' clause in a directive that might generate an outlined function.
ArrayRef< const Attr * > getAttrs() const
Returned the attributes parsed from this clause.
This represents 'ompx_bare' clause in the 'pragma omp target teams ...' directive.
This represents 'ompx_dyn_cgroup_mem' clause in the 'pragma omp target ...' directive.
Expr * getSize()
Return the size expression.
A (possibly-)qualified type.
Definition TypeBase.h:937
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:8463
QualType getCanonicalType() const
Definition TypeBase.h:8330
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
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:1833
bool isPointerType() const
Definition TypeBase.h:8515
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:752
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
OpenMPOriginalSharingModifier
OpenMP 6.0 original sharing modifiers.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ OMPC_ORDER_MODIFIER_unknown
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)
Expr * Cond
};
OpenMPDoacrossClauseModifier
OpenMP dependence types for 'doacross' clause.
static constexpr unsigned NumberOfOMPMapClauseModifiers
Number of allowed map-type-modifiers.
Definition OpenMPKinds.h:88
@ OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown
@ Property
The type of a property.
Definition TypeBase.h:911
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
const FunctionProtoType * T
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
@ OMPC_LASTPRIVATE_unknown
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
Definition OpenMPKinds.h:55
OpenMPGrainsizeClauseModifier
@ OMPC_GRAINSIZE_unknown
OpenMPNumTasksClauseModifier
@ OMPC_NUMTASKS_unknown
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
OpenMPNumThreadsClauseModifier
@ OMPC_NUMTHREADS_unknown
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
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.
llvm::SmallVector< Expr *, 4 > PreferTypes
This structure contains all sizes needed for by an OMPMappableExprListClause.
unsigned NumComponentLists
Number of component lists.
unsigned NumVars
Number of expressions listed.
unsigned NumUniqueDeclarations
Number of unique base declarations.
unsigned NumComponents
Total number of expression components.
Data for list of allocators.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * AllocatorTraits
Allocator traits.
This structure contains most locations needed for by an OMPVarListClause.
Describes how types, statements, expressions, and declarations should be printed.
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.