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