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