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