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