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

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