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