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