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