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