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