Thanks to visit codestin.com
Credit goes to clang.llvm.org

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