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