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