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