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
13#include "clang/AST/OpenMPClause.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Attr.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclOpenMP.h"
18#include "clang/Basic/LLVM.h"
19#include "clang/Basic/OpenMPKinds.h"
20#include "clang/Basic/TargetInfo.h"
21#include "llvm/ADT/SmallPtrSet.h"
22#include "llvm/Support/Casting.h"
23#include "llvm/Support/ErrorHandling.h"
24#include <algorithm>
25#include <cassert>
26#include <optional>
27
28using namespace clang;
29using namespace llvm;
30using namespace omp;
31
32OMPClause::child_range OMPClause::children() {
33 switch (getClauseKind()) {
34 default:
35 break;
36#define GEN_CLANG_CLAUSE_CLASS
37#define CLAUSE_CLASS(Enum, Str, Class) \
38 case Enum: \
39 return static_cast<Class *>(this)->children();
40#include "llvm/Frontend/OpenMP/OMP.inc"
41 }
42 llvm_unreachable("unknown OMPClause");
43}
44
45OMPClause::child_range OMPClause::used_children() {
46 switch (getClauseKind()) {
47#define GEN_CLANG_CLAUSE_CLASS
48#define CLAUSE_CLASS(Enum, Str, Class) \
49 case Enum: \
50 return static_cast<Class *>(this)->used_children();
51#define CLAUSE_NO_CLASS(Enum, Str) \
52 case Enum: \
53 break;
54#include "llvm/Frontend/OpenMP/OMP.inc"
55 }
56 llvm_unreachable("unknown OMPClause");
57}
58
59OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {
60 auto *Res = OMPClauseWithPreInit::get(C: const_cast<const OMPClause *>(C));
61 return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
62}
63
64const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
65 switch (C->getClauseKind()) {
66 case OMPC_schedule:
67 return static_cast<const OMPScheduleClause *>(C);
68 case OMPC_dist_schedule:
69 return static_cast<const OMPDistScheduleClause *>(C);
70 case OMPC_firstprivate:
71 return static_cast<const OMPFirstprivateClause *>(C);
72 case OMPC_lastprivate:
73 return static_cast<const OMPLastprivateClause *>(C);
74 case OMPC_reduction:
75 return static_cast<const OMPReductionClause *>(C);
76 case OMPC_task_reduction:
77 return static_cast<const OMPTaskReductionClause *>(C);
78 case OMPC_in_reduction:
79 return static_cast<const OMPInReductionClause *>(C);
80 case OMPC_linear:
81 return static_cast<const OMPLinearClause *>(C);
82 case OMPC_if:
83 return static_cast<const OMPIfClause *>(C);
84 case OMPC_num_threads:
85 return static_cast<const OMPNumThreadsClause *>(C);
86 case OMPC_num_teams:
87 return static_cast<const OMPNumTeamsClause *>(C);
88 case OMPC_thread_limit:
89 return static_cast<const OMPThreadLimitClause *>(C);
90 case OMPC_device:
91 return static_cast<const OMPDeviceClause *>(C);
92 case OMPC_grainsize:
93 return static_cast<const OMPGrainsizeClause *>(C);
94 case OMPC_num_tasks:
95 return static_cast<const OMPNumTasksClause *>(C);
96 case OMPC_final:
97 return static_cast<const OMPFinalClause *>(C);
98 case OMPC_priority:
99 return static_cast<const OMPPriorityClause *>(C);
100 case OMPC_novariants:
101 return static_cast<const OMPNovariantsClause *>(C);
102 case OMPC_nocontext:
103 return static_cast<const OMPNocontextClause *>(C);
104 case OMPC_filter:
105 return static_cast<const OMPFilterClause *>(C);
106 case OMPC_ompx_dyn_cgroup_mem:
107 return static_cast<const OMPXDynCGroupMemClause *>(C);
108 case OMPC_default:
109 case OMPC_proc_bind:
110 case OMPC_safelen:
111 case OMPC_simdlen:
112 case OMPC_sizes:
113 case OMPC_allocator:
114 case OMPC_allocate:
115 case OMPC_collapse:
116 case OMPC_private:
117 case OMPC_shared:
118 case OMPC_aligned:
119 case OMPC_copyin:
120 case OMPC_copyprivate:
121 case OMPC_ordered:
122 case OMPC_nowait:
123 case OMPC_untied:
124 case OMPC_mergeable:
125 case OMPC_threadprivate:
126 case OMPC_flush:
127 case OMPC_depobj:
128 case OMPC_read:
129 case OMPC_write:
130 case OMPC_update:
131 case OMPC_capture:
132 case OMPC_compare:
133 case OMPC_fail:
134 case OMPC_seq_cst:
135 case OMPC_acq_rel:
136 case OMPC_acquire:
137 case OMPC_release:
138 case OMPC_relaxed:
139 case OMPC_depend:
140 case OMPC_threads:
141 case OMPC_simd:
142 case OMPC_map:
143 case OMPC_nogroup:
144 case OMPC_hint:
145 case OMPC_defaultmap:
146 case OMPC_unknown:
147 case OMPC_uniform:
148 case OMPC_to:
149 case OMPC_from:
150 case OMPC_use_device_ptr:
151 case OMPC_use_device_addr:
152 case OMPC_is_device_ptr:
153 case OMPC_has_device_addr:
154 case OMPC_unified_address:
155 case OMPC_unified_shared_memory:
156 case OMPC_reverse_offload:
157 case OMPC_dynamic_allocators:
158 case OMPC_atomic_default_mem_order:
159 case OMPC_at:
160 case OMPC_severity:
161 case OMPC_message:
162 case OMPC_device_type:
163 case OMPC_match:
164 case OMPC_nontemporal:
165 case OMPC_order:
166 case OMPC_destroy:
167 case OMPC_detach:
168 case OMPC_inclusive:
169 case OMPC_exclusive:
170 case OMPC_uses_allocators:
171 case OMPC_affinity:
172 case OMPC_when:
173 case OMPC_bind:
174 case OMPC_ompx_bare:
175 break;
176 default:
177 break;
178 }
179
180 return nullptr;
181}
182
183OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) {
184 auto *Res = OMPClauseWithPostUpdate::get(C: const_cast<const OMPClause *>(C));
185 return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
186}
187
188const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) {
189 switch (C->getClauseKind()) {
190 case OMPC_lastprivate:
191 return static_cast<const OMPLastprivateClause *>(C);
192 case OMPC_reduction:
193 return static_cast<const OMPReductionClause *>(C);
194 case OMPC_task_reduction:
195 return static_cast<const OMPTaskReductionClause *>(C);
196 case OMPC_in_reduction:
197 return static_cast<const OMPInReductionClause *>(C);
198 case OMPC_linear:
199 return static_cast<const OMPLinearClause *>(C);
200 case OMPC_schedule:
201 case OMPC_dist_schedule:
202 case OMPC_firstprivate:
203 case OMPC_default:
204 case OMPC_proc_bind:
205 case OMPC_if:
206 case OMPC_final:
207 case OMPC_num_threads:
208 case OMPC_safelen:
209 case OMPC_simdlen:
210 case OMPC_sizes:
211 case OMPC_allocator:
212 case OMPC_allocate:
213 case OMPC_collapse:
214 case OMPC_private:
215 case OMPC_shared:
216 case OMPC_aligned:
217 case OMPC_copyin:
218 case OMPC_copyprivate:
219 case OMPC_ordered:
220 case OMPC_nowait:
221 case OMPC_untied:
222 case OMPC_mergeable:
223 case OMPC_threadprivate:
224 case OMPC_flush:
225 case OMPC_depobj:
226 case OMPC_read:
227 case OMPC_write:
228 case OMPC_update:
229 case OMPC_capture:
230 case OMPC_compare:
231 case OMPC_fail:
232 case OMPC_seq_cst:
233 case OMPC_acq_rel:
234 case OMPC_acquire:
235 case OMPC_release:
236 case OMPC_relaxed:
237 case OMPC_depend:
238 case OMPC_device:
239 case OMPC_threads:
240 case OMPC_simd:
241 case OMPC_map:
242 case OMPC_num_teams:
243 case OMPC_thread_limit:
244 case OMPC_priority:
245 case OMPC_grainsize:
246 case OMPC_nogroup:
247 case OMPC_num_tasks:
248 case OMPC_hint:
249 case OMPC_defaultmap:
250 case OMPC_unknown:
251 case OMPC_uniform:
252 case OMPC_to:
253 case OMPC_from:
254 case OMPC_use_device_ptr:
255 case OMPC_use_device_addr:
256 case OMPC_is_device_ptr:
257 case OMPC_has_device_addr:
258 case OMPC_unified_address:
259 case OMPC_unified_shared_memory:
260 case OMPC_reverse_offload:
261 case OMPC_dynamic_allocators:
262 case OMPC_atomic_default_mem_order:
263 case OMPC_at:
264 case OMPC_severity:
265 case OMPC_message:
266 case OMPC_device_type:
267 case OMPC_match:
268 case OMPC_nontemporal:
269 case OMPC_order:
270 case OMPC_destroy:
271 case OMPC_novariants:
272 case OMPC_nocontext:
273 case OMPC_detach:
274 case OMPC_inclusive:
275 case OMPC_exclusive:
276 case OMPC_uses_allocators:
277 case OMPC_affinity:
278 case OMPC_when:
279 case OMPC_bind:
280 break;
281 default:
282 break;
283 }
284
285 return nullptr;
286}
287
288/// Gets the address of the original, non-captured, expression used in the
289/// clause as the preinitializer.
290static Stmt **getAddrOfExprAsWritten(Stmt *S) {
291 if (!S)
292 return nullptr;
293 if (auto *DS = dyn_cast<DeclStmt>(Val: S)) {
294 assert(DS->isSingleDecl() && "Only single expression must be captured.");
295 if (auto *OED = dyn_cast<OMPCapturedExprDecl>(Val: DS->getSingleDecl()))
296 return OED->getInitAddress();
297 }
298 return nullptr;
299}
300
301OMPClause::child_range OMPIfClause::used_children() {
302 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
303 return child_range(C, C + 1);
304 return child_range(&Condition, &Condition + 1);
305}
306
307OMPClause::child_range OMPGrainsizeClause::used_children() {
308 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
309 return child_range(C, C + 1);
310 return child_range(&Grainsize, &Grainsize + 1);
311}
312
313OMPClause::child_range OMPNumTasksClause::used_children() {
314 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
315 return child_range(C, C + 1);
316 return child_range(&NumTasks, &NumTasks + 1);
317}
318
319OMPClause::child_range OMPFinalClause::used_children() {
320 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
321 return child_range(C, C + 1);
322 return children();
323}
324
325OMPClause::child_range OMPPriorityClause::used_children() {
326 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
327 return child_range(C, C + 1);
328 return child_range(&Priority, &Priority + 1);
329}
330
331OMPClause::child_range OMPNovariantsClause::used_children() {
332 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
333 return child_range(C, C + 1);
334 return children();
335}
336
337OMPClause::child_range OMPNocontextClause::used_children() {
338 if (Stmt **C = getAddrOfExprAsWritten(S: getPreInitStmt()))
339 return child_range(C, C + 1);
340 return children();
341}
342
343OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,
344 unsigned NumLoops,
345 SourceLocation StartLoc,
346 SourceLocation LParenLoc,
347 SourceLocation EndLoc) {
348 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * NumLoops));
349 auto *Clause =
350 new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);
351 for (unsigned I = 0; I < NumLoops; ++I) {
352 Clause->setLoopNumIterations(NumLoop: I, NumIterations: nullptr);
353 Clause->setLoopCounter(NumLoop: I, Counter: nullptr);
354 }
355 return Clause;
356}
357
358OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C,
359 unsigned NumLoops) {
360 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * NumLoops));
361 auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
362 for (unsigned I = 0; I < NumLoops; ++I) {
363 Clause->setLoopNumIterations(NumLoop: I, NumIterations: nullptr);
364 Clause->setLoopCounter(NumLoop: I, Counter: nullptr);
365 }
366 return Clause;
367}
368
369void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop,
370 Expr *NumIterations) {
371 assert(NumLoop < NumberOfLoops && "out of loops number.");
372 getTrailingObjects<Expr *>()[NumLoop] = NumIterations;
373}
374
375ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations() const {
376 return llvm::ArrayRef(getTrailingObjects<Expr *>(), NumberOfLoops);
377}
378
379void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {
380 assert(NumLoop < NumberOfLoops && "out of loops number.");
381 getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop] = Counter;
382}
383
384Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) {
385 assert(NumLoop < NumberOfLoops && "out of loops number.");
386 return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
387}
388
389const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
390 assert(NumLoop < NumberOfLoops && "out of loops number.");
391 return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
392}
393
394OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C,
395 SourceLocation StartLoc,
396 SourceLocation EndLoc) {
397 return new (C) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/false);
398}
399
400OMPUpdateClause *
401OMPUpdateClause::Create(const ASTContext &C, SourceLocation StartLoc,
402 SourceLocation LParenLoc, SourceLocation ArgumentLoc,
403 OpenMPDependClauseKind DK, SourceLocation EndLoc) {
404 void *Mem =
405 C.Allocate(Size: totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(Counts: 2, Counts: 1),
406 Align: alignof(OMPUpdateClause));
407 auto *Clause =
408 new (Mem) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/true);
409 Clause->setLParenLoc(LParenLoc);
410 Clause->setArgumentLoc(ArgumentLoc);
411 Clause->setDependencyKind(DK);
412 return Clause;
413}
414
415OMPUpdateClause *OMPUpdateClause::CreateEmpty(const ASTContext &C,
416 bool IsExtended) {
417 if (!IsExtended)
418 return new (C) OMPUpdateClause(/*IsExtended=*/false);
419 void *Mem =
420 C.Allocate(Size: totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(Counts: 2, Counts: 1),
421 Align: alignof(OMPUpdateClause));
422 auto *Clause = new (Mem) OMPUpdateClause(/*IsExtended=*/true);
423 Clause->IsExtended = true;
424 return Clause;
425}
426
427void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
428 assert(VL.size() == varlist_size() &&
429 "Number of private copies is not the same as the preallocated buffer");
430 std::copy(VL.begin(), VL.end(), varlist_end());
431}
432
433OMPPrivateClause *
434OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
435 SourceLocation LParenLoc, SourceLocation EndLoc,
436 ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
437 // Allocate space for private variables and initializer expressions.
438 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * VL.size()));
439 OMPPrivateClause *Clause =
440 new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
441 Clause->setVarRefs(VL);
442 Clause->setPrivateCopies(PrivateVL);
443 return Clause;
444}
445
446OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
447 unsigned N) {
448 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * N));
449 return new (Mem) OMPPrivateClause(N);
450}
451
452void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
453 assert(VL.size() == varlist_size() &&
454 "Number of private copies is not the same as the preallocated buffer");
455 std::copy(VL.begin(), VL.end(), varlist_end());
456}
457
458void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
459 assert(VL.size() == varlist_size() &&
460 "Number of inits is not the same as the preallocated buffer");
461 std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
462}
463
464OMPFirstprivateClause *
465OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
466 SourceLocation LParenLoc, SourceLocation EndLoc,
467 ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
468 ArrayRef<Expr *> InitVL, Stmt *PreInit) {
469 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 3 * VL.size()));
470 OMPFirstprivateClause *Clause =
471 new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
472 Clause->setVarRefs(VL);
473 Clause->setPrivateCopies(PrivateVL);
474 Clause->setInits(InitVL);
475 Clause->setPreInitStmt(S: PreInit);
476 return Clause;
477}
478
479OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
480 unsigned N) {
481 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 3 * N));
482 return new (Mem) OMPFirstprivateClause(N);
483}
484
485void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
486 assert(PrivateCopies.size() == varlist_size() &&
487 "Number of private copies is not the same as the preallocated buffer");
488 std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
489}
490
491void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
492 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
493 "not the same as the "
494 "preallocated buffer");
495 std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
496}
497
498void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
499 assert(DstExprs.size() == varlist_size() && "Number of destination "
500 "expressions is not the same as "
501 "the preallocated buffer");
502 std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
503}
504
505void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
506 assert(AssignmentOps.size() == varlist_size() &&
507 "Number of assignment expressions is not the same as the preallocated "
508 "buffer");
509 std::copy(AssignmentOps.begin(), AssignmentOps.end(),
510 getDestinationExprs().end());
511}
512
513OMPLastprivateClause *OMPLastprivateClause::Create(
514 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
515 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
516 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
517 OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,
518 SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {
519 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * VL.size()));
520 OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(
521 StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());
522 Clause->setVarRefs(VL);
523 Clause->setSourceExprs(SrcExprs);
524 Clause->setDestinationExprs(DstExprs);
525 Clause->setAssignmentOps(AssignmentOps);
526 Clause->setPreInitStmt(S: PreInit);
527 Clause->setPostUpdateExpr(PostUpdate);
528 return Clause;
529}
530
531OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
532 unsigned N) {
533 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * N));
534 return new (Mem) OMPLastprivateClause(N);
535}
536
537OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
538 SourceLocation StartLoc,
539 SourceLocation LParenLoc,
540 SourceLocation EndLoc,
541 ArrayRef<Expr *> VL) {
542 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
543 OMPSharedClause *Clause =
544 new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
545 Clause->setVarRefs(VL);
546 return Clause;
547}
548
549OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
550 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
551 return new (Mem) OMPSharedClause(N);
552}
553
554void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
555 assert(PL.size() == varlist_size() &&
556 "Number of privates is not the same as the preallocated buffer");
557 std::copy(PL.begin(), PL.end(), varlist_end());
558}
559
560void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
561 assert(IL.size() == varlist_size() &&
562 "Number of inits is not the same as the preallocated buffer");
563 std::copy(IL.begin(), IL.end(), getPrivates().end());
564}
565
566void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
567 assert(UL.size() == varlist_size() &&
568 "Number of updates is not the same as the preallocated buffer");
569 std::copy(UL.begin(), UL.end(), getInits().end());
570}
571
572void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
573 assert(FL.size() == varlist_size() &&
574 "Number of final updates is not the same as the preallocated buffer");
575 std::copy(FL.begin(), FL.end(), getUpdates().end());
576}
577
578void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {
579 assert(
580 UE.size() == varlist_size() + 1 &&
581 "Number of used expressions is not the same as the preallocated buffer");
582 std::copy(UE.begin(), UE.end(), getFinals().end() + 2);
583}
584
585OMPLinearClause *OMPLinearClause::Create(
586 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
587 OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
588 SourceLocation ColonLoc, SourceLocation StepModifierLoc,
589 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
590 ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
591 Expr *PostUpdate) {
592 // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
593 // (Step and CalcStep), list of used expression + step.
594 void *Mem =
595 C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * VL.size() + 2 + VL.size() + 1));
596 OMPLinearClause *Clause =
597 new (Mem) OMPLinearClause(StartLoc, LParenLoc, Modifier, ModifierLoc,
598 ColonLoc, StepModifierLoc, EndLoc, VL.size());
599 Clause->setVarRefs(VL);
600 Clause->setPrivates(PL);
601 Clause->setInits(IL);
602 // Fill update and final expressions with zeroes, they are provided later,
603 // after the directive construction.
604 std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
605 nullptr);
606 std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
607 nullptr);
608 std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),
609 nullptr);
610 Clause->setStep(Step);
611 Clause->setCalcStep(CalcStep);
612 Clause->setPreInitStmt(S: PreInit);
613 Clause->setPostUpdateExpr(PostUpdate);
614 return Clause;
615}
616
617OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
618 unsigned NumVars) {
619 // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
620 // (Step and CalcStep), list of used expression + step.
621 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * NumVars + 2 + NumVars +1));
622 return new (Mem) OMPLinearClause(NumVars);
623}
624
625OMPClause::child_range OMPLinearClause::used_children() {
626 // Range includes only non-nullptr elements.
627 return child_range(
628 reinterpret_cast<Stmt **>(getUsedExprs().begin()),
629 reinterpret_cast<Stmt **>(llvm::find(Range: getUsedExprs(), Val: nullptr)));
630}
631
632OMPAlignedClause *
633OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
634 SourceLocation LParenLoc, SourceLocation ColonLoc,
635 SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
636 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + 1));
637 OMPAlignedClause *Clause = new (Mem)
638 OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
639 Clause->setVarRefs(VL);
640 Clause->setAlignment(A);
641 return Clause;
642}
643
644OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
645 unsigned NumVars) {
646 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: NumVars + 1));
647 return new (Mem) OMPAlignedClause(NumVars);
648}
649
650OMPAlignClause *OMPAlignClause::Create(const ASTContext &C, Expr *A,
651 SourceLocation StartLoc,
652 SourceLocation LParenLoc,
653 SourceLocation EndLoc) {
654 return new (C) OMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
655}
656
657void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
658 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
659 "not the same as the "
660 "preallocated buffer");
661 std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
662}
663
664void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
665 assert(DstExprs.size() == varlist_size() && "Number of destination "
666 "expressions is not the same as "
667 "the preallocated buffer");
668 std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
669}
670
671void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
672 assert(AssignmentOps.size() == varlist_size() &&
673 "Number of assignment expressions is not the same as the preallocated "
674 "buffer");
675 std::copy(AssignmentOps.begin(), AssignmentOps.end(),
676 getDestinationExprs().end());
677}
678
679OMPCopyinClause *OMPCopyinClause::Create(
680 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
681 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
682 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
683 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 4 * VL.size()));
684 OMPCopyinClause *Clause =
685 new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
686 Clause->setVarRefs(VL);
687 Clause->setSourceExprs(SrcExprs);
688 Clause->setDestinationExprs(DstExprs);
689 Clause->setAssignmentOps(AssignmentOps);
690 return Clause;
691}
692
693OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
694 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 4 * N));
695 return new (Mem) OMPCopyinClause(N);
696}
697
698void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
699 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
700 "not the same as the "
701 "preallocated buffer");
702 std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
703}
704
705void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
706 assert(DstExprs.size() == varlist_size() && "Number of destination "
707 "expressions is not the same as "
708 "the preallocated buffer");
709 std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
710}
711
712void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
713 assert(AssignmentOps.size() == varlist_size() &&
714 "Number of assignment expressions is not the same as the preallocated "
715 "buffer");
716 std::copy(AssignmentOps.begin(), AssignmentOps.end(),
717 getDestinationExprs().end());
718}
719
720OMPCopyprivateClause *OMPCopyprivateClause::Create(
721 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
722 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
723 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
724 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 4 * VL.size()));
725 OMPCopyprivateClause *Clause =
726 new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
727 Clause->setVarRefs(VL);
728 Clause->setSourceExprs(SrcExprs);
729 Clause->setDestinationExprs(DstExprs);
730 Clause->setAssignmentOps(AssignmentOps);
731 return Clause;
732}
733
734OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
735 unsigned N) {
736 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 4 * N));
737 return new (Mem) OMPCopyprivateClause(N);
738}
739
740void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
741 assert(Privates.size() == varlist_size() &&
742 "Number of private copies is not the same as the preallocated buffer");
743 std::copy(Privates.begin(), Privates.end(), varlist_end());
744}
745
746void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
747 assert(
748 LHSExprs.size() == varlist_size() &&
749 "Number of LHS expressions is not the same as the preallocated buffer");
750 std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
751}
752
753void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
754 assert(
755 RHSExprs.size() == varlist_size() &&
756 "Number of RHS expressions is not the same as the preallocated buffer");
757 std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
758}
759
760void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
761 assert(ReductionOps.size() == varlist_size() && "Number of reduction "
762 "expressions is not the same "
763 "as the preallocated buffer");
764 std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
765}
766
767void OMPReductionClause::setInscanCopyOps(ArrayRef<Expr *> Ops) {
768 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
769 assert(Ops.size() == varlist_size() && "Number of copy "
770 "expressions is not the same "
771 "as the preallocated buffer");
772 llvm::copy(Range&: Ops, Out: getReductionOps().end());
773}
774
775void OMPReductionClause::setInscanCopyArrayTemps(
776 ArrayRef<Expr *> CopyArrayTemps) {
777 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
778 assert(CopyArrayTemps.size() == varlist_size() &&
779 "Number of copy temp expressions is not the same as the preallocated "
780 "buffer");
781 llvm::copy(Range&: CopyArrayTemps, Out: getInscanCopyOps().end());
782}
783
784void OMPReductionClause::setInscanCopyArrayElems(
785 ArrayRef<Expr *> CopyArrayElems) {
786 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
787 assert(CopyArrayElems.size() == varlist_size() &&
788 "Number of copy temp expressions is not the same as the preallocated "
789 "buffer");
790 llvm::copy(Range&: CopyArrayElems, Out: getInscanCopyArrayTemps().end());
791}
792
793OMPReductionClause *OMPReductionClause::Create(
794 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
795 SourceLocation ModifierLoc, SourceLocation EndLoc, SourceLocation ColonLoc,
796 OpenMPReductionClauseModifier Modifier, ArrayRef<Expr *> VL,
797 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
798 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
799 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
800 ArrayRef<Expr *> CopyOps, ArrayRef<Expr *> CopyArrayTemps,
801 ArrayRef<Expr *> CopyArrayElems, Stmt *PreInit, Expr *PostUpdate) {
802 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(
803 Counts: (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size()));
804 auto *Clause = new (Mem)
805 OMPReductionClause(StartLoc, LParenLoc, ModifierLoc, EndLoc, ColonLoc,
806 Modifier, VL.size(), QualifierLoc, NameInfo);
807 Clause->setVarRefs(VL);
808 Clause->setPrivates(Privates);
809 Clause->setLHSExprs(LHSExprs);
810 Clause->setRHSExprs(RHSExprs);
811 Clause->setReductionOps(ReductionOps);
812 Clause->setPreInitStmt(S: PreInit);
813 Clause->setPostUpdateExpr(PostUpdate);
814 if (Modifier == OMPC_REDUCTION_inscan) {
815 Clause->setInscanCopyOps(CopyOps);
816 Clause->setInscanCopyArrayTemps(CopyArrayTemps);
817 Clause->setInscanCopyArrayElems(CopyArrayElems);
818 } else {
819 assert(CopyOps.empty() &&
820 "copy operations are expected in inscan reductions only.");
821 assert(CopyArrayTemps.empty() &&
822 "copy array temps are expected in inscan reductions only.");
823 assert(CopyArrayElems.empty() &&
824 "copy array temps are expected in inscan reductions only.");
825 }
826 return Clause;
827}
828
829OMPReductionClause *
830OMPReductionClause::CreateEmpty(const ASTContext &C, unsigned N,
831 OpenMPReductionClauseModifier Modifier) {
832 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(
833 Counts: (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N));
834 auto *Clause = new (Mem) OMPReductionClause(N);
835 Clause->setModifier(Modifier);
836 return Clause;
837}
838
839void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
840 assert(Privates.size() == varlist_size() &&
841 "Number of private copies is not the same as the preallocated buffer");
842 std::copy(Privates.begin(), Privates.end(), varlist_end());
843}
844
845void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
846 assert(
847 LHSExprs.size() == varlist_size() &&
848 "Number of LHS expressions is not the same as the preallocated buffer");
849 std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
850}
851
852void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
853 assert(
854 RHSExprs.size() == varlist_size() &&
855 "Number of RHS expressions is not the same as the preallocated buffer");
856 std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
857}
858
859void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
860 assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
861 "expressions is not the same "
862 "as the preallocated buffer");
863 std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
864}
865
866OMPTaskReductionClause *OMPTaskReductionClause::Create(
867 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
868 SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
869 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
870 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
871 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
872 Expr *PostUpdate) {
873 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * VL.size()));
874 OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
875 StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
876 Clause->setVarRefs(VL);
877 Clause->setPrivates(Privates);
878 Clause->setLHSExprs(LHSExprs);
879 Clause->setRHSExprs(RHSExprs);
880 Clause->setReductionOps(ReductionOps);
881 Clause->setPreInitStmt(S: PreInit);
882 Clause->setPostUpdateExpr(PostUpdate);
883 return Clause;
884}
885
886OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
887 unsigned N) {
888 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 5 * N));
889 return new (Mem) OMPTaskReductionClause(N);
890}
891
892void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
893 assert(Privates.size() == varlist_size() &&
894 "Number of private copies is not the same as the preallocated buffer");
895 std::copy(Privates.begin(), Privates.end(), varlist_end());
896}
897
898void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
899 assert(
900 LHSExprs.size() == varlist_size() &&
901 "Number of LHS expressions is not the same as the preallocated buffer");
902 std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
903}
904
905void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
906 assert(
907 RHSExprs.size() == varlist_size() &&
908 "Number of RHS expressions is not the same as the preallocated buffer");
909 std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
910}
911
912void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
913 assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
914 "expressions is not the same "
915 "as the preallocated buffer");
916 std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
917}
918
919void OMPInReductionClause::setTaskgroupDescriptors(
920 ArrayRef<Expr *> TaskgroupDescriptors) {
921 assert(TaskgroupDescriptors.size() == varlist_size() &&
922 "Number of in reduction descriptors is not the same as the "
923 "preallocated buffer");
924 std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(),
925 getReductionOps().end());
926}
927
928OMPInReductionClause *OMPInReductionClause::Create(
929 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
930 SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
931 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
932 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
933 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
934 ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
935 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 6 * VL.size()));
936 OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
937 StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
938 Clause->setVarRefs(VL);
939 Clause->setPrivates(Privates);
940 Clause->setLHSExprs(LHSExprs);
941 Clause->setRHSExprs(RHSExprs);
942 Clause->setReductionOps(ReductionOps);
943 Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
944 Clause->setPreInitStmt(S: PreInit);
945 Clause->setPostUpdateExpr(PostUpdate);
946 return Clause;
947}
948
949OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
950 unsigned N) {
951 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 6 * N));
952 return new (Mem) OMPInReductionClause(N);
953}
954
955OMPSizesClause *OMPSizesClause::Create(const ASTContext &C,
956 SourceLocation StartLoc,
957 SourceLocation LParenLoc,
958 SourceLocation EndLoc,
959 ArrayRef<Expr *> Sizes) {
960 OMPSizesClause *Clause = CreateEmpty(C, NumSizes: Sizes.size());
961 Clause->setLocStart(StartLoc);
962 Clause->setLParenLoc(LParenLoc);
963 Clause->setLocEnd(EndLoc);
964 Clause->setSizesRefs(Sizes);
965 return Clause;
966}
967
968OMPSizesClause *OMPSizesClause::CreateEmpty(const ASTContext &C,
969 unsigned NumSizes) {
970 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: NumSizes));
971 return new (Mem) OMPSizesClause(NumSizes);
972}
973
974OMPFullClause *OMPFullClause::Create(const ASTContext &C,
975 SourceLocation StartLoc,
976 SourceLocation EndLoc) {
977 OMPFullClause *Clause = CreateEmpty(C);
978 Clause->setLocStart(StartLoc);
979 Clause->setLocEnd(EndLoc);
980 return Clause;
981}
982
983OMPFullClause *OMPFullClause::CreateEmpty(const ASTContext &C) {
984 return new (C) OMPFullClause();
985}
986
987OMPPartialClause *OMPPartialClause::Create(const ASTContext &C,
988 SourceLocation StartLoc,
989 SourceLocation LParenLoc,
990 SourceLocation EndLoc,
991 Expr *Factor) {
992 OMPPartialClause *Clause = CreateEmpty(C);
993 Clause->setLocStart(StartLoc);
994 Clause->setLParenLoc(LParenLoc);
995 Clause->setLocEnd(EndLoc);
996 Clause->setFactor(Factor);
997 return Clause;
998}
999
1000OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
1001 return new (C) OMPPartialClause();
1002}
1003
1004OMPAllocateClause *
1005OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
1006 SourceLocation LParenLoc, Expr *Allocator,
1007 SourceLocation ColonLoc, SourceLocation EndLoc,
1008 ArrayRef<Expr *> VL) {
1009 // Allocate space for private variables and initializer expressions.
1010 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
1011 auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
1012 ColonLoc, EndLoc, VL.size());
1013 Clause->setVarRefs(VL);
1014 return Clause;
1015}
1016
1017OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,
1018 unsigned N) {
1019 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1020 return new (Mem) OMPAllocateClause(N);
1021}
1022
1023OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
1024 SourceLocation StartLoc,
1025 SourceLocation LParenLoc,
1026 SourceLocation EndLoc,
1027 ArrayRef<Expr *> VL) {
1028 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + 1));
1029 OMPFlushClause *Clause =
1030 new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
1031 Clause->setVarRefs(VL);
1032 return Clause;
1033}
1034
1035OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
1036 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1037 return new (Mem) OMPFlushClause(N);
1038}
1039
1040OMPDepobjClause *OMPDepobjClause::Create(const ASTContext &C,
1041 SourceLocation StartLoc,
1042 SourceLocation LParenLoc,
1043 SourceLocation RParenLoc,
1044 Expr *Depobj) {
1045 auto *Clause = new (C) OMPDepobjClause(StartLoc, LParenLoc, RParenLoc);
1046 Clause->setDepobj(Depobj);
1047 return Clause;
1048}
1049
1050OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) {
1051 return new (C) OMPDepobjClause();
1052}
1053
1054OMPDependClause *
1055OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
1056 SourceLocation LParenLoc, SourceLocation EndLoc,
1057 DependDataTy Data, Expr *DepModifier,
1058 ArrayRef<Expr *> VL, unsigned NumLoops) {
1059 void *Mem = C.Allocate(
1060 Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + /*depend-modifier*/ 1 + NumLoops),
1061 Align: alignof(OMPDependClause));
1062 OMPDependClause *Clause = new (Mem)
1063 OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
1064 Clause->setDependencyKind(Data.DepKind);
1065 Clause->setDependencyLoc(Data.DepLoc);
1066 Clause->setColonLoc(Data.ColonLoc);
1067 Clause->setOmpAllMemoryLoc(Data.OmpAllMemoryLoc);
1068 Clause->setModifier(DepModifier);
1069 Clause->setVarRefs(VL);
1070 for (unsigned I = 0 ; I < NumLoops; ++I)
1071 Clause->setLoopData(NumLoop: I, Cnt: nullptr);
1072 return Clause;
1073}
1074
1075OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,
1076 unsigned NumLoops) {
1077 void *Mem =
1078 C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N + /*depend-modifier*/ 1 + NumLoops),
1079 Align: alignof(OMPDependClause));
1080 return new (Mem) OMPDependClause(N, NumLoops);
1081}
1082
1083void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
1084 assert((getDependencyKind() == OMPC_DEPEND_sink ||
1085 getDependencyKind() == OMPC_DEPEND_source) &&
1086 NumLoop < NumLoops &&
1087 "Expected sink or source depend + loop index must be less number of "
1088 "loops.");
1089 auto *It = std::next(x: getVarRefs().end(), n: NumLoop + 1);
1090 *It = Cnt;
1091}
1092
1093Expr *OMPDependClause::getLoopData(unsigned NumLoop) {
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(x: getVarRefs().end(), n: NumLoop + 1);
1100 return *It;
1101}
1102
1103const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {
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 const auto *It = std::next(x: getVarRefs().end(), n: NumLoop + 1);
1110 return *It;
1111}
1112
1113void OMPDependClause::setModifier(Expr *DepModifier) {
1114 *getVarRefs().end() = DepModifier;
1115}
1116Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); }
1117
1118unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
1119 MappableExprComponentListsRef ComponentLists) {
1120 unsigned TotalNum = 0u;
1121 for (auto &C : ComponentLists)
1122 TotalNum += C.size();
1123 return TotalNum;
1124}
1125
1126unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
1127 ArrayRef<const ValueDecl *> Declarations) {
1128 unsigned TotalNum = 0u;
1129 llvm::SmallPtrSet<const ValueDecl *, 8> Cache;
1130 for (const ValueDecl *D : Declarations) {
1131 const ValueDecl *VD = D ? cast<ValueDecl>(Val: D->getCanonicalDecl()) : nullptr;
1132 if (Cache.count(Ptr: VD))
1133 continue;
1134 ++TotalNum;
1135 Cache.insert(Ptr: VD);
1136 }
1137 return TotalNum;
1138}
1139
1140OMPMapClause *OMPMapClause::Create(
1141 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1142 ArrayRef<ValueDecl *> Declarations,
1143 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1144 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapModifiers,
1145 ArrayRef<SourceLocation> MapModifiersLoc,
1146 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
1147 OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
1148 OMPMappableExprListSizeTy Sizes;
1149 Sizes.NumVars = Vars.size();
1150 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1151 Sizes.NumComponentLists = ComponentLists.size();
1152 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1153
1154 // We need to allocate:
1155 // 2 x NumVars x Expr* - we have an original list expression and an associated
1156 // user-defined mapper for each clause list entry.
1157 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1158 // with each component list.
1159 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1160 // number of lists for each unique declaration and the size of each component
1161 // list.
1162 // NumComponents x MappableComponent - the total of all the components in all
1163 // the lists.
1164 void *Mem = C.Allocate(
1165 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1166 OMPClauseMappableExprCommon::MappableComponent>(
1167 Counts: 2 * Sizes.NumVars + 1, Counts: Sizes.NumUniqueDeclarations,
1168 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1169 Counts: Sizes.NumComponents));
1170 OMPMapClause *Clause = new (Mem)
1171 OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
1172 Type, TypeIsImplicit, TypeLoc, Locs, Sizes);
1173
1174 Clause->setVarRefs(Vars);
1175 Clause->setUDMapperRefs(UDMapperRefs);
1176 Clause->setIteratorModifier(IteratorModifier);
1177 Clause->setClauseInfo(Declarations, ComponentLists);
1178 Clause->setMapType(Type);
1179 Clause->setMapLoc(TypeLoc);
1180 return Clause;
1181}
1182
1183OMPMapClause *
1184OMPMapClause::CreateEmpty(const ASTContext &C,
1185 const OMPMappableExprListSizeTy &Sizes) {
1186 void *Mem = C.Allocate(
1187 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1188 OMPClauseMappableExprCommon::MappableComponent>(
1189 Counts: 2 * Sizes.NumVars + 1, Counts: Sizes.NumUniqueDeclarations,
1190 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1191 Counts: Sizes.NumComponents));
1192 OMPMapClause *Clause = new (Mem) OMPMapClause(Sizes);
1193 Clause->setIteratorModifier(nullptr);
1194 return Clause;
1195}
1196
1197OMPToClause *OMPToClause::Create(
1198 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1199 ArrayRef<ValueDecl *> Declarations,
1200 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1201 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
1202 ArrayRef<SourceLocation> MotionModifiersLoc,
1203 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1204 OMPMappableExprListSizeTy Sizes;
1205 Sizes.NumVars = Vars.size();
1206 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1207 Sizes.NumComponentLists = ComponentLists.size();
1208 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1209
1210 // We need to allocate:
1211 // 2 x NumVars x Expr* - we have an original list expression and an associated
1212 // user-defined mapper for each clause list entry.
1213 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1214 // with each component list.
1215 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1216 // number of lists for each unique declaration and the size of each component
1217 // list.
1218 // NumComponents x MappableComponent - the total of all the components in all
1219 // the lists.
1220 void *Mem = C.Allocate(
1221 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1222 OMPClauseMappableExprCommon::MappableComponent>(
1223 Counts: 2 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1224 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1225 Counts: Sizes.NumComponents));
1226
1227 auto *Clause = new (Mem) OMPToClause(MotionModifiers, MotionModifiersLoc,
1228 UDMQualifierLoc, MapperId, Locs, Sizes);
1229
1230 Clause->setVarRefs(Vars);
1231 Clause->setUDMapperRefs(UDMapperRefs);
1232 Clause->setClauseInfo(Declarations, ComponentLists);
1233 return Clause;
1234}
1235
1236OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C,
1237 const OMPMappableExprListSizeTy &Sizes) {
1238 void *Mem = C.Allocate(
1239 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1240 OMPClauseMappableExprCommon::MappableComponent>(
1241 Counts: 2 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1242 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1243 Counts: Sizes.NumComponents));
1244 return new (Mem) OMPToClause(Sizes);
1245}
1246
1247OMPFromClause *OMPFromClause::Create(
1248 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1249 ArrayRef<ValueDecl *> Declarations,
1250 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1251 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
1252 ArrayRef<SourceLocation> MotionModifiersLoc,
1253 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1254 OMPMappableExprListSizeTy Sizes;
1255 Sizes.NumVars = Vars.size();
1256 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1257 Sizes.NumComponentLists = ComponentLists.size();
1258 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1259
1260 // We need to allocate:
1261 // 2 x NumVars x Expr* - we have an original list expression and an associated
1262 // user-defined mapper for each clause list entry.
1263 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1264 // with each component list.
1265 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1266 // number of lists for each unique declaration and the size of each component
1267 // list.
1268 // NumComponents x MappableComponent - the total of all the components in all
1269 // the lists.
1270 void *Mem = C.Allocate(
1271 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1272 OMPClauseMappableExprCommon::MappableComponent>(
1273 Counts: 2 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1274 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1275 Counts: Sizes.NumComponents));
1276
1277 auto *Clause =
1278 new (Mem) OMPFromClause(MotionModifiers, MotionModifiersLoc,
1279 UDMQualifierLoc, MapperId, Locs, Sizes);
1280
1281 Clause->setVarRefs(Vars);
1282 Clause->setUDMapperRefs(UDMapperRefs);
1283 Clause->setClauseInfo(Declarations, ComponentLists);
1284 return Clause;
1285}
1286
1287OMPFromClause *
1288OMPFromClause::CreateEmpty(const ASTContext &C,
1289 const OMPMappableExprListSizeTy &Sizes) {
1290 void *Mem = C.Allocate(
1291 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1292 OMPClauseMappableExprCommon::MappableComponent>(
1293 Counts: 2 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1294 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1295 Counts: Sizes.NumComponents));
1296 return new (Mem) OMPFromClause(Sizes);
1297}
1298
1299void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
1300 assert(VL.size() == varlist_size() &&
1301 "Number of private copies is not the same as the preallocated buffer");
1302 std::copy(VL.begin(), VL.end(), varlist_end());
1303}
1304
1305void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
1306 assert(VL.size() == varlist_size() &&
1307 "Number of inits is not the same as the preallocated buffer");
1308 std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
1309}
1310
1311OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
1312 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1313 ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
1314 ArrayRef<ValueDecl *> Declarations,
1315 MappableExprComponentListsRef ComponentLists) {
1316 OMPMappableExprListSizeTy Sizes;
1317 Sizes.NumVars = Vars.size();
1318 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1319 Sizes.NumComponentLists = ComponentLists.size();
1320 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1321
1322 // We need to allocate:
1323 // NumVars x Expr* - we have an original list expression for each clause
1324 // list entry.
1325 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1326 // with each component list.
1327 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1328 // number of lists for each unique declaration and the size of each component
1329 // list.
1330 // NumComponents x MappableComponent - the total of all the components in all
1331 // the lists.
1332 void *Mem = C.Allocate(
1333 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1334 OMPClauseMappableExprCommon::MappableComponent>(
1335 Counts: 3 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1336 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1337 Counts: Sizes.NumComponents));
1338
1339 OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
1340
1341 Clause->setVarRefs(Vars);
1342 Clause->setPrivateCopies(PrivateVars);
1343 Clause->setInits(Inits);
1344 Clause->setClauseInfo(Declarations, ComponentLists);
1345 return Clause;
1346}
1347
1348OMPUseDevicePtrClause *
1349OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C,
1350 const OMPMappableExprListSizeTy &Sizes) {
1351 void *Mem = C.Allocate(
1352 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1353 OMPClauseMappableExprCommon::MappableComponent>(
1354 Counts: 3 * Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1355 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1356 Counts: Sizes.NumComponents));
1357 return new (Mem) OMPUseDevicePtrClause(Sizes);
1358}
1359
1360OMPUseDeviceAddrClause *
1361OMPUseDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1362 ArrayRef<Expr *> Vars,
1363 ArrayRef<ValueDecl *> Declarations,
1364 MappableExprComponentListsRef ComponentLists) {
1365 OMPMappableExprListSizeTy Sizes;
1366 Sizes.NumVars = Vars.size();
1367 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1368 Sizes.NumComponentLists = ComponentLists.size();
1369 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1370
1371 // We need to allocate:
1372 // 3 x NumVars x Expr* - we have an original list expression for each clause
1373 // list entry and an equal number of private copies and inits.
1374 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1375 // with each component list.
1376 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1377 // number of lists for each unique declaration and the size of each component
1378 // list.
1379 // NumComponents x MappableComponent - the total of all the components in all
1380 // the lists.
1381 void *Mem = C.Allocate(
1382 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1383 OMPClauseMappableExprCommon::MappableComponent>(
1384 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1385 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1386 Counts: Sizes.NumComponents));
1387
1388 auto *Clause = new (Mem) OMPUseDeviceAddrClause(Locs, Sizes);
1389
1390 Clause->setVarRefs(Vars);
1391 Clause->setClauseInfo(Declarations, ComponentLists);
1392 return Clause;
1393}
1394
1395OMPUseDeviceAddrClause *
1396OMPUseDeviceAddrClause::CreateEmpty(const ASTContext &C,
1397 const OMPMappableExprListSizeTy &Sizes) {
1398 void *Mem = C.Allocate(
1399 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1400 OMPClauseMappableExprCommon::MappableComponent>(
1401 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1402 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1403 Counts: Sizes.NumComponents));
1404 return new (Mem) OMPUseDeviceAddrClause(Sizes);
1405}
1406
1407OMPIsDevicePtrClause *
1408OMPIsDevicePtrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1409 ArrayRef<Expr *> Vars,
1410 ArrayRef<ValueDecl *> Declarations,
1411 MappableExprComponentListsRef ComponentLists) {
1412 OMPMappableExprListSizeTy Sizes;
1413 Sizes.NumVars = Vars.size();
1414 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1415 Sizes.NumComponentLists = ComponentLists.size();
1416 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1417
1418 // We need to allocate:
1419 // NumVars x Expr* - we have an original list expression for each clause list
1420 // entry.
1421 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1422 // with each component list.
1423 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1424 // number of lists for each unique declaration and the size of each component
1425 // list.
1426 // NumComponents x MappableComponent - the total of all the components in all
1427 // the lists.
1428 void *Mem = C.Allocate(
1429 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1430 OMPClauseMappableExprCommon::MappableComponent>(
1431 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1432 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1433 Counts: Sizes.NumComponents));
1434
1435 OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);
1436
1437 Clause->setVarRefs(Vars);
1438 Clause->setClauseInfo(Declarations, ComponentLists);
1439 return Clause;
1440}
1441
1442OMPIsDevicePtrClause *
1443OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,
1444 const OMPMappableExprListSizeTy &Sizes) {
1445 void *Mem = C.Allocate(
1446 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1447 OMPClauseMappableExprCommon::MappableComponent>(
1448 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1449 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1450 Counts: Sizes.NumComponents));
1451 return new (Mem) OMPIsDevicePtrClause(Sizes);
1452}
1453
1454OMPHasDeviceAddrClause *
1455OMPHasDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1456 ArrayRef<Expr *> Vars,
1457 ArrayRef<ValueDecl *> Declarations,
1458 MappableExprComponentListsRef ComponentLists) {
1459 OMPMappableExprListSizeTy Sizes;
1460 Sizes.NumVars = Vars.size();
1461 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1462 Sizes.NumComponentLists = ComponentLists.size();
1463 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1464
1465 // We need to allocate:
1466 // NumVars x Expr* - we have an original list expression for each clause list
1467 // entry.
1468 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1469 // with each component list.
1470 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1471 // number of lists for each unique declaration and the size of each component
1472 // list.
1473 // NumComponents x MappableComponent - the total of all the components in all
1474 // the lists.
1475 void *Mem = C.Allocate(
1476 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1477 OMPClauseMappableExprCommon::MappableComponent>(
1478 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1479 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1480 Counts: Sizes.NumComponents));
1481
1482 auto *Clause = new (Mem) OMPHasDeviceAddrClause(Locs, Sizes);
1483
1484 Clause->setVarRefs(Vars);
1485 Clause->setClauseInfo(Declarations, ComponentLists);
1486 return Clause;
1487}
1488
1489OMPHasDeviceAddrClause *
1490OMPHasDeviceAddrClause::CreateEmpty(const ASTContext &C,
1491 const OMPMappableExprListSizeTy &Sizes) {
1492 void *Mem = C.Allocate(
1493 Size: totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1494 OMPClauseMappableExprCommon::MappableComponent>(
1495 Counts: Sizes.NumVars, Counts: Sizes.NumUniqueDeclarations,
1496 Counts: Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1497 Counts: Sizes.NumComponents));
1498 return new (Mem) OMPHasDeviceAddrClause(Sizes);
1499}
1500
1501OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
1502 SourceLocation StartLoc,
1503 SourceLocation LParenLoc,
1504 SourceLocation EndLoc,
1505 ArrayRef<Expr *> VL) {
1506 // Allocate space for nontemporal variables + private references.
1507 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * VL.size()));
1508 auto *Clause =
1509 new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
1510 Clause->setVarRefs(VL);
1511 return Clause;
1512}
1513
1514OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,
1515 unsigned N) {
1516 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: 2 * N));
1517 return new (Mem) OMPNontemporalClause(N);
1518}
1519
1520void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {
1521 assert(VL.size() == varlist_size() && "Number of private references is not "
1522 "the same as the preallocated buffer");
1523 std::copy(VL.begin(), VL.end(), varlist_end());
1524}
1525
1526OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C,
1527 SourceLocation StartLoc,
1528 SourceLocation LParenLoc,
1529 SourceLocation EndLoc,
1530 ArrayRef<Expr *> VL) {
1531 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
1532 auto *Clause =
1533 new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1534 Clause->setVarRefs(VL);
1535 return Clause;
1536}
1537
1538OMPInclusiveClause *OMPInclusiveClause::CreateEmpty(const ASTContext &C,
1539 unsigned N) {
1540 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1541 return new (Mem) OMPInclusiveClause(N);
1542}
1543
1544OMPExclusiveClause *OMPExclusiveClause::Create(const ASTContext &C,
1545 SourceLocation StartLoc,
1546 SourceLocation LParenLoc,
1547 SourceLocation EndLoc,
1548 ArrayRef<Expr *> VL) {
1549 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size()));
1550 auto *Clause =
1551 new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1552 Clause->setVarRefs(VL);
1553 return Clause;
1554}
1555
1556OMPExclusiveClause *OMPExclusiveClause::CreateEmpty(const ASTContext &C,
1557 unsigned N) {
1558 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1559 return new (Mem) OMPExclusiveClause(N);
1560}
1561
1562void OMPUsesAllocatorsClause::setAllocatorsData(
1563 ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
1564 assert(Data.size() == NumOfAllocators &&
1565 "Size of allocators data is not the same as the preallocated buffer.");
1566 for (unsigned I = 0, E = Data.size(); I < E; ++I) {
1567 const OMPUsesAllocatorsClause::Data &D = Data[I];
1568 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1569 static_cast<int>(ExprOffsets::Allocator)] =
1570 D.Allocator;
1571 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1572 static_cast<int>(
1573 ExprOffsets::AllocatorTraits)] =
1574 D.AllocatorTraits;
1575 getTrailingObjects<
1576 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1577 static_cast<int>(ParenLocsOffsets::LParen)] =
1578 D.LParenLoc;
1579 getTrailingObjects<
1580 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1581 static_cast<int>(ParenLocsOffsets::RParen)] =
1582 D.RParenLoc;
1583 }
1584}
1585
1586OMPUsesAllocatorsClause::Data
1587OMPUsesAllocatorsClause::getAllocatorData(unsigned I) const {
1588 OMPUsesAllocatorsClause::Data Data;
1589 Data.Allocator =
1590 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1591 static_cast<int>(ExprOffsets::Allocator)];
1592 Data.AllocatorTraits =
1593 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1594 static_cast<int>(
1595 ExprOffsets::AllocatorTraits)];
1596 Data.LParenLoc = getTrailingObjects<
1597 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1598 static_cast<int>(ParenLocsOffsets::LParen)];
1599 Data.RParenLoc = getTrailingObjects<
1600 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1601 static_cast<int>(ParenLocsOffsets::RParen)];
1602 return Data;
1603}
1604
1605OMPUsesAllocatorsClause *
1606OMPUsesAllocatorsClause::Create(const ASTContext &C, SourceLocation StartLoc,
1607 SourceLocation LParenLoc, SourceLocation EndLoc,
1608 ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
1609 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *, SourceLocation>(
1610 Counts: static_cast<int>(ExprOffsets::Total) * Data.size(),
1611 Counts: static_cast<int>(ParenLocsOffsets::Total) * Data.size()));
1612 auto *Clause = new (Mem)
1613 OMPUsesAllocatorsClause(StartLoc, LParenLoc, EndLoc, Data.size());
1614 Clause->setAllocatorsData(Data);
1615 return Clause;
1616}
1617
1618OMPUsesAllocatorsClause *
1619OMPUsesAllocatorsClause::CreateEmpty(const ASTContext &C, unsigned N) {
1620 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *, SourceLocation>(
1621 Counts: static_cast<int>(ExprOffsets::Total) * N,
1622 Counts: static_cast<int>(ParenLocsOffsets::Total) * N));
1623 return new (Mem) OMPUsesAllocatorsClause(N);
1624}
1625
1626OMPAffinityClause *
1627OMPAffinityClause::Create(const ASTContext &C, SourceLocation StartLoc,
1628 SourceLocation LParenLoc, SourceLocation ColonLoc,
1629 SourceLocation EndLoc, Expr *Modifier,
1630 ArrayRef<Expr *> Locators) {
1631 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: Locators.size() + 1));
1632 auto *Clause = new (Mem)
1633 OMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, Locators.size());
1634 Clause->setModifier(Modifier);
1635 Clause->setVarRefs(Locators);
1636 return Clause;
1637}
1638
1639OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C,
1640 unsigned N) {
1641 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N + 1));
1642 return new (Mem) OMPAffinityClause(N);
1643}
1644
1645OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar,
1646 OMPInteropInfo &InteropInfo,
1647 SourceLocation StartLoc,
1648 SourceLocation LParenLoc,
1649 SourceLocation VarLoc,
1650 SourceLocation EndLoc) {
1651
1652 void *Mem =
1653 C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: InteropInfo.PreferTypes.size() + 1));
1654 auto *Clause = new (Mem) OMPInitClause(
1655 InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc, LParenLoc,
1656 VarLoc, EndLoc, InteropInfo.PreferTypes.size() + 1);
1657 Clause->setInteropVar(InteropVar);
1658 llvm::copy(Range&: InteropInfo.PreferTypes, Out: Clause->getTrailingObjects<Expr *>() + 1);
1659 return Clause;
1660}
1661
1662OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {
1663 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N));
1664 return new (Mem) OMPInitClause(N);
1665}
1666
1667OMPBindClause *
1668OMPBindClause::Create(const ASTContext &C, OpenMPBindClauseKind K,
1669 SourceLocation KLoc, SourceLocation StartLoc,
1670 SourceLocation LParenLoc, SourceLocation EndLoc) {
1671 return new (C) OMPBindClause(K, KLoc, StartLoc, LParenLoc, EndLoc);
1672}
1673
1674OMPBindClause *OMPBindClause::CreateEmpty(const ASTContext &C) {
1675 return new (C) OMPBindClause();
1676}
1677
1678OMPDoacrossClause *
1679OMPDoacrossClause::Create(const ASTContext &C, SourceLocation StartLoc,
1680 SourceLocation LParenLoc, SourceLocation EndLoc,
1681 OpenMPDoacrossClauseModifier DepType,
1682 SourceLocation DepLoc, SourceLocation ColonLoc,
1683 ArrayRef<Expr *> VL, unsigned NumLoops) {
1684 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: VL.size() + NumLoops),
1685 Align: alignof(OMPDoacrossClause));
1686 OMPDoacrossClause *Clause = new (Mem)
1687 OMPDoacrossClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
1688 Clause->setDependenceType(DepType);
1689 Clause->setDependenceLoc(DepLoc);
1690 Clause->setColonLoc(ColonLoc);
1691 Clause->setVarRefs(VL);
1692 for (unsigned I = 0; I < NumLoops; ++I)
1693 Clause->setLoopData(NumLoop: I, Cnt: nullptr);
1694 return Clause;
1695}
1696
1697OMPDoacrossClause *OMPDoacrossClause::CreateEmpty(const ASTContext &C,
1698 unsigned N,
1699 unsigned NumLoops) {
1700 void *Mem = C.Allocate(Size: totalSizeToAlloc<Expr *>(Counts: N + NumLoops),
1701 Align: alignof(OMPDoacrossClause));
1702 return new (Mem) OMPDoacrossClause(N, NumLoops);
1703}
1704
1705void OMPDoacrossClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
1706 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1707 auto *It = std::next(x: getVarRefs().end(), n: NumLoop);
1708 *It = Cnt;
1709}
1710
1711Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) {
1712 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1713 auto *It = std::next(x: getVarRefs().end(), n: NumLoop);
1714 return *It;
1715}
1716
1717const Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) const {
1718 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1719 const auto *It = std::next(x: getVarRefs().end(), n: NumLoop);
1720 return *It;
1721}
1722
1723//===----------------------------------------------------------------------===//
1724// OpenMP clauses printing methods
1725//===----------------------------------------------------------------------===//
1726
1727void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
1728 OS << "if(";
1729 if (Node->getNameModifier() != OMPD_unknown)
1730 OS << getOpenMPDirectiveName(D: Node->getNameModifier()) << ": ";
1731 Node->getCondition()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1732 OS << ")";
1733}
1734
1735void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
1736 OS << "final(";
1737 Node->getCondition()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1738 OS << ")";
1739}
1740
1741void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
1742 OS << "num_threads(";
1743 Node->getNumThreads()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1744 OS << ")";
1745}
1746
1747void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
1748 OS << "align(";
1749 Node->getAlignment()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1750 OS << ")";
1751}
1752
1753void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
1754 OS << "safelen(";
1755 Node->getSafelen()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1756 OS << ")";
1757}
1758
1759void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
1760 OS << "simdlen(";
1761 Node->getSimdlen()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1762 OS << ")";
1763}
1764
1765void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {
1766 OS << "sizes(";
1767 bool First = true;
1768 for (auto *Size : Node->getSizesRefs()) {
1769 if (!First)
1770 OS << ", ";
1771 Size->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1772 First = false;
1773 }
1774 OS << ")";
1775}
1776
1777void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }
1778
1779void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
1780 OS << "partial";
1781
1782 if (Expr *Factor = Node->getFactor()) {
1783 OS << '(';
1784 Factor->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1785 OS << ')';
1786 }
1787}
1788
1789void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
1790 OS << "allocator(";
1791 Node->getAllocator()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1792 OS << ")";
1793}
1794
1795void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
1796 OS << "collapse(";
1797 Node->getNumForLoops()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1798 OS << ")";
1799}
1800
1801void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
1802 OS << "detach(";
1803 Node->getEventHandler()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1804 OS << ")";
1805}
1806
1807void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
1808 OS << "default("
1809 << getOpenMPSimpleClauseTypeName(Kind: OMPC_default,
1810 Type: unsigned(Node->getDefaultKind()))
1811 << ")";
1812}
1813
1814void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
1815 OS << "proc_bind("
1816 << getOpenMPSimpleClauseTypeName(Kind: OMPC_proc_bind,
1817 Type: unsigned(Node->getProcBindKind()))
1818 << ")";
1819}
1820
1821void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
1822 OS << "unified_address";
1823}
1824
1825void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
1826 OMPUnifiedSharedMemoryClause *) {
1827 OS << "unified_shared_memory";
1828}
1829
1830void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
1831 OS << "reverse_offload";
1832}
1833
1834void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
1835 OMPDynamicAllocatorsClause *) {
1836 OS << "dynamic_allocators";
1837}
1838
1839void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
1840 OMPAtomicDefaultMemOrderClause *Node) {
1841 OS << "atomic_default_mem_order("
1842 << getOpenMPSimpleClauseTypeName(Kind: OMPC_atomic_default_mem_order,
1843 Type: Node->getAtomicDefaultMemOrderKind())
1844 << ")";
1845}
1846
1847void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
1848 OS << "at(" << getOpenMPSimpleClauseTypeName(Kind: OMPC_at, Type: Node->getAtKind())
1849 << ")";
1850}
1851
1852void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
1853 OS << "severity("
1854 << getOpenMPSimpleClauseTypeName(Kind: OMPC_severity, Type: Node->getSeverityKind())
1855 << ")";
1856}
1857
1858void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
1859 OS << "message(\""
1860 << cast<StringLiteral>(Val: Node->getMessageString())->getString() << "\")";
1861}
1862
1863void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
1864 OS << "schedule(";
1865 if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1866 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule,
1867 Type: Node->getFirstScheduleModifier());
1868 if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1869 OS << ", ";
1870 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule,
1871 Type: Node->getSecondScheduleModifier());
1872 }
1873 OS << ": ";
1874 }
1875 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_schedule, Type: Node->getScheduleKind());
1876 if (auto *E = Node->getChunkSize()) {
1877 OS << ", ";
1878 E->printPretty(OS, Helper: nullptr, Policy);
1879 }
1880 OS << ")";
1881}
1882
1883void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
1884 OS << "ordered";
1885 if (auto *Num = Node->getNumForLoops()) {
1886 OS << "(";
1887 Num->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1888 OS << ")";
1889 }
1890}
1891
1892void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
1893 OS << "nowait";
1894}
1895
1896void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
1897 OS << "untied";
1898}
1899
1900void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
1901 OS << "nogroup";
1902}
1903
1904void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
1905 OS << "mergeable";
1906}
1907
1908void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
1909
1910void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
1911
1912void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
1913 OS << "update";
1914 if (Node->isExtended()) {
1915 OS << "(";
1916 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(),
1917 Type: Node->getDependencyKind());
1918 OS << ")";
1919 }
1920}
1921
1922void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
1923 OS << "capture";
1924}
1925
1926void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
1927 OS << "compare";
1928}
1929
1930void OMPClausePrinter::VisitOMPFailClause(OMPFailClause *Node) {
1931 OS << "fail";
1932 if (Node) {
1933 OS << "(";
1934 OS << getOpenMPSimpleClauseTypeName(
1935 Kind: Node->getClauseKind(), Type: static_cast<int>(Node->getFailParameter()));
1936 OS << ")";
1937 }
1938}
1939
1940void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
1941 OS << "seq_cst";
1942}
1943
1944void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
1945 OS << "acq_rel";
1946}
1947
1948void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
1949 OS << "acquire";
1950}
1951
1952void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
1953 OS << "release";
1954}
1955
1956void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
1957 OS << "relaxed";
1958}
1959
1960void OMPClausePrinter::VisitOMPWeakClause(OMPWeakClause *) { OS << "weak"; }
1961
1962void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
1963 OS << "threads";
1964}
1965
1966void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
1967
1968void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
1969 OS << "device(";
1970 OpenMPDeviceClauseModifier Modifier = Node->getModifier();
1971 if (Modifier != OMPC_DEVICE_unknown) {
1972 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
1973 << ": ";
1974 }
1975 Node->getDevice()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1976 OS << ")";
1977}
1978
1979void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
1980 OS << "num_teams(";
1981 Node->getNumTeams()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1982 OS << ")";
1983}
1984
1985void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
1986 OS << "thread_limit(";
1987 Node->getThreadLimit()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1988 OS << ")";
1989}
1990
1991void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
1992 OS << "priority(";
1993 Node->getPriority()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
1994 OS << ")";
1995}
1996
1997void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
1998 OS << "grainsize(";
1999 OpenMPGrainsizeClauseModifier Modifier = Node->getModifier();
2000 if (Modifier != OMPC_GRAINSIZE_unknown) {
2001 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2002 << ": ";
2003 }
2004 Node->getGrainsize()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2005 OS << ")";
2006}
2007
2008void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
2009 OS << "num_tasks(";
2010 OpenMPNumTasksClauseModifier Modifier = Node->getModifier();
2011 if (Modifier != OMPC_NUMTASKS_unknown) {
2012 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: Modifier)
2013 << ": ";
2014 }
2015 Node->getNumTasks()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2016 OS << ")";
2017}
2018
2019void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
2020 OS << "hint(";
2021 Node->getHint()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2022 OS << ")";
2023}
2024
2025void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
2026 OS << "init(";
2027 bool First = true;
2028 for (const Expr *E : Node->prefs()) {
2029 if (First)
2030 OS << "prefer_type(";
2031 else
2032 OS << ",";
2033 E->printPretty(OS, Helper: nullptr, Policy);
2034 First = false;
2035 }
2036 if (!First)
2037 OS << "), ";
2038 if (Node->getIsTarget())
2039 OS << "target";
2040 if (Node->getIsTargetSync()) {
2041 if (Node->getIsTarget())
2042 OS << ", ";
2043 OS << "targetsync";
2044 }
2045 OS << " : ";
2046 Node->getInteropVar()->printPretty(OS, Helper: nullptr, Policy);
2047 OS << ")";
2048}
2049
2050void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
2051 OS << "use(";
2052 Node->getInteropVar()->printPretty(OS, Helper: nullptr, Policy);
2053 OS << ")";
2054}
2055
2056void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {
2057 OS << "destroy";
2058 if (Expr *E = Node->getInteropVar()) {
2059 OS << "(";
2060 E->printPretty(OS, Helper: nullptr, Policy);
2061 OS << ")";
2062 }
2063}
2064
2065void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {
2066 OS << "novariants";
2067 if (Expr *E = Node->getCondition()) {
2068 OS << "(";
2069 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2070 OS << ")";
2071 }
2072}
2073
2074void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {
2075 OS << "nocontext";
2076 if (Expr *E = Node->getCondition()) {
2077 OS << "(";
2078 E->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2079 OS << ")";
2080 }
2081}
2082
2083template<typename T>
2084void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
2085 for (typename T::varlist_iterator I = Node->varlist_begin(),
2086 E = Node->varlist_end();
2087 I != E; ++I) {
2088 assert(*I && "Expected non-null Stmt");
2089 OS << (I == Node->varlist_begin() ? StartSym : ',');
2090 if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
2091 if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
2092 DRE->printPretty(OS, nullptr, Policy, 0);
2093 else
2094 DRE->getDecl()->printQualifiedName(OS);
2095 } else
2096 (*I)->printPretty(OS, nullptr, Policy, 0);
2097 }
2098}
2099
2100void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
2101 if (Node->varlist_empty())
2102 return;
2103 OS << "allocate";
2104 if (Expr *Allocator = Node->getAllocator()) {
2105 OS << "(";
2106 Allocator->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2107 OS << ":";
2108 VisitOMPClauseList(Node, StartSym: ' ');
2109 } else {
2110 VisitOMPClauseList(Node, StartSym: '(');
2111 }
2112 OS << ")";
2113}
2114
2115void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
2116 if (!Node->varlist_empty()) {
2117 OS << "private";
2118 VisitOMPClauseList(Node, StartSym: '(');
2119 OS << ")";
2120 }
2121}
2122
2123void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
2124 if (!Node->varlist_empty()) {
2125 OS << "firstprivate";
2126 VisitOMPClauseList(Node, StartSym: '(');
2127 OS << ")";
2128 }
2129}
2130
2131void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
2132 if (!Node->varlist_empty()) {
2133 OS << "lastprivate";
2134 OpenMPLastprivateModifier LPKind = Node->getKind();
2135 if (LPKind != OMPC_LASTPRIVATE_unknown) {
2136 OS << "("
2137 << getOpenMPSimpleClauseTypeName(Kind: OMPC_lastprivate, Type: Node->getKind())
2138 << ":";
2139 }
2140 VisitOMPClauseList(Node, StartSym: LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
2141 OS << ")";
2142 }
2143}
2144
2145void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
2146 if (!Node->varlist_empty()) {
2147 OS << "shared";
2148 VisitOMPClauseList(Node, StartSym: '(');
2149 OS << ")";
2150 }
2151}
2152
2153void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
2154 if (!Node->varlist_empty()) {
2155 OS << "reduction(";
2156 if (Node->getModifierLoc().isValid())
2157 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_reduction, Type: Node->getModifier())
2158 << ", ";
2159 NestedNameSpecifier *QualifierLoc =
2160 Node->getQualifierLoc().getNestedNameSpecifier();
2161 OverloadedOperatorKind OOK =
2162 Node->getNameInfo().getName().getCXXOverloadedOperator();
2163 if (QualifierLoc == nullptr && OOK != OO_None) {
2164 // Print reduction identifier in C format
2165 OS << getOperatorSpelling(Operator: OOK);
2166 } else {
2167 // Use C++ format
2168 if (QualifierLoc != nullptr)
2169 QualifierLoc->print(OS, Policy);
2170 OS << Node->getNameInfo();
2171 }
2172 OS << ":";
2173 VisitOMPClauseList(Node, StartSym: ' ');
2174 OS << ")";
2175 }
2176}
2177
2178void OMPClausePrinter::VisitOMPTaskReductionClause(
2179 OMPTaskReductionClause *Node) {
2180 if (!Node->varlist_empty()) {
2181 OS << "task_reduction(";
2182 NestedNameSpecifier *QualifierLoc =
2183 Node->getQualifierLoc().getNestedNameSpecifier();
2184 OverloadedOperatorKind OOK =
2185 Node->getNameInfo().getName().getCXXOverloadedOperator();
2186 if (QualifierLoc == nullptr && OOK != OO_None) {
2187 // Print reduction identifier in C format
2188 OS << getOperatorSpelling(Operator: OOK);
2189 } else {
2190 // Use C++ format
2191 if (QualifierLoc != nullptr)
2192 QualifierLoc->print(OS, Policy);
2193 OS << Node->getNameInfo();
2194 }
2195 OS << ":";
2196 VisitOMPClauseList(Node, StartSym: ' ');
2197 OS << ")";
2198 }
2199}
2200
2201void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
2202 if (!Node->varlist_empty()) {
2203 OS << "in_reduction(";
2204 NestedNameSpecifier *QualifierLoc =
2205 Node->getQualifierLoc().getNestedNameSpecifier();
2206 OverloadedOperatorKind OOK =
2207 Node->getNameInfo().getName().getCXXOverloadedOperator();
2208 if (QualifierLoc == nullptr && OOK != OO_None) {
2209 // Print reduction identifier in C format
2210 OS << getOperatorSpelling(Operator: OOK);
2211 } else {
2212 // Use C++ format
2213 if (QualifierLoc != nullptr)
2214 QualifierLoc->print(OS, Policy);
2215 OS << Node->getNameInfo();
2216 }
2217 OS << ":";
2218 VisitOMPClauseList(Node, StartSym: ' ');
2219 OS << ")";
2220 }
2221}
2222
2223void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
2224 if (!Node->varlist_empty()) {
2225 OS << "linear";
2226 VisitOMPClauseList(Node, StartSym: '(');
2227 if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {
2228 OS << ": ";
2229 }
2230 if (Node->getModifierLoc().isValid()) {
2231 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_linear, Type: Node->getModifier());
2232 }
2233 if (Node->getStep() != nullptr) {
2234 if (Node->getModifierLoc().isValid()) {
2235 OS << ", ";
2236 }
2237 OS << "step(";
2238 Node->getStep()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2239 OS << ")";
2240 }
2241 OS << ")";
2242 }
2243}
2244
2245void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
2246 if (!Node->varlist_empty()) {
2247 OS << "aligned";
2248 VisitOMPClauseList(Node, StartSym: '(');
2249 if (Node->getAlignment() != nullptr) {
2250 OS << ": ";
2251 Node->getAlignment()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2252 }
2253 OS << ")";
2254 }
2255}
2256
2257void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
2258 if (!Node->varlist_empty()) {
2259 OS << "copyin";
2260 VisitOMPClauseList(Node, StartSym: '(');
2261 OS << ")";
2262 }
2263}
2264
2265void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
2266 if (!Node->varlist_empty()) {
2267 OS << "copyprivate";
2268 VisitOMPClauseList(Node, StartSym: '(');
2269 OS << ")";
2270 }
2271}
2272
2273void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
2274 if (!Node->varlist_empty()) {
2275 VisitOMPClauseList(Node, StartSym: '(');
2276 OS << ")";
2277 }
2278}
2279
2280void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
2281 OS << "(";
2282 Node->getDepobj()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2283 OS << ")";
2284}
2285
2286void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
2287 OS << "depend(";
2288 if (Expr *DepModifier = Node->getModifier()) {
2289 DepModifier->printPretty(OS, Helper: nullptr, Policy);
2290 OS << ", ";
2291 }
2292 OpenMPDependClauseKind DepKind = Node->getDependencyKind();
2293 OpenMPDependClauseKind PrintKind = DepKind;
2294 bool IsOmpAllMemory = false;
2295 if (PrintKind == OMPC_DEPEND_outallmemory) {
2296 PrintKind = OMPC_DEPEND_out;
2297 IsOmpAllMemory = true;
2298 } else if (PrintKind == OMPC_DEPEND_inoutallmemory) {
2299 PrintKind = OMPC_DEPEND_inout;
2300 IsOmpAllMemory = true;
2301 }
2302 OS << getOpenMPSimpleClauseTypeName(Kind: Node->getClauseKind(), Type: PrintKind);
2303 if (!Node->varlist_empty() || IsOmpAllMemory)
2304 OS << " :";
2305 VisitOMPClauseList(Node, StartSym: ' ');
2306 if (IsOmpAllMemory) {
2307 OS << (Node->varlist_empty() ? " " : ",");
2308 OS << "omp_all_memory";
2309 }
2310 OS << ")";
2311}
2312
2313template <typename T>
2314static void PrintMapper(raw_ostream &OS, T *Node,
2315 const PrintingPolicy &Policy) {
2316 OS << '(';
2317 NestedNameSpecifier *MapperNNS =
2318 Node->getMapperQualifierLoc().getNestedNameSpecifier();
2319 if (MapperNNS)
2320 MapperNNS->print(OS, Policy);
2321 OS << Node->getMapperIdInfo() << ')';
2322}
2323
2324template <typename T>
2325static void PrintIterator(raw_ostream &OS, T *Node,
2326 const PrintingPolicy &Policy) {
2327 if (Expr *IteratorModifier = Node->getIteratorModifier())
2328 IteratorModifier->printPretty(OS, Helper: nullptr, Policy);
2329}
2330
2331void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
2332 if (!Node->varlist_empty()) {
2333 OS << "map(";
2334 if (Node->getMapType() != OMPC_MAP_unknown) {
2335 for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
2336 if (Node->getMapTypeModifier(Cnt: I) != OMPC_MAP_MODIFIER_unknown) {
2337 if (Node->getMapTypeModifier(Cnt: I) == OMPC_MAP_MODIFIER_iterator) {
2338 PrintIterator(OS, Node, Policy);
2339 } else {
2340 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_map,
2341 Type: Node->getMapTypeModifier(Cnt: I));
2342 if (Node->getMapTypeModifier(Cnt: I) == OMPC_MAP_MODIFIER_mapper)
2343 PrintMapper(OS, Node, Policy);
2344 }
2345 OS << ',';
2346 }
2347 }
2348 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_map, Type: Node->getMapType());
2349 OS << ':';
2350 }
2351 VisitOMPClauseList(Node, StartSym: ' ');
2352 OS << ")";
2353 }
2354}
2355
2356template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {
2357 if (Node->varlist_empty())
2358 return;
2359 OS << getOpenMPClauseName(Node->getClauseKind());
2360 unsigned ModifierCount = 0;
2361 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2362 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)
2363 ++ModifierCount;
2364 }
2365 if (ModifierCount) {
2366 OS << '(';
2367 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2368 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {
2369 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
2370 Node->getMotionModifier(I));
2371 if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)
2372 PrintMapper(OS, Node, Policy);
2373 if (I < ModifierCount - 1)
2374 OS << ", ";
2375 }
2376 }
2377 OS << ':';
2378 VisitOMPClauseList(Node, ' ');
2379 } else {
2380 VisitOMPClauseList(Node, '(');
2381 }
2382 OS << ")";
2383}
2384
2385void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
2386 VisitOMPMotionClause(Node);
2387}
2388
2389void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
2390 VisitOMPMotionClause(Node);
2391}
2392
2393void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
2394 OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
2395 Kind: OMPC_dist_schedule, Type: Node->getDistScheduleKind());
2396 if (auto *E = Node->getChunkSize()) {
2397 OS << ", ";
2398 E->printPretty(OS, Helper: nullptr, Policy);
2399 }
2400 OS << ")";
2401}
2402
2403void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
2404 OS << "defaultmap(";
2405 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_defaultmap,
2406 Type: Node->getDefaultmapModifier());
2407 if (Node->getDefaultmapKind() != OMPC_DEFAULTMAP_unknown) {
2408 OS << ": ";
2409 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_defaultmap,
2410 Type: Node->getDefaultmapKind());
2411 }
2412 OS << ")";
2413}
2414
2415void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
2416 if (!Node->varlist_empty()) {
2417 OS << "use_device_ptr";
2418 VisitOMPClauseList(Node, StartSym: '(');
2419 OS << ")";
2420 }
2421}
2422
2423void OMPClausePrinter::VisitOMPUseDeviceAddrClause(
2424 OMPUseDeviceAddrClause *Node) {
2425 if (!Node->varlist_empty()) {
2426 OS << "use_device_addr";
2427 VisitOMPClauseList(Node, StartSym: '(');
2428 OS << ")";
2429 }
2430}
2431
2432void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
2433 if (!Node->varlist_empty()) {
2434 OS << "is_device_ptr";
2435 VisitOMPClauseList(Node, StartSym: '(');
2436 OS << ")";
2437 }
2438}
2439
2440void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {
2441 if (!Node->varlist_empty()) {
2442 OS << "has_device_addr";
2443 VisitOMPClauseList(Node, StartSym: '(');
2444 OS << ")";
2445 }
2446}
2447
2448void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
2449 if (!Node->varlist_empty()) {
2450 OS << "nontemporal";
2451 VisitOMPClauseList(Node, StartSym: '(');
2452 OS << ")";
2453 }
2454}
2455
2456void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
2457 OS << "order(";
2458 if (Node->getModifier() != OMPC_ORDER_MODIFIER_unknown) {
2459 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_order, Type: Node->getModifier());
2460 OS << ": ";
2461 }
2462 OS << getOpenMPSimpleClauseTypeName(Kind: OMPC_order, Type: Node->getKind()) << ")";
2463}
2464
2465void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
2466 if (!Node->varlist_empty()) {
2467 OS << "inclusive";
2468 VisitOMPClauseList(Node, StartSym: '(');
2469 OS << ")";
2470 }
2471}
2472
2473void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
2474 if (!Node->varlist_empty()) {
2475 OS << "exclusive";
2476 VisitOMPClauseList(Node, StartSym: '(');
2477 OS << ")";
2478 }
2479}
2480
2481void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
2482 OMPUsesAllocatorsClause *Node) {
2483 if (Node->getNumberOfAllocators() == 0)
2484 return;
2485 OS << "uses_allocators(";
2486 for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {
2487 OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);
2488 Data.Allocator->printPretty(OS, Helper: nullptr, Policy);
2489 if (Data.AllocatorTraits) {
2490 OS << "(";
2491 Data.AllocatorTraits->printPretty(OS, Helper: nullptr, Policy);
2492 OS << ")";
2493 }
2494 if (I < E - 1)
2495 OS << ",";
2496 }
2497 OS << ")";
2498}
2499
2500void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
2501 if (Node->varlist_empty())
2502 return;
2503 OS << "affinity";
2504 char StartSym = '(';
2505 if (Expr *Modifier = Node->getModifier()) {
2506 OS << "(";
2507 Modifier->printPretty(OS, Helper: nullptr, Policy);
2508 OS << " :";
2509 StartSym = ' ';
2510 }
2511 VisitOMPClauseList(Node, StartSym);
2512 OS << ")";
2513}
2514
2515void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
2516 OS << "filter(";
2517 Node->getThreadID()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2518 OS << ")";
2519}
2520
2521void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
2522 OS << "bind("
2523 << getOpenMPSimpleClauseTypeName(Kind: OMPC_bind, Type: unsigned(Node->getBindKind()))
2524 << ")";
2525}
2526
2527void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
2528 OMPXDynCGroupMemClause *Node) {
2529 OS << "ompx_dyn_cgroup_mem(";
2530 Node->getSize()->printPretty(OS, Helper: nullptr, Policy, Indentation: 0);
2531 OS << ")";
2532}
2533
2534void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {
2535 OS << "doacross(";
2536 OpenMPDoacrossClauseModifier DepType = Node->getDependenceType();
2537
2538 switch (DepType) {
2539 case OMPC_DOACROSS_source:
2540 OS << "source:";
2541 break;
2542 case OMPC_DOACROSS_sink:
2543 OS << "sink:";
2544 break;
2545 case OMPC_DOACROSS_source_omp_cur_iteration:
2546 OS << "source: omp_cur_iteration";
2547 break;
2548 case OMPC_DOACROSS_sink_omp_cur_iteration:
2549 OS << "sink: omp_cur_iteration - 1";
2550 break;
2551 default:
2552 llvm_unreachable("unknown docaross modifier");
2553 }
2554 VisitOMPClauseList(Node, StartSym: ' ');
2555 OS << ")";
2556}
2557
2558void OMPClausePrinter::VisitOMPXAttributeClause(OMPXAttributeClause *Node) {
2559 OS << "ompx_attribute(";
2560 bool IsFirst = true;
2561 for (auto &Attr : Node->getAttrs()) {
2562 if (!IsFirst)
2563 OS << ", ";
2564 Attr->printPretty(OS, Policy);
2565 IsFirst = false;
2566 }
2567 OS << ")";
2568}
2569
2570void OMPClausePrinter::VisitOMPXBareClause(OMPXBareClause *Node) {
2571 OS << "ompx_bare";
2572}
2573
2574void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
2575 VariantMatchInfo &VMI) const {
2576 for (const OMPTraitSet &Set : Sets) {
2577 for (const OMPTraitSelector &Selector : Set.Selectors) {
2578
2579 // User conditions are special as we evaluate the condition here.
2580 if (Selector.Kind == TraitSelector::user_condition) {
2581 assert(Selector.ScoreOrCondition &&
2582 "Ill-formed user condition, expected condition expression!");
2583 assert(Selector.Properties.size() == 1 &&
2584 Selector.Properties.front().Kind ==
2585 TraitProperty::user_condition_unknown &&
2586 "Ill-formed user condition, expected unknown trait property!");
2587
2588 if (std::optional<APSInt> CondVal =
2589 Selector.ScoreOrCondition->getIntegerConstantExpr(Ctx: ASTCtx))
2590 VMI.addTrait(Property: CondVal->isZero() ? TraitProperty::user_condition_false
2591 : TraitProperty::user_condition_true,
2592 RawString: "<condition>");
2593 else
2594 VMI.addTrait(Property: TraitProperty::user_condition_false, RawString: "<condition>");
2595 continue;
2596 }
2597
2598 std::optional<llvm::APSInt> Score;
2599 llvm::APInt *ScorePtr = nullptr;
2600 if (Selector.ScoreOrCondition) {
2601 if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(Ctx: ASTCtx)))
2602 ScorePtr = &*Score;
2603 else
2604 VMI.addTrait(Property: TraitProperty::user_condition_false,
2605 RawString: "<non-constant-score>");
2606 }
2607
2608 for (const OMPTraitProperty &Property : Selector.Properties)
2609 VMI.addTrait(Set: Set.Kind, Property: Property.Kind, RawString: Property.RawString, Score: ScorePtr);
2610
2611 if (Set.Kind != TraitSet::construct)
2612 continue;
2613
2614 // TODO: This might not hold once we implement SIMD properly.
2615 assert(Selector.Properties.size() == 1 &&
2616 Selector.Properties.front().Kind ==
2617 getOpenMPContextTraitPropertyForSelector(
2618 Selector.Kind) &&
2619 "Ill-formed construct selector!");
2620 }
2621 }
2622}
2623
2624void OMPTraitInfo::print(llvm::raw_ostream &OS,
2625 const PrintingPolicy &Policy) const {
2626 bool FirstSet = true;
2627 for (const OMPTraitSet &Set : Sets) {
2628 if (!FirstSet)
2629 OS << ", ";
2630 FirstSet = false;
2631 OS << getOpenMPContextTraitSetName(Kind: Set.Kind) << "={";
2632
2633 bool FirstSelector = true;
2634 for (const OMPTraitSelector &Selector : Set.Selectors) {
2635 if (!FirstSelector)
2636 OS << ", ";
2637 FirstSelector = false;
2638 OS << getOpenMPContextTraitSelectorName(Kind: Selector.Kind);
2639
2640 bool AllowsTraitScore = false;
2641 bool RequiresProperty = false;
2642 isValidTraitSelectorForTraitSet(
2643 Selector: Selector.Kind, Set: Set.Kind, AllowsTraitScore, RequiresProperty);
2644
2645 if (!RequiresProperty)
2646 continue;
2647
2648 OS << "(";
2649 if (Selector.Kind == TraitSelector::user_condition) {
2650 if (Selector.ScoreOrCondition)
2651 Selector.ScoreOrCondition->printPretty(OS, Helper: nullptr, Policy);
2652 else
2653 OS << "...";
2654 } else {
2655
2656 if (Selector.ScoreOrCondition) {
2657 OS << "score(";
2658 Selector.ScoreOrCondition->printPretty(OS, Helper: nullptr, Policy);
2659 OS << "): ";
2660 }
2661
2662 bool FirstProperty = true;
2663 for (const OMPTraitProperty &Property : Selector.Properties) {
2664 if (!FirstProperty)
2665 OS << ", ";
2666 FirstProperty = false;
2667 OS << getOpenMPContextTraitPropertyName(Kind: Property.Kind,
2668 RawString: Property.RawString);
2669 }
2670 }
2671 OS << ")";
2672 }
2673 OS << "}";
2674 }
2675}
2676
2677std::string OMPTraitInfo::getMangledName() const {
2678 std::string MangledName;
2679 llvm::raw_string_ostream OS(MangledName);
2680 for (const OMPTraitSet &Set : Sets) {
2681 OS << '$' << 'S' << unsigned(Set.Kind);
2682 for (const OMPTraitSelector &Selector : Set.Selectors) {
2683
2684 bool AllowsTraitScore = false;
2685 bool RequiresProperty = false;
2686 isValidTraitSelectorForTraitSet(
2687 Selector: Selector.Kind, Set: Set.Kind, AllowsTraitScore, RequiresProperty);
2688 OS << '$' << 's' << unsigned(Selector.Kind);
2689
2690 if (!RequiresProperty ||
2691 Selector.Kind == TraitSelector::user_condition)
2692 continue;
2693
2694 for (const OMPTraitProperty &Property : Selector.Properties)
2695 OS << '$' << 'P'
2696 << getOpenMPContextTraitPropertyName(Kind: Property.Kind,
2697 RawString: Property.RawString);
2698 }
2699 }
2700 return MangledName;
2701}
2702
2703OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
2704 unsigned long U;
2705 do {
2706 if (!MangledName.consume_front(Prefix: "$S"))
2707 break;
2708 if (MangledName.consumeInteger(Radix: 10, Result&: U))
2709 break;
2710 Sets.push_back(Elt: OMPTraitSet());
2711 OMPTraitSet &Set = Sets.back();
2712 Set.Kind = TraitSet(U);
2713 do {
2714 if (!MangledName.consume_front(Prefix: "$s"))
2715 break;
2716 if (MangledName.consumeInteger(Radix: 10, Result&: U))
2717 break;
2718 Set.Selectors.push_back(Elt: OMPTraitSelector());
2719 OMPTraitSelector &Selector = Set.Selectors.back();
2720 Selector.Kind = TraitSelector(U);
2721 do {
2722 if (!MangledName.consume_front(Prefix: "$P"))
2723 break;
2724 Selector.Properties.push_back(Elt: OMPTraitProperty());
2725 OMPTraitProperty &Property = Selector.Properties.back();
2726 std::pair<StringRef, StringRef> PropRestPair = MangledName.split(Separator: '$');
2727 Property.RawString = PropRestPair.first;
2728 Property.Kind = getOpenMPContextTraitPropertyKind(
2729 Set: Set.Kind, Selector: Selector.Kind, Str: PropRestPair.first);
2730 MangledName = MangledName.drop_front(N: PropRestPair.first.size());
2731 } while (true);
2732 } while (true);
2733 } while (true);
2734}
2735
2736llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
2737 const OMPTraitInfo &TI) {
2738 LangOptions LO;
2739 PrintingPolicy Policy(LO);
2740 TI.print(OS, Policy);
2741 return OS;
2742}
2743llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
2744 const OMPTraitInfo *TI) {
2745 return TI ? OS << *TI : OS;
2746}
2747
2748TargetOMPContext::TargetOMPContext(
2749 ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
2750 const FunctionDecl *CurrentFunctionDecl,
2751 ArrayRef<llvm::omp::TraitProperty> ConstructTraits)
2752 : OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
2753 ASTCtx.getTargetInfo().getTriple()),
2754 FeatureValidityCheck([&](StringRef FeatureName) {
2755 return ASTCtx.getTargetInfo().isValidFeatureName(Feature: FeatureName);
2756 }),
2757 DiagUnknownTrait(std::move(DiagUnknownTrait)) {
2758 ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);
2759
2760 for (llvm::omp::TraitProperty Property : ConstructTraits)
2761 addTrait(Property);
2762}
2763
2764bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
2765 auto It = FeatureMap.find(Key: RawString);
2766 if (It != FeatureMap.end())
2767 return It->second;
2768 if (!FeatureValidityCheck(RawString))
2769 DiagUnknownTrait(RawString);
2770 return false;
2771}
2772