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/Decl.h"
16 #include "clang/AST/DeclOpenMP.h"
17 #include "clang/Basic/LLVM.h"
18 #include "clang/Basic/OpenMPKinds.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include <algorithm>
23 #include <cassert>
24 
25 using namespace clang;
26 
27 OMPClause::child_range OMPClause::children() {
28   switch (getClauseKind()) {
29   default:
30     break;
31 #define OPENMP_CLAUSE(Name, Class)                                             \
32   case OMPC_##Name:                                                            \
33     return static_cast<Class *>(this)->children();
34 #include "clang/Basic/OpenMPKinds.def"
35   }
36   llvm_unreachable("unknown OMPClause");
37 }
38 
39 OMPClause::child_range OMPClause::used_children() {
40   switch (getClauseKind()) {
41 #define OPENMP_CLAUSE(Name, Class)                                             \
42   case OMPC_##Name:                                                            \
43     return static_cast<Class *>(this)->used_children();
44 #include "clang/Basic/OpenMPKinds.def"
45   case OMPC_threadprivate:
46   case OMPC_uniform:
47   case OMPC_device_type:
48   case OMPC_match:
49   case OMPC_unknown:
50     break;
51   }
52   llvm_unreachable("unknown OMPClause");
53 }
54 
55 OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {
56   auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
57   return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
58 }
59 
60 const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
61   switch (C->getClauseKind()) {
62   case OMPC_schedule:
63     return static_cast<const OMPScheduleClause *>(C);
64   case OMPC_dist_schedule:
65     return static_cast<const OMPDistScheduleClause *>(C);
66   case OMPC_firstprivate:
67     return static_cast<const OMPFirstprivateClause *>(C);
68   case OMPC_lastprivate:
69     return static_cast<const OMPLastprivateClause *>(C);
70   case OMPC_reduction:
71     return static_cast<const OMPReductionClause *>(C);
72   case OMPC_task_reduction:
73     return static_cast<const OMPTaskReductionClause *>(C);
74   case OMPC_in_reduction:
75     return static_cast<const OMPInReductionClause *>(C);
76   case OMPC_linear:
77     return static_cast<const OMPLinearClause *>(C);
78   case OMPC_if:
79     return static_cast<const OMPIfClause *>(C);
80   case OMPC_num_threads:
81     return static_cast<const OMPNumThreadsClause *>(C);
82   case OMPC_num_teams:
83     return static_cast<const OMPNumTeamsClause *>(C);
84   case OMPC_thread_limit:
85     return static_cast<const OMPThreadLimitClause *>(C);
86   case OMPC_device:
87     return static_cast<const OMPDeviceClause *>(C);
88   case OMPC_grainsize:
89     return static_cast<const OMPGrainsizeClause *>(C);
90   case OMPC_num_tasks:
91     return static_cast<const OMPNumTasksClause *>(C);
92   case OMPC_final:
93     return static_cast<const OMPFinalClause *>(C);
94   case OMPC_priority:
95     return static_cast<const OMPPriorityClause *>(C);
96   case OMPC_default:
97   case OMPC_proc_bind:
98   case OMPC_safelen:
99   case OMPC_simdlen:
100   case OMPC_allocator:
101   case OMPC_allocate:
102   case OMPC_collapse:
103   case OMPC_private:
104   case OMPC_shared:
105   case OMPC_aligned:
106   case OMPC_copyin:
107   case OMPC_copyprivate:
108   case OMPC_ordered:
109   case OMPC_nowait:
110   case OMPC_untied:
111   case OMPC_mergeable:
112   case OMPC_threadprivate:
113   case OMPC_flush:
114   case OMPC_read:
115   case OMPC_write:
116   case OMPC_update:
117   case OMPC_capture:
118   case OMPC_seq_cst:
119   case OMPC_acq_rel:
120   case OMPC_acquire:
121   case OMPC_release:
122   case OMPC_relaxed:
123   case OMPC_depend:
124   case OMPC_threads:
125   case OMPC_simd:
126   case OMPC_map:
127   case OMPC_nogroup:
128   case OMPC_hint:
129   case OMPC_defaultmap:
130   case OMPC_unknown:
131   case OMPC_uniform:
132   case OMPC_to:
133   case OMPC_from:
134   case OMPC_use_device_ptr:
135   case OMPC_is_device_ptr:
136   case OMPC_unified_address:
137   case OMPC_unified_shared_memory:
138   case OMPC_reverse_offload:
139   case OMPC_dynamic_allocators:
140   case OMPC_atomic_default_mem_order:
141   case OMPC_device_type:
142   case OMPC_match:
143   case OMPC_nontemporal:
144   case OMPC_order:
145     break;
146   }
147 
148   return nullptr;
149 }
150 
151 OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) {
152   auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));
153   return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
154 }
155 
156 const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) {
157   switch (C->getClauseKind()) {
158   case OMPC_lastprivate:
159     return static_cast<const OMPLastprivateClause *>(C);
160   case OMPC_reduction:
161     return static_cast<const OMPReductionClause *>(C);
162   case OMPC_task_reduction:
163     return static_cast<const OMPTaskReductionClause *>(C);
164   case OMPC_in_reduction:
165     return static_cast<const OMPInReductionClause *>(C);
166   case OMPC_linear:
167     return static_cast<const OMPLinearClause *>(C);
168   case OMPC_schedule:
169   case OMPC_dist_schedule:
170   case OMPC_firstprivate:
171   case OMPC_default:
172   case OMPC_proc_bind:
173   case OMPC_if:
174   case OMPC_final:
175   case OMPC_num_threads:
176   case OMPC_safelen:
177   case OMPC_simdlen:
178   case OMPC_allocator:
179   case OMPC_allocate:
180   case OMPC_collapse:
181   case OMPC_private:
182   case OMPC_shared:
183   case OMPC_aligned:
184   case OMPC_copyin:
185   case OMPC_copyprivate:
186   case OMPC_ordered:
187   case OMPC_nowait:
188   case OMPC_untied:
189   case OMPC_mergeable:
190   case OMPC_threadprivate:
191   case OMPC_flush:
192   case OMPC_read:
193   case OMPC_write:
194   case OMPC_update:
195   case OMPC_capture:
196   case OMPC_seq_cst:
197   case OMPC_acq_rel:
198   case OMPC_acquire:
199   case OMPC_release:
200   case OMPC_relaxed:
201   case OMPC_depend:
202   case OMPC_device:
203   case OMPC_threads:
204   case OMPC_simd:
205   case OMPC_map:
206   case OMPC_num_teams:
207   case OMPC_thread_limit:
208   case OMPC_priority:
209   case OMPC_grainsize:
210   case OMPC_nogroup:
211   case OMPC_num_tasks:
212   case OMPC_hint:
213   case OMPC_defaultmap:
214   case OMPC_unknown:
215   case OMPC_uniform:
216   case OMPC_to:
217   case OMPC_from:
218   case OMPC_use_device_ptr:
219   case OMPC_is_device_ptr:
220   case OMPC_unified_address:
221   case OMPC_unified_shared_memory:
222   case OMPC_reverse_offload:
223   case OMPC_dynamic_allocators:
224   case OMPC_atomic_default_mem_order:
225   case OMPC_device_type:
226   case OMPC_match:
227   case OMPC_nontemporal:
228   case OMPC_order:
229     break;
230   }
231 
232   return nullptr;
233 }
234 
235 /// Gets the address of the original, non-captured, expression used in the
236 /// clause as the preinitializer.
237 static Stmt **getAddrOfExprAsWritten(Stmt *S) {
238   if (!S)
239     return nullptr;
240   if (auto *DS = dyn_cast<DeclStmt>(S)) {
241     assert(DS->isSingleDecl() && "Only single expression must be captured.");
242     if (auto *OED = dyn_cast<OMPCapturedExprDecl>(DS->getSingleDecl()))
243       return OED->getInitAddress();
244   }
245   return nullptr;
246 }
247 
248 OMPClause::child_range OMPIfClause::used_children() {
249   if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
250     return child_range(C, C + 1);
251   return child_range(&Condition, &Condition + 1);
252 }
253 
254 OMPClause::child_range OMPGrainsizeClause::used_children() {
255   if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
256     return child_range(C, C + 1);
257   return child_range(&Grainsize, &Grainsize + 1);
258 }
259 
260 OMPClause::child_range OMPNumTasksClause::used_children() {
261   if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
262     return child_range(C, C + 1);
263   return child_range(&NumTasks, &NumTasks + 1);
264 }
265 
266 OMPClause::child_range OMPFinalClause::used_children() {
267   if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
268     return child_range(C, C + 1);
269   return child_range(&Condition, &Condition + 1);
270 }
271 
272 OMPClause::child_range OMPPriorityClause::used_children() {
273   if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
274     return child_range(C, C + 1);
275   return child_range(&Priority, &Priority + 1);
276 }
277 
278 OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,
279                                            unsigned NumLoops,
280                                            SourceLocation StartLoc,
281                                            SourceLocation LParenLoc,
282                                            SourceLocation EndLoc) {
283   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
284   auto *Clause =
285       new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);
286   for (unsigned I = 0; I < NumLoops; ++I) {
287     Clause->setLoopNumIterations(I, nullptr);
288     Clause->setLoopCounter(I, nullptr);
289   }
290   return Clause;
291 }
292 
293 OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C,
294                                                 unsigned NumLoops) {
295   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
296   auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
297   for (unsigned I = 0; I < NumLoops; ++I) {
298     Clause->setLoopNumIterations(I, nullptr);
299     Clause->setLoopCounter(I, nullptr);
300   }
301   return Clause;
302 }
303 
304 void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop,
305                                             Expr *NumIterations) {
306   assert(NumLoop < NumberOfLoops && "out of loops number.");
307   getTrailingObjects<Expr *>()[NumLoop] = NumIterations;
308 }
309 
310 ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations() const {
311   return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumberOfLoops);
312 }
313 
314 void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {
315   assert(NumLoop < NumberOfLoops && "out of loops number.");
316   getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop] = Counter;
317 }
318 
319 Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) {
320   assert(NumLoop < NumberOfLoops && "out of loops number.");
321   return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
322 }
323 
324 const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
325   assert(NumLoop < NumberOfLoops && "out of loops number.");
326   return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
327 }
328 
329 void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
330   assert(VL.size() == varlist_size() &&
331          "Number of private copies is not the same as the preallocated buffer");
332   std::copy(VL.begin(), VL.end(), varlist_end());
333 }
334 
335 OMPPrivateClause *
336 OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
337                          SourceLocation LParenLoc, SourceLocation EndLoc,
338                          ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
339   // Allocate space for private variables and initializer expressions.
340   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
341   OMPPrivateClause *Clause =
342       new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
343   Clause->setVarRefs(VL);
344   Clause->setPrivateCopies(PrivateVL);
345   return Clause;
346 }
347 
348 OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
349                                                 unsigned N) {
350   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
351   return new (Mem) OMPPrivateClause(N);
352 }
353 
354 void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
355   assert(VL.size() == varlist_size() &&
356          "Number of private copies is not the same as the preallocated buffer");
357   std::copy(VL.begin(), VL.end(), varlist_end());
358 }
359 
360 void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
361   assert(VL.size() == varlist_size() &&
362          "Number of inits is not the same as the preallocated buffer");
363   std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
364 }
365 
366 OMPFirstprivateClause *
367 OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
368                               SourceLocation LParenLoc, SourceLocation EndLoc,
369                               ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
370                               ArrayRef<Expr *> InitVL, Stmt *PreInit) {
371   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));
372   OMPFirstprivateClause *Clause =
373       new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
374   Clause->setVarRefs(VL);
375   Clause->setPrivateCopies(PrivateVL);
376   Clause->setInits(InitVL);
377   Clause->setPreInitStmt(PreInit);
378   return Clause;
379 }
380 
381 OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
382                                                           unsigned N) {
383   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));
384   return new (Mem) OMPFirstprivateClause(N);
385 }
386 
387 void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
388   assert(PrivateCopies.size() == varlist_size() &&
389          "Number of private copies is not the same as the preallocated buffer");
390   std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
391 }
392 
393 void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
394   assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
395                                               "not the same as the "
396                                               "preallocated buffer");
397   std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
398 }
399 
400 void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
401   assert(DstExprs.size() == varlist_size() && "Number of destination "
402                                               "expressions is not the same as "
403                                               "the preallocated buffer");
404   std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
405 }
406 
407 void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
408   assert(AssignmentOps.size() == varlist_size() &&
409          "Number of assignment expressions is not the same as the preallocated "
410          "buffer");
411   std::copy(AssignmentOps.begin(), AssignmentOps.end(),
412             getDestinationExprs().end());
413 }
414 
415 OMPLastprivateClause *OMPLastprivateClause::Create(
416     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
417     SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
418     ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
419     OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,
420     SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {
421   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
422   OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(
423       StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());
424   Clause->setVarRefs(VL);
425   Clause->setSourceExprs(SrcExprs);
426   Clause->setDestinationExprs(DstExprs);
427   Clause->setAssignmentOps(AssignmentOps);
428   Clause->setPreInitStmt(PreInit);
429   Clause->setPostUpdateExpr(PostUpdate);
430   return Clause;
431 }
432 
433 OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
434                                                         unsigned N) {
435   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
436   return new (Mem) OMPLastprivateClause(N);
437 }
438 
439 OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
440                                          SourceLocation StartLoc,
441                                          SourceLocation LParenLoc,
442                                          SourceLocation EndLoc,
443                                          ArrayRef<Expr *> VL) {
444   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
445   OMPSharedClause *Clause =
446       new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
447   Clause->setVarRefs(VL);
448   return Clause;
449 }
450 
451 OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
452   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
453   return new (Mem) OMPSharedClause(N);
454 }
455 
456 void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
457   assert(PL.size() == varlist_size() &&
458          "Number of privates is not the same as the preallocated buffer");
459   std::copy(PL.begin(), PL.end(), varlist_end());
460 }
461 
462 void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
463   assert(IL.size() == varlist_size() &&
464          "Number of inits is not the same as the preallocated buffer");
465   std::copy(IL.begin(), IL.end(), getPrivates().end());
466 }
467 
468 void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
469   assert(UL.size() == varlist_size() &&
470          "Number of updates is not the same as the preallocated buffer");
471   std::copy(UL.begin(), UL.end(), getInits().end());
472 }
473 
474 void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
475   assert(FL.size() == varlist_size() &&
476          "Number of final updates is not the same as the preallocated buffer");
477   std::copy(FL.begin(), FL.end(), getUpdates().end());
478 }
479 
480 void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {
481   assert(
482       UE.size() == varlist_size() + 1 &&
483       "Number of used expressions is not the same as the preallocated buffer");
484   std::copy(UE.begin(), UE.end(), getFinals().end() + 2);
485 }
486 
487 OMPLinearClause *OMPLinearClause::Create(
488     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
489     OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
490     SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
491     ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
492     Stmt *PreInit, Expr *PostUpdate) {
493   // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
494   // (Step and CalcStep), list of used expression + step.
495   void *Mem =
496       C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));
497   OMPLinearClause *Clause = new (Mem) OMPLinearClause(
498       StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
499   Clause->setVarRefs(VL);
500   Clause->setPrivates(PL);
501   Clause->setInits(IL);
502   // Fill update and final expressions with zeroes, they are provided later,
503   // after the directive construction.
504   std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
505             nullptr);
506   std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
507             nullptr);
508   std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),
509             nullptr);
510   Clause->setStep(Step);
511   Clause->setCalcStep(CalcStep);
512   Clause->setPreInitStmt(PreInit);
513   Clause->setPostUpdateExpr(PostUpdate);
514   return Clause;
515 }
516 
517 OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
518                                               unsigned NumVars) {
519   // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
520   // (Step and CalcStep), list of used expression + step.
521   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2 + NumVars  +1));
522   return new (Mem) OMPLinearClause(NumVars);
523 }
524 
525 OMPClause::child_range OMPLinearClause::used_children() {
526   // Range includes only non-nullptr elements.
527   return child_range(
528       reinterpret_cast<Stmt **>(getUsedExprs().begin()),
529       reinterpret_cast<Stmt **>(llvm::find(getUsedExprs(), nullptr)));
530 }
531 
532 OMPAlignedClause *
533 OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
534                          SourceLocation LParenLoc, SourceLocation ColonLoc,
535                          SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
536   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
537   OMPAlignedClause *Clause = new (Mem)
538       OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
539   Clause->setVarRefs(VL);
540   Clause->setAlignment(A);
541   return Clause;
542 }
543 
544 OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
545                                                 unsigned NumVars) {
546   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));
547   return new (Mem) OMPAlignedClause(NumVars);
548 }
549 
550 void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
551   assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
552                                               "not the same as the "
553                                               "preallocated buffer");
554   std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
555 }
556 
557 void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
558   assert(DstExprs.size() == varlist_size() && "Number of destination "
559                                               "expressions is not the same as "
560                                               "the preallocated buffer");
561   std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
562 }
563 
564 void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
565   assert(AssignmentOps.size() == varlist_size() &&
566          "Number of assignment expressions is not the same as the preallocated "
567          "buffer");
568   std::copy(AssignmentOps.begin(), AssignmentOps.end(),
569             getDestinationExprs().end());
570 }
571 
572 OMPCopyinClause *OMPCopyinClause::Create(
573     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
574     SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
575     ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
576   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
577   OMPCopyinClause *Clause =
578       new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
579   Clause->setVarRefs(VL);
580   Clause->setSourceExprs(SrcExprs);
581   Clause->setDestinationExprs(DstExprs);
582   Clause->setAssignmentOps(AssignmentOps);
583   return Clause;
584 }
585 
586 OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
587   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
588   return new (Mem) OMPCopyinClause(N);
589 }
590 
591 void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
592   assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
593                                               "not the same as the "
594                                               "preallocated buffer");
595   std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
596 }
597 
598 void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
599   assert(DstExprs.size() == varlist_size() && "Number of destination "
600                                               "expressions is not the same as "
601                                               "the preallocated buffer");
602   std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
603 }
604 
605 void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
606   assert(AssignmentOps.size() == varlist_size() &&
607          "Number of assignment expressions is not the same as the preallocated "
608          "buffer");
609   std::copy(AssignmentOps.begin(), AssignmentOps.end(),
610             getDestinationExprs().end());
611 }
612 
613 OMPCopyprivateClause *OMPCopyprivateClause::Create(
614     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
615     SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
616     ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
617   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
618   OMPCopyprivateClause *Clause =
619       new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
620   Clause->setVarRefs(VL);
621   Clause->setSourceExprs(SrcExprs);
622   Clause->setDestinationExprs(DstExprs);
623   Clause->setAssignmentOps(AssignmentOps);
624   return Clause;
625 }
626 
627 OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
628                                                         unsigned N) {
629   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
630   return new (Mem) OMPCopyprivateClause(N);
631 }
632 
633 void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
634   assert(Privates.size() == varlist_size() &&
635          "Number of private copies is not the same as the preallocated buffer");
636   std::copy(Privates.begin(), Privates.end(), varlist_end());
637 }
638 
639 void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
640   assert(
641       LHSExprs.size() == varlist_size() &&
642       "Number of LHS expressions is not the same as the preallocated buffer");
643   std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
644 }
645 
646 void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
647   assert(
648       RHSExprs.size() == varlist_size() &&
649       "Number of RHS expressions is not the same as the preallocated buffer");
650   std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
651 }
652 
653 void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
654   assert(ReductionOps.size() == varlist_size() && "Number of reduction "
655                                                   "expressions is not the same "
656                                                   "as the preallocated buffer");
657   std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
658 }
659 
660 OMPReductionClause *OMPReductionClause::Create(
661     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
662     SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
663     NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
664     ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
665     ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
666     Expr *PostUpdate) {
667   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
668   OMPReductionClause *Clause = new (Mem) OMPReductionClause(
669       StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
670   Clause->setVarRefs(VL);
671   Clause->setPrivates(Privates);
672   Clause->setLHSExprs(LHSExprs);
673   Clause->setRHSExprs(RHSExprs);
674   Clause->setReductionOps(ReductionOps);
675   Clause->setPreInitStmt(PreInit);
676   Clause->setPostUpdateExpr(PostUpdate);
677   return Clause;
678 }
679 
680 OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
681                                                     unsigned N) {
682   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
683   return new (Mem) OMPReductionClause(N);
684 }
685 
686 void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
687   assert(Privates.size() == varlist_size() &&
688          "Number of private copies is not the same as the preallocated buffer");
689   std::copy(Privates.begin(), Privates.end(), varlist_end());
690 }
691 
692 void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
693   assert(
694       LHSExprs.size() == varlist_size() &&
695       "Number of LHS expressions is not the same as the preallocated buffer");
696   std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
697 }
698 
699 void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
700   assert(
701       RHSExprs.size() == varlist_size() &&
702       "Number of RHS expressions is not the same as the preallocated buffer");
703   std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
704 }
705 
706 void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
707   assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
708                                                   "expressions is not the same "
709                                                   "as the preallocated buffer");
710   std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
711 }
712 
713 OMPTaskReductionClause *OMPTaskReductionClause::Create(
714     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
715     SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
716     NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
717     ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
718     ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
719     Expr *PostUpdate) {
720   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
721   OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
722       StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
723   Clause->setVarRefs(VL);
724   Clause->setPrivates(Privates);
725   Clause->setLHSExprs(LHSExprs);
726   Clause->setRHSExprs(RHSExprs);
727   Clause->setReductionOps(ReductionOps);
728   Clause->setPreInitStmt(PreInit);
729   Clause->setPostUpdateExpr(PostUpdate);
730   return Clause;
731 }
732 
733 OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
734                                                             unsigned N) {
735   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
736   return new (Mem) OMPTaskReductionClause(N);
737 }
738 
739 void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
740   assert(Privates.size() == varlist_size() &&
741          "Number of private copies is not the same as the preallocated buffer");
742   std::copy(Privates.begin(), Privates.end(), varlist_end());
743 }
744 
745 void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
746   assert(
747       LHSExprs.size() == varlist_size() &&
748       "Number of LHS expressions is not the same as the preallocated buffer");
749   std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
750 }
751 
752 void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
753   assert(
754       RHSExprs.size() == varlist_size() &&
755       "Number of RHS expressions is not the same as the preallocated buffer");
756   std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
757 }
758 
759 void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
760   assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
761                                                   "expressions is not the same "
762                                                   "as the preallocated buffer");
763   std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
764 }
765 
766 void OMPInReductionClause::setTaskgroupDescriptors(
767     ArrayRef<Expr *> TaskgroupDescriptors) {
768   assert(TaskgroupDescriptors.size() == varlist_size() &&
769          "Number of in reduction descriptors is not the same as the "
770          "preallocated buffer");
771   std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(),
772             getReductionOps().end());
773 }
774 
775 OMPInReductionClause *OMPInReductionClause::Create(
776     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
777     SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
778     NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
779     ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
780     ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
781     ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
782   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));
783   OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
784       StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
785   Clause->setVarRefs(VL);
786   Clause->setPrivates(Privates);
787   Clause->setLHSExprs(LHSExprs);
788   Clause->setRHSExprs(RHSExprs);
789   Clause->setReductionOps(ReductionOps);
790   Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
791   Clause->setPreInitStmt(PreInit);
792   Clause->setPostUpdateExpr(PostUpdate);
793   return Clause;
794 }
795 
796 OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
797                                                         unsigned N) {
798   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));
799   return new (Mem) OMPInReductionClause(N);
800 }
801 
802 OMPAllocateClause *
803 OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
804                           SourceLocation LParenLoc, Expr *Allocator,
805                           SourceLocation ColonLoc, SourceLocation EndLoc,
806                           ArrayRef<Expr *> VL) {
807   // Allocate space for private variables and initializer expressions.
808   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
809   auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
810                                              ColonLoc, EndLoc, VL.size());
811   Clause->setVarRefs(VL);
812   return Clause;
813 }
814 
815 OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,
816                                                   unsigned N) {
817   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
818   return new (Mem) OMPAllocateClause(N);
819 }
820 
821 OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
822                                        SourceLocation StartLoc,
823                                        SourceLocation LParenLoc,
824                                        SourceLocation EndLoc,
825                                        ArrayRef<Expr *> VL) {
826   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
827   OMPFlushClause *Clause =
828       new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
829   Clause->setVarRefs(VL);
830   return Clause;
831 }
832 
833 OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
834   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
835   return new (Mem) OMPFlushClause(N);
836 }
837 
838 OMPDependClause *
839 OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
840                         SourceLocation LParenLoc, SourceLocation EndLoc,
841                         OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
842                         SourceLocation ColonLoc, ArrayRef<Expr *> VL,
843                         unsigned NumLoops) {
844   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + NumLoops));
845   OMPDependClause *Clause = new (Mem)
846       OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
847   Clause->setVarRefs(VL);
848   Clause->setDependencyKind(DepKind);
849   Clause->setDependencyLoc(DepLoc);
850   Clause->setColonLoc(ColonLoc);
851   for (unsigned I = 0 ; I < NumLoops; ++I)
852     Clause->setLoopData(I, nullptr);
853   return Clause;
854 }
855 
856 OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,
857                                               unsigned NumLoops) {
858   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + NumLoops));
859   return new (Mem) OMPDependClause(N, NumLoops);
860 }
861 
862 void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
863   assert((getDependencyKind() == OMPC_DEPEND_sink ||
864           getDependencyKind() == OMPC_DEPEND_source) &&
865          NumLoop < NumLoops &&
866          "Expected sink or source depend + loop index must be less number of "
867          "loops.");
868   auto It = std::next(getVarRefs().end(), NumLoop);
869   *It = Cnt;
870 }
871 
872 Expr *OMPDependClause::getLoopData(unsigned NumLoop) {
873   assert((getDependencyKind() == OMPC_DEPEND_sink ||
874           getDependencyKind() == OMPC_DEPEND_source) &&
875          NumLoop < NumLoops &&
876          "Expected sink or source depend + loop index must be less number of "
877          "loops.");
878   auto It = std::next(getVarRefs().end(), NumLoop);
879   return *It;
880 }
881 
882 const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {
883   assert((getDependencyKind() == OMPC_DEPEND_sink ||
884           getDependencyKind() == OMPC_DEPEND_source) &&
885          NumLoop < NumLoops &&
886          "Expected sink or source depend + loop index must be less number of "
887          "loops.");
888   auto It = std::next(getVarRefs().end(), NumLoop);
889   return *It;
890 }
891 
892 unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
893     MappableExprComponentListsRef ComponentLists) {
894   unsigned TotalNum = 0u;
895   for (auto &C : ComponentLists)
896     TotalNum += C.size();
897   return TotalNum;
898 }
899 
900 unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
901     ArrayRef<const ValueDecl *> Declarations) {
902   unsigned TotalNum = 0u;
903   llvm::SmallPtrSet<const ValueDecl *, 8> Cache;
904   for (const ValueDecl *D : Declarations) {
905     const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
906     if (Cache.count(VD))
907       continue;
908     ++TotalNum;
909     Cache.insert(VD);
910   }
911   return TotalNum;
912 }
913 
914 OMPMapClause *OMPMapClause::Create(
915     const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
916     ArrayRef<ValueDecl *> Declarations,
917     MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
918     ArrayRef<OpenMPMapModifierKind> MapModifiers,
919     ArrayRef<SourceLocation> MapModifiersLoc,
920     NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
921     OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
922   OMPMappableExprListSizeTy Sizes;
923   Sizes.NumVars = Vars.size();
924   Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
925   Sizes.NumComponentLists = ComponentLists.size();
926   Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
927 
928   // We need to allocate:
929   // 2 x NumVars x Expr* - we have an original list expression and an associated
930   // user-defined mapper for each clause list entry.
931   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
932   // with each component list.
933   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
934   // number of lists for each unique declaration and the size of each component
935   // list.
936   // NumComponents x MappableComponent - the total of all the components in all
937   // the lists.
938   void *Mem = C.Allocate(
939       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
940                        OMPClauseMappableExprCommon::MappableComponent>(
941           2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
942           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
943           Sizes.NumComponents));
944   OMPMapClause *Clause = new (Mem)
945       OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
946                    Type, TypeIsImplicit, TypeLoc, Locs, Sizes);
947 
948   Clause->setVarRefs(Vars);
949   Clause->setUDMapperRefs(UDMapperRefs);
950   Clause->setClauseInfo(Declarations, ComponentLists);
951   Clause->setMapType(Type);
952   Clause->setMapLoc(TypeLoc);
953   return Clause;
954 }
955 
956 OMPMapClause *
957 OMPMapClause::CreateEmpty(const ASTContext &C,
958                           const OMPMappableExprListSizeTy &Sizes) {
959   void *Mem = C.Allocate(
960       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
961                        OMPClauseMappableExprCommon::MappableComponent>(
962           2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
963           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
964           Sizes.NumComponents));
965   return new (Mem) OMPMapClause(Sizes);
966 }
967 
968 OMPToClause *OMPToClause::Create(
969     const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
970     ArrayRef<ValueDecl *> Declarations,
971     MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
972     NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
973   OMPMappableExprListSizeTy Sizes;
974   Sizes.NumVars = Vars.size();
975   Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
976   Sizes.NumComponentLists = ComponentLists.size();
977   Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
978 
979   // We need to allocate:
980   // 2 x NumVars x Expr* - we have an original list expression and an associated
981   // user-defined mapper for each clause list entry.
982   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
983   // with each component list.
984   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
985   // number of lists for each unique declaration and the size of each component
986   // list.
987   // NumComponents x MappableComponent - the total of all the components in all
988   // the lists.
989   void *Mem = C.Allocate(
990       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
991                        OMPClauseMappableExprCommon::MappableComponent>(
992           2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
993           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
994           Sizes.NumComponents));
995 
996   auto *Clause = new (Mem) OMPToClause(UDMQualifierLoc, MapperId, Locs, Sizes);
997 
998   Clause->setVarRefs(Vars);
999   Clause->setUDMapperRefs(UDMapperRefs);
1000   Clause->setClauseInfo(Declarations, ComponentLists);
1001   return Clause;
1002 }
1003 
1004 OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C,
1005                                       const OMPMappableExprListSizeTy &Sizes) {
1006   void *Mem = C.Allocate(
1007       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1008                        OMPClauseMappableExprCommon::MappableComponent>(
1009           2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1010           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1011           Sizes.NumComponents));
1012   return new (Mem) OMPToClause(Sizes);
1013 }
1014 
1015 OMPFromClause *OMPFromClause::Create(
1016     const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1017     ArrayRef<ValueDecl *> Declarations,
1018     MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1019     NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1020   OMPMappableExprListSizeTy Sizes;
1021   Sizes.NumVars = Vars.size();
1022   Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1023   Sizes.NumComponentLists = ComponentLists.size();
1024   Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1025 
1026   // We need to allocate:
1027   // 2 x NumVars x Expr* - we have an original list expression and an associated
1028   // user-defined mapper for each clause list entry.
1029   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1030   // with each component list.
1031   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1032   // number of lists for each unique declaration and the size of each component
1033   // list.
1034   // NumComponents x MappableComponent - the total of all the components in all
1035   // the lists.
1036   void *Mem = C.Allocate(
1037       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1038                        OMPClauseMappableExprCommon::MappableComponent>(
1039           2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1040           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1041           Sizes.NumComponents));
1042 
1043   auto *Clause =
1044       new (Mem) OMPFromClause(UDMQualifierLoc, MapperId, Locs, Sizes);
1045 
1046   Clause->setVarRefs(Vars);
1047   Clause->setUDMapperRefs(UDMapperRefs);
1048   Clause->setClauseInfo(Declarations, ComponentLists);
1049   return Clause;
1050 }
1051 
1052 OMPFromClause *
1053 OMPFromClause::CreateEmpty(const ASTContext &C,
1054                            const OMPMappableExprListSizeTy &Sizes) {
1055   void *Mem = C.Allocate(
1056       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1057                        OMPClauseMappableExprCommon::MappableComponent>(
1058           2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1059           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1060           Sizes.NumComponents));
1061   return new (Mem) OMPFromClause(Sizes);
1062 }
1063 
1064 void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
1065   assert(VL.size() == varlist_size() &&
1066          "Number of private copies is not the same as the preallocated buffer");
1067   std::copy(VL.begin(), VL.end(), varlist_end());
1068 }
1069 
1070 void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
1071   assert(VL.size() == varlist_size() &&
1072          "Number of inits is not the same as the preallocated buffer");
1073   std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
1074 }
1075 
1076 OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
1077     const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1078     ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
1079     ArrayRef<ValueDecl *> Declarations,
1080     MappableExprComponentListsRef ComponentLists) {
1081   OMPMappableExprListSizeTy Sizes;
1082   Sizes.NumVars = Vars.size();
1083   Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1084   Sizes.NumComponentLists = ComponentLists.size();
1085   Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1086 
1087   // We need to allocate:
1088   // 3 x NumVars x Expr* - we have an original list expression for each clause
1089   // list entry and an equal number of private copies and inits.
1090   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1091   // with each component list.
1092   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1093   // number of lists for each unique declaration and the size of each component
1094   // list.
1095   // NumComponents x MappableComponent - the total of all the components in all
1096   // the lists.
1097   void *Mem = C.Allocate(
1098       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1099                        OMPClauseMappableExprCommon::MappableComponent>(
1100           3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1101           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1102           Sizes.NumComponents));
1103 
1104   OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
1105 
1106   Clause->setVarRefs(Vars);
1107   Clause->setPrivateCopies(PrivateVars);
1108   Clause->setInits(Inits);
1109   Clause->setClauseInfo(Declarations, ComponentLists);
1110   return Clause;
1111 }
1112 
1113 OMPUseDevicePtrClause *
1114 OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C,
1115                                    const OMPMappableExprListSizeTy &Sizes) {
1116   void *Mem = C.Allocate(
1117       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1118                        OMPClauseMappableExprCommon::MappableComponent>(
1119           3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1120           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1121           Sizes.NumComponents));
1122   return new (Mem) OMPUseDevicePtrClause(Sizes);
1123 }
1124 
1125 OMPIsDevicePtrClause *
1126 OMPIsDevicePtrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1127                              ArrayRef<Expr *> Vars,
1128                              ArrayRef<ValueDecl *> Declarations,
1129                              MappableExprComponentListsRef ComponentLists) {
1130   OMPMappableExprListSizeTy Sizes;
1131   Sizes.NumVars = Vars.size();
1132   Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1133   Sizes.NumComponentLists = ComponentLists.size();
1134   Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1135 
1136   // We need to allocate:
1137   // NumVars x Expr* - we have an original list expression for each clause list
1138   // entry.
1139   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1140   // with each component list.
1141   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1142   // number of lists for each unique declaration and the size of each component
1143   // list.
1144   // NumComponents x MappableComponent - the total of all the components in all
1145   // the lists.
1146   void *Mem = C.Allocate(
1147       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1148                        OMPClauseMappableExprCommon::MappableComponent>(
1149           Sizes.NumVars, Sizes.NumUniqueDeclarations,
1150           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1151           Sizes.NumComponents));
1152 
1153   OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);
1154 
1155   Clause->setVarRefs(Vars);
1156   Clause->setClauseInfo(Declarations, ComponentLists);
1157   return Clause;
1158 }
1159 
1160 OMPIsDevicePtrClause *
1161 OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,
1162                                   const OMPMappableExprListSizeTy &Sizes) {
1163   void *Mem = C.Allocate(
1164       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1165                        OMPClauseMappableExprCommon::MappableComponent>(
1166           Sizes.NumVars, Sizes.NumUniqueDeclarations,
1167           Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1168           Sizes.NumComponents));
1169   return new (Mem) OMPIsDevicePtrClause(Sizes);
1170 }
1171 
1172 OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
1173                                                    SourceLocation StartLoc,
1174                                                    SourceLocation LParenLoc,
1175                                                    SourceLocation EndLoc,
1176                                                    ArrayRef<Expr *> VL) {
1177   // Allocate space for nontemporal variables + private references.
1178   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
1179   auto *Clause =
1180       new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
1181   Clause->setVarRefs(VL);
1182   return Clause;
1183 }
1184 
1185 OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,
1186                                                         unsigned N) {
1187   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
1188   return new (Mem) OMPNontemporalClause(N);
1189 }
1190 
1191 void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {
1192   assert(VL.size() == varlist_size() && "Number of private references is not "
1193                                         "the same as the preallocated buffer");
1194   std::copy(VL.begin(), VL.end(), varlist_end());
1195 }
1196 
1197 //===----------------------------------------------------------------------===//
1198 //  OpenMP clauses printing methods
1199 //===----------------------------------------------------------------------===//
1200 
1201 void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
1202   OS << "if(";
1203   if (Node->getNameModifier() != llvm::omp::OMPD_unknown)
1204     OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
1205   Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1206   OS << ")";
1207 }
1208 
1209 void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
1210   OS << "final(";
1211   Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1212   OS << ")";
1213 }
1214 
1215 void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
1216   OS << "num_threads(";
1217   Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
1218   OS << ")";
1219 }
1220 
1221 void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
1222   OS << "safelen(";
1223   Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
1224   OS << ")";
1225 }
1226 
1227 void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
1228   OS << "simdlen(";
1229   Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);
1230   OS << ")";
1231 }
1232 
1233 void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
1234   OS << "allocator(";
1235   Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
1236   OS << ")";
1237 }
1238 
1239 void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
1240   OS << "collapse(";
1241   Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
1242   OS << ")";
1243 }
1244 
1245 void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
1246   OS << "default("
1247      << getOpenMPSimpleClauseTypeName(OMPC_default,
1248                                       unsigned(Node->getDefaultKind()))
1249      << ")";
1250 }
1251 
1252 void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
1253   OS << "proc_bind("
1254      << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
1255                                       unsigned(Node->getProcBindKind()))
1256      << ")";
1257 }
1258 
1259 void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
1260   OS << "unified_address";
1261 }
1262 
1263 void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
1264     OMPUnifiedSharedMemoryClause *) {
1265   OS << "unified_shared_memory";
1266 }
1267 
1268 void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
1269   OS << "reverse_offload";
1270 }
1271 
1272 void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
1273     OMPDynamicAllocatorsClause *) {
1274   OS << "dynamic_allocators";
1275 }
1276 
1277 void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
1278     OMPAtomicDefaultMemOrderClause *Node) {
1279   OS << "atomic_default_mem_order("
1280      << getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order,
1281                                       Node->getAtomicDefaultMemOrderKind())
1282      << ")";
1283 }
1284 
1285 void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
1286   OS << "schedule(";
1287   if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1288     OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
1289                                         Node->getFirstScheduleModifier());
1290     if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1291       OS << ", ";
1292       OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
1293                                           Node->getSecondScheduleModifier());
1294     }
1295     OS << ": ";
1296   }
1297   OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
1298   if (auto *E = Node->getChunkSize()) {
1299     OS << ", ";
1300     E->printPretty(OS, nullptr, Policy);
1301   }
1302   OS << ")";
1303 }
1304 
1305 void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
1306   OS << "ordered";
1307   if (auto *Num = Node->getNumForLoops()) {
1308     OS << "(";
1309     Num->printPretty(OS, nullptr, Policy, 0);
1310     OS << ")";
1311   }
1312 }
1313 
1314 void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
1315   OS << "nowait";
1316 }
1317 
1318 void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
1319   OS << "untied";
1320 }
1321 
1322 void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
1323   OS << "nogroup";
1324 }
1325 
1326 void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
1327   OS << "mergeable";
1328 }
1329 
1330 void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
1331 
1332 void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
1333 
1334 void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *) {
1335   OS << "update";
1336 }
1337 
1338 void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
1339   OS << "capture";
1340 }
1341 
1342 void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
1343   OS << "seq_cst";
1344 }
1345 
1346 void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
1347   OS << "acq_rel";
1348 }
1349 
1350 void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
1351   OS << "acquire";
1352 }
1353 
1354 void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
1355   OS << "release";
1356 }
1357 
1358 void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
1359   OS << "relaxed";
1360 }
1361 
1362 void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
1363   OS << "threads";
1364 }
1365 
1366 void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
1367 
1368 void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
1369   OS << "device(";
1370   Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
1371   OS << ")";
1372 }
1373 
1374 void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
1375   OS << "num_teams(";
1376   Node->getNumTeams()->printPretty(OS, nullptr, Policy, 0);
1377   OS << ")";
1378 }
1379 
1380 void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
1381   OS << "thread_limit(";
1382   Node->getThreadLimit()->printPretty(OS, nullptr, Policy, 0);
1383   OS << ")";
1384 }
1385 
1386 void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
1387   OS << "priority(";
1388   Node->getPriority()->printPretty(OS, nullptr, Policy, 0);
1389   OS << ")";
1390 }
1391 
1392 void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
1393   OS << "grainsize(";
1394   Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);
1395   OS << ")";
1396 }
1397 
1398 void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
1399   OS << "num_tasks(";
1400   Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
1401   OS << ")";
1402 }
1403 
1404 void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
1405   OS << "hint(";
1406   Node->getHint()->printPretty(OS, nullptr, Policy, 0);
1407   OS << ")";
1408 }
1409 
1410 template<typename T>
1411 void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
1412   for (typename T::varlist_iterator I = Node->varlist_begin(),
1413                                     E = Node->varlist_end();
1414        I != E; ++I) {
1415     assert(*I && "Expected non-null Stmt");
1416     OS << (I == Node->varlist_begin() ? StartSym : ',');
1417     if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
1418       if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
1419         DRE->printPretty(OS, nullptr, Policy, 0);
1420       else
1421         DRE->getDecl()->printQualifiedName(OS);
1422     } else
1423       (*I)->printPretty(OS, nullptr, Policy, 0);
1424   }
1425 }
1426 
1427 void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
1428   if (Node->varlist_empty())
1429     return;
1430   OS << "allocate";
1431   if (Expr *Allocator = Node->getAllocator()) {
1432     OS << "(";
1433     Allocator->printPretty(OS, nullptr, Policy, 0);
1434     OS << ":";
1435     VisitOMPClauseList(Node, ' ');
1436   } else {
1437     VisitOMPClauseList(Node, '(');
1438   }
1439   OS << ")";
1440 }
1441 
1442 void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
1443   if (!Node->varlist_empty()) {
1444     OS << "private";
1445     VisitOMPClauseList(Node, '(');
1446     OS << ")";
1447   }
1448 }
1449 
1450 void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
1451   if (!Node->varlist_empty()) {
1452     OS << "firstprivate";
1453     VisitOMPClauseList(Node, '(');
1454     OS << ")";
1455   }
1456 }
1457 
1458 void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
1459   if (!Node->varlist_empty()) {
1460     OS << "lastprivate";
1461     OpenMPLastprivateModifier LPKind = Node->getKind();
1462     if (LPKind != OMPC_LASTPRIVATE_unknown) {
1463       OS << "("
1464          << getOpenMPSimpleClauseTypeName(OMPC_lastprivate, Node->getKind())
1465          << ":";
1466     }
1467     VisitOMPClauseList(Node, LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
1468     OS << ")";
1469   }
1470 }
1471 
1472 void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
1473   if (!Node->varlist_empty()) {
1474     OS << "shared";
1475     VisitOMPClauseList(Node, '(');
1476     OS << ")";
1477   }
1478 }
1479 
1480 void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
1481   if (!Node->varlist_empty()) {
1482     OS << "reduction(";
1483     NestedNameSpecifier *QualifierLoc =
1484         Node->getQualifierLoc().getNestedNameSpecifier();
1485     OverloadedOperatorKind OOK =
1486         Node->getNameInfo().getName().getCXXOverloadedOperator();
1487     if (QualifierLoc == nullptr && OOK != OO_None) {
1488       // Print reduction identifier in C format
1489       OS << getOperatorSpelling(OOK);
1490     } else {
1491       // Use C++ format
1492       if (QualifierLoc != nullptr)
1493         QualifierLoc->print(OS, Policy);
1494       OS << Node->getNameInfo();
1495     }
1496     OS << ":";
1497     VisitOMPClauseList(Node, ' ');
1498     OS << ")";
1499   }
1500 }
1501 
1502 void OMPClausePrinter::VisitOMPTaskReductionClause(
1503     OMPTaskReductionClause *Node) {
1504   if (!Node->varlist_empty()) {
1505     OS << "task_reduction(";
1506     NestedNameSpecifier *QualifierLoc =
1507         Node->getQualifierLoc().getNestedNameSpecifier();
1508     OverloadedOperatorKind OOK =
1509         Node->getNameInfo().getName().getCXXOverloadedOperator();
1510     if (QualifierLoc == nullptr && OOK != OO_None) {
1511       // Print reduction identifier in C format
1512       OS << getOperatorSpelling(OOK);
1513     } else {
1514       // Use C++ format
1515       if (QualifierLoc != nullptr)
1516         QualifierLoc->print(OS, Policy);
1517       OS << Node->getNameInfo();
1518     }
1519     OS << ":";
1520     VisitOMPClauseList(Node, ' ');
1521     OS << ")";
1522   }
1523 }
1524 
1525 void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
1526   if (!Node->varlist_empty()) {
1527     OS << "in_reduction(";
1528     NestedNameSpecifier *QualifierLoc =
1529         Node->getQualifierLoc().getNestedNameSpecifier();
1530     OverloadedOperatorKind OOK =
1531         Node->getNameInfo().getName().getCXXOverloadedOperator();
1532     if (QualifierLoc == nullptr && OOK != OO_None) {
1533       // Print reduction identifier in C format
1534       OS << getOperatorSpelling(OOK);
1535     } else {
1536       // Use C++ format
1537       if (QualifierLoc != nullptr)
1538         QualifierLoc->print(OS, Policy);
1539       OS << Node->getNameInfo();
1540     }
1541     OS << ":";
1542     VisitOMPClauseList(Node, ' ');
1543     OS << ")";
1544   }
1545 }
1546 
1547 void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
1548   if (!Node->varlist_empty()) {
1549     OS << "linear";
1550     if (Node->getModifierLoc().isValid()) {
1551       OS << '('
1552          << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
1553     }
1554     VisitOMPClauseList(Node, '(');
1555     if (Node->getModifierLoc().isValid())
1556       OS << ')';
1557     if (Node->getStep() != nullptr) {
1558       OS << ": ";
1559       Node->getStep()->printPretty(OS, nullptr, Policy, 0);
1560     }
1561     OS << ")";
1562   }
1563 }
1564 
1565 void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
1566   if (!Node->varlist_empty()) {
1567     OS << "aligned";
1568     VisitOMPClauseList(Node, '(');
1569     if (Node->getAlignment() != nullptr) {
1570       OS << ": ";
1571       Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
1572     }
1573     OS << ")";
1574   }
1575 }
1576 
1577 void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
1578   if (!Node->varlist_empty()) {
1579     OS << "copyin";
1580     VisitOMPClauseList(Node, '(');
1581     OS << ")";
1582   }
1583 }
1584 
1585 void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
1586   if (!Node->varlist_empty()) {
1587     OS << "copyprivate";
1588     VisitOMPClauseList(Node, '(');
1589     OS << ")";
1590   }
1591 }
1592 
1593 void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
1594   if (!Node->varlist_empty()) {
1595     VisitOMPClauseList(Node, '(');
1596     OS << ")";
1597   }
1598 }
1599 
1600 void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
1601   OS << "depend(";
1602   OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
1603                                       Node->getDependencyKind());
1604   if (!Node->varlist_empty()) {
1605     OS << " :";
1606     VisitOMPClauseList(Node, ' ');
1607   }
1608   OS << ")";
1609 }
1610 
1611 void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
1612   if (!Node->varlist_empty()) {
1613     OS << "map(";
1614     if (Node->getMapType() != OMPC_MAP_unknown) {
1615       for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) {
1616         if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) {
1617           OS << getOpenMPSimpleClauseTypeName(OMPC_map,
1618                                               Node->getMapTypeModifier(I));
1619           if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper) {
1620             OS << '(';
1621             NestedNameSpecifier *MapperNNS =
1622                 Node->getMapperQualifierLoc().getNestedNameSpecifier();
1623             if (MapperNNS)
1624               MapperNNS->print(OS, Policy);
1625             OS << Node->getMapperIdInfo() << ')';
1626           }
1627           OS << ',';
1628         }
1629       }
1630       OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
1631       OS << ':';
1632     }
1633     VisitOMPClauseList(Node, ' ');
1634     OS << ")";
1635   }
1636 }
1637 
1638 void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
1639   if (!Node->varlist_empty()) {
1640     OS << "to";
1641     DeclarationNameInfo MapperId = Node->getMapperIdInfo();
1642     if (MapperId.getName() && !MapperId.getName().isEmpty()) {
1643       OS << '(';
1644       OS << "mapper(";
1645       NestedNameSpecifier *MapperNNS =
1646           Node->getMapperQualifierLoc().getNestedNameSpecifier();
1647       if (MapperNNS)
1648         MapperNNS->print(OS, Policy);
1649       OS << MapperId << "):";
1650       VisitOMPClauseList(Node, ' ');
1651     } else {
1652       VisitOMPClauseList(Node, '(');
1653     }
1654     OS << ")";
1655   }
1656 }
1657 
1658 void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
1659   if (!Node->varlist_empty()) {
1660     OS << "from";
1661     DeclarationNameInfo MapperId = Node->getMapperIdInfo();
1662     if (MapperId.getName() && !MapperId.getName().isEmpty()) {
1663       OS << '(';
1664       OS << "mapper(";
1665       NestedNameSpecifier *MapperNNS =
1666           Node->getMapperQualifierLoc().getNestedNameSpecifier();
1667       if (MapperNNS)
1668         MapperNNS->print(OS, Policy);
1669       OS << MapperId << "):";
1670       VisitOMPClauseList(Node, ' ');
1671     } else {
1672       VisitOMPClauseList(Node, '(');
1673     }
1674     OS << ")";
1675   }
1676 }
1677 
1678 void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
1679   OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
1680                            OMPC_dist_schedule, Node->getDistScheduleKind());
1681   if (auto *E = Node->getChunkSize()) {
1682     OS << ", ";
1683     E->printPretty(OS, nullptr, Policy);
1684   }
1685   OS << ")";
1686 }
1687 
1688 void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
1689   OS << "defaultmap(";
1690   OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
1691                                       Node->getDefaultmapModifier());
1692   OS << ": ";
1693   OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
1694     Node->getDefaultmapKind());
1695   OS << ")";
1696 }
1697 
1698 void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
1699   if (!Node->varlist_empty()) {
1700     OS << "use_device_ptr";
1701     VisitOMPClauseList(Node, '(');
1702     OS << ")";
1703   }
1704 }
1705 
1706 void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
1707   if (!Node->varlist_empty()) {
1708     OS << "is_device_ptr";
1709     VisitOMPClauseList(Node, '(');
1710     OS << ")";
1711   }
1712 }
1713 
1714 void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
1715   if (!Node->varlist_empty()) {
1716     OS << "nontemporal";
1717     VisitOMPClauseList(Node, '(');
1718     OS << ")";
1719   }
1720 }
1721 
1722 void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
1723   OS << "order(" << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind())
1724      << ")";
1725 }
1726 
1727 void OMPTraitInfo::getAsVariantMatchInfo(
1728     ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const {
1729   for (const OMPTraitSet &Set : Sets) {
1730     for (const OMPTraitSelector &Selector : Set.Selectors) {
1731 
1732       // User conditions are special as we evaluate the condition here.
1733       if (Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1734         assert(Selector.ScoreOrCondition &&
1735                "Ill-formed user condition, expected condition expression!");
1736         assert(Selector.Properties.size() == 1 &&
1737                Selector.Properties.front().Kind ==
1738                    llvm::omp::TraitProperty::user_condition_unknown &&
1739                "Ill-formed user condition, expected unknown trait property!");
1740 
1741         llvm::APInt CondVal =
1742             Selector.ScoreOrCondition->EvaluateKnownConstInt(ASTCtx);
1743         VMI.addTrait(CondVal.isNullValue()
1744                          ? llvm::omp::TraitProperty::user_condition_false
1745                          : llvm::omp::TraitProperty::user_condition_true);
1746         continue;
1747       }
1748 
1749       llvm::APInt Score;
1750       llvm::APInt *ScorePtr = nullptr;
1751       if (Selector.ScoreOrCondition) {
1752         Score = Selector.ScoreOrCondition->EvaluateKnownConstInt(ASTCtx);
1753         ScorePtr = &Score;
1754       }
1755       for (const OMPTraitProperty &Property : Selector.Properties)
1756         VMI.addTrait(Set.Kind, Property.Kind, ScorePtr);
1757 
1758       if (Set.Kind != llvm::omp::TraitSet::construct)
1759         continue;
1760 
1761       // TODO: This might not hold once we implement SIMD properly.
1762       assert(Selector.Properties.size() == 1 &&
1763              Selector.Properties.front().Kind ==
1764                  llvm::omp::getOpenMPContextTraitPropertyForSelector(
1765                      Selector.Kind) &&
1766              "Ill-formed construct selector!");
1767 
1768       VMI.ConstructTraits.push_back(Selector.Properties.front().Kind);
1769     }
1770   }
1771 }
1772 
1773 void OMPTraitInfo::print(llvm::raw_ostream &OS,
1774                          const PrintingPolicy &Policy) const {
1775   bool FirstSet = true;
1776   for (const OMPTraitInfo::OMPTraitSet &Set : Sets) {
1777     if (!FirstSet)
1778       OS << ", ";
1779     FirstSet = false;
1780     OS << llvm::omp::getOpenMPContextTraitSetName(Set.Kind) << "={";
1781 
1782     bool FirstSelector = true;
1783     for (const OMPTraitInfo::OMPTraitSelector &Selector : Set.Selectors) {
1784       if (!FirstSelector)
1785         OS << ", ";
1786       FirstSelector = false;
1787       OS << llvm::omp::getOpenMPContextTraitSelectorName(Selector.Kind);
1788 
1789       bool AllowsTraitScore = false;
1790       bool RequiresProperty = false;
1791       llvm::omp::isValidTraitSelectorForTraitSet(
1792           Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
1793 
1794       if (!RequiresProperty)
1795         continue;
1796 
1797       OS << "(";
1798       if (Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1799         Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
1800       } else {
1801 
1802         if (Selector.ScoreOrCondition) {
1803           OS << "score(";
1804           Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
1805           OS << "): ";
1806         }
1807 
1808         bool FirstProperty = true;
1809         for (const OMPTraitInfo::OMPTraitProperty &Property :
1810              Selector.Properties) {
1811           if (!FirstProperty)
1812             OS << ", ";
1813           FirstProperty = false;
1814           OS << llvm::omp::getOpenMPContextTraitPropertyName(Property.Kind);
1815         }
1816       }
1817       OS << ")";
1818     }
1819     OS << "}";
1820   }
1821 }
1822 
1823 llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
1824                                      const OMPTraitInfo &TI) {
1825   LangOptions LO;
1826   PrintingPolicy Policy(LO);
1827   TI.print(OS, Policy);
1828   return OS;
1829 }
1830