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 
16 #include "clang/AST/ASTContext.h"
17 
18 using namespace clang;
19 
20 OMPClause::child_range OMPClause::children() {
21   switch (getClauseKind()) {
22   default:
23     break;
24 #define OPENMP_CLAUSE(Name, Class)                                             \
25   case OMPC_##Name:                                                            \
26     return static_cast<Class *>(this)->children();
27 #include "clang/Basic/OpenMPKinds.def"
28   }
29   llvm_unreachable("unknown OMPClause");
30 }
31 
32 OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {
33   auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
34   return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
35 }
36 
37 const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
38   switch (C->getClauseKind()) {
39   case OMPC_schedule:
40     return static_cast<const OMPScheduleClause *>(C);
41   case OMPC_dist_schedule:
42     return static_cast<const OMPDistScheduleClause *>(C);
43   case OMPC_firstprivate:
44     return static_cast<const OMPFirstprivateClause *>(C);
45   case OMPC_lastprivate:
46     return static_cast<const OMPLastprivateClause *>(C);
47   case OMPC_reduction:
48     return static_cast<const OMPReductionClause *>(C);
49   case OMPC_task_reduction:
50     return static_cast<const OMPTaskReductionClause *>(C);
51   case OMPC_in_reduction:
52     return static_cast<const OMPInReductionClause *>(C);
53   case OMPC_linear:
54     return static_cast<const OMPLinearClause *>(C);
55   case OMPC_if:
56     return static_cast<const OMPIfClause *>(C);
57   case OMPC_num_threads:
58     return static_cast<const OMPNumThreadsClause *>(C);
59   case OMPC_num_teams:
60     return static_cast<const OMPNumTeamsClause *>(C);
61   case OMPC_thread_limit:
62     return static_cast<const OMPThreadLimitClause *>(C);
63   case OMPC_device:
64     return static_cast<const OMPDeviceClause *>(C);
65   case OMPC_default:
66   case OMPC_proc_bind:
67   case OMPC_final:
68   case OMPC_safelen:
69   case OMPC_simdlen:
70   case OMPC_collapse:
71   case OMPC_private:
72   case OMPC_shared:
73   case OMPC_aligned:
74   case OMPC_copyin:
75   case OMPC_copyprivate:
76   case OMPC_ordered:
77   case OMPC_nowait:
78   case OMPC_untied:
79   case OMPC_mergeable:
80   case OMPC_threadprivate:
81   case OMPC_flush:
82   case OMPC_read:
83   case OMPC_write:
84   case OMPC_update:
85   case OMPC_capture:
86   case OMPC_seq_cst:
87   case OMPC_depend:
88   case OMPC_threads:
89   case OMPC_simd:
90   case OMPC_map:
91   case OMPC_priority:
92   case OMPC_grainsize:
93   case OMPC_nogroup:
94   case OMPC_num_tasks:
95   case OMPC_hint:
96   case OMPC_defaultmap:
97   case OMPC_unknown:
98   case OMPC_uniform:
99   case OMPC_to:
100   case OMPC_from:
101   case OMPC_use_device_ptr:
102   case OMPC_is_device_ptr:
103     break;
104   }
105 
106   return nullptr;
107 }
108 
109 OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) {
110   auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));
111   return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
112 }
113 
114 const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) {
115   switch (C->getClauseKind()) {
116   case OMPC_lastprivate:
117     return static_cast<const OMPLastprivateClause *>(C);
118   case OMPC_reduction:
119     return static_cast<const OMPReductionClause *>(C);
120   case OMPC_task_reduction:
121     return static_cast<const OMPTaskReductionClause *>(C);
122   case OMPC_in_reduction:
123     return static_cast<const OMPInReductionClause *>(C);
124   case OMPC_linear:
125     return static_cast<const OMPLinearClause *>(C);
126   case OMPC_schedule:
127   case OMPC_dist_schedule:
128   case OMPC_firstprivate:
129   case OMPC_default:
130   case OMPC_proc_bind:
131   case OMPC_if:
132   case OMPC_final:
133   case OMPC_num_threads:
134   case OMPC_safelen:
135   case OMPC_simdlen:
136   case OMPC_collapse:
137   case OMPC_private:
138   case OMPC_shared:
139   case OMPC_aligned:
140   case OMPC_copyin:
141   case OMPC_copyprivate:
142   case OMPC_ordered:
143   case OMPC_nowait:
144   case OMPC_untied:
145   case OMPC_mergeable:
146   case OMPC_threadprivate:
147   case OMPC_flush:
148   case OMPC_read:
149   case OMPC_write:
150   case OMPC_update:
151   case OMPC_capture:
152   case OMPC_seq_cst:
153   case OMPC_depend:
154   case OMPC_device:
155   case OMPC_threads:
156   case OMPC_simd:
157   case OMPC_map:
158   case OMPC_num_teams:
159   case OMPC_thread_limit:
160   case OMPC_priority:
161   case OMPC_grainsize:
162   case OMPC_nogroup:
163   case OMPC_num_tasks:
164   case OMPC_hint:
165   case OMPC_defaultmap:
166   case OMPC_unknown:
167   case OMPC_uniform:
168   case OMPC_to:
169   case OMPC_from:
170   case OMPC_use_device_ptr:
171   case OMPC_is_device_ptr:
172     break;
173   }
174 
175   return nullptr;
176 }
177 
178 void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
179   assert(VL.size() == varlist_size() &&
180          "Number of private copies is not the same as the preallocated buffer");
181   std::copy(VL.begin(), VL.end(), varlist_end());
182 }
183 
184 OMPPrivateClause *
185 OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
186                          SourceLocation LParenLoc, SourceLocation EndLoc,
187                          ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
188   // Allocate space for private variables and initializer expressions.
189   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
190   OMPPrivateClause *Clause =
191       new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
192   Clause->setVarRefs(VL);
193   Clause->setPrivateCopies(PrivateVL);
194   return Clause;
195 }
196 
197 OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
198                                                 unsigned N) {
199   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
200   return new (Mem) OMPPrivateClause(N);
201 }
202 
203 void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
204   assert(VL.size() == varlist_size() &&
205          "Number of private copies is not the same as the preallocated buffer");
206   std::copy(VL.begin(), VL.end(), varlist_end());
207 }
208 
209 void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
210   assert(VL.size() == varlist_size() &&
211          "Number of inits is not the same as the preallocated buffer");
212   std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
213 }
214 
215 OMPFirstprivateClause *
216 OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
217                               SourceLocation LParenLoc, SourceLocation EndLoc,
218                               ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
219                               ArrayRef<Expr *> InitVL, Stmt *PreInit) {
220   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));
221   OMPFirstprivateClause *Clause =
222       new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
223   Clause->setVarRefs(VL);
224   Clause->setPrivateCopies(PrivateVL);
225   Clause->setInits(InitVL);
226   Clause->setPreInitStmt(PreInit);
227   return Clause;
228 }
229 
230 OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
231                                                           unsigned N) {
232   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));
233   return new (Mem) OMPFirstprivateClause(N);
234 }
235 
236 void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
237   assert(PrivateCopies.size() == varlist_size() &&
238          "Number of private copies is not the same as the preallocated buffer");
239   std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
240 }
241 
242 void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
243   assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
244                                               "not the same as the "
245                                               "preallocated buffer");
246   std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
247 }
248 
249 void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
250   assert(DstExprs.size() == varlist_size() && "Number of destination "
251                                               "expressions is not the same as "
252                                               "the preallocated buffer");
253   std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
254 }
255 
256 void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
257   assert(AssignmentOps.size() == varlist_size() &&
258          "Number of assignment expressions is not the same as the preallocated "
259          "buffer");
260   std::copy(AssignmentOps.begin(), AssignmentOps.end(),
261             getDestinationExprs().end());
262 }
263 
264 OMPLastprivateClause *OMPLastprivateClause::Create(
265     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
266     SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
267     ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps, Stmt *PreInit,
268     Expr *PostUpdate) {
269   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
270   OMPLastprivateClause *Clause =
271       new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
272   Clause->setVarRefs(VL);
273   Clause->setSourceExprs(SrcExprs);
274   Clause->setDestinationExprs(DstExprs);
275   Clause->setAssignmentOps(AssignmentOps);
276   Clause->setPreInitStmt(PreInit);
277   Clause->setPostUpdateExpr(PostUpdate);
278   return Clause;
279 }
280 
281 OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
282                                                         unsigned N) {
283   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
284   return new (Mem) OMPLastprivateClause(N);
285 }
286 
287 OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
288                                          SourceLocation StartLoc,
289                                          SourceLocation LParenLoc,
290                                          SourceLocation EndLoc,
291                                          ArrayRef<Expr *> VL) {
292   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
293   OMPSharedClause *Clause =
294       new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
295   Clause->setVarRefs(VL);
296   return Clause;
297 }
298 
299 OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
300   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
301   return new (Mem) OMPSharedClause(N);
302 }
303 
304 void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
305   assert(PL.size() == varlist_size() &&
306          "Number of privates is not the same as the preallocated buffer");
307   std::copy(PL.begin(), PL.end(), varlist_end());
308 }
309 
310 void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
311   assert(IL.size() == varlist_size() &&
312          "Number of inits is not the same as the preallocated buffer");
313   std::copy(IL.begin(), IL.end(), getPrivates().end());
314 }
315 
316 void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
317   assert(UL.size() == varlist_size() &&
318          "Number of updates is not the same as the preallocated buffer");
319   std::copy(UL.begin(), UL.end(), getInits().end());
320 }
321 
322 void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
323   assert(FL.size() == varlist_size() &&
324          "Number of final updates is not the same as the preallocated buffer");
325   std::copy(FL.begin(), FL.end(), getUpdates().end());
326 }
327 
328 OMPLinearClause *OMPLinearClause::Create(
329     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
330     OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
331     SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
332     ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
333     Stmt *PreInit, Expr *PostUpdate) {
334   // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
335   // (Step and CalcStep).
336   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2));
337   OMPLinearClause *Clause = new (Mem) OMPLinearClause(
338       StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
339   Clause->setVarRefs(VL);
340   Clause->setPrivates(PL);
341   Clause->setInits(IL);
342   // Fill update and final expressions with zeroes, they are provided later,
343   // after the directive construction.
344   std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
345             nullptr);
346   std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
347             nullptr);
348   Clause->setStep(Step);
349   Clause->setCalcStep(CalcStep);
350   Clause->setPreInitStmt(PreInit);
351   Clause->setPostUpdateExpr(PostUpdate);
352   return Clause;
353 }
354 
355 OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
356                                               unsigned NumVars) {
357   // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
358   // (Step and CalcStep).
359   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2));
360   return new (Mem) OMPLinearClause(NumVars);
361 }
362 
363 OMPAlignedClause *
364 OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
365                          SourceLocation LParenLoc, SourceLocation ColonLoc,
366                          SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
367   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
368   OMPAlignedClause *Clause = new (Mem)
369       OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
370   Clause->setVarRefs(VL);
371   Clause->setAlignment(A);
372   return Clause;
373 }
374 
375 OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
376                                                 unsigned NumVars) {
377   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));
378   return new (Mem) OMPAlignedClause(NumVars);
379 }
380 
381 void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
382   assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
383                                               "not the same as the "
384                                               "preallocated buffer");
385   std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
386 }
387 
388 void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
389   assert(DstExprs.size() == varlist_size() && "Number of destination "
390                                               "expressions is not the same as "
391                                               "the preallocated buffer");
392   std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
393 }
394 
395 void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
396   assert(AssignmentOps.size() == varlist_size() &&
397          "Number of assignment expressions is not the same as the preallocated "
398          "buffer");
399   std::copy(AssignmentOps.begin(), AssignmentOps.end(),
400             getDestinationExprs().end());
401 }
402 
403 OMPCopyinClause *OMPCopyinClause::Create(
404     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
405     SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
406     ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
407   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
408   OMPCopyinClause *Clause =
409       new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
410   Clause->setVarRefs(VL);
411   Clause->setSourceExprs(SrcExprs);
412   Clause->setDestinationExprs(DstExprs);
413   Clause->setAssignmentOps(AssignmentOps);
414   return Clause;
415 }
416 
417 OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
418   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
419   return new (Mem) OMPCopyinClause(N);
420 }
421 
422 void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
423   assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
424                                               "not the same as the "
425                                               "preallocated buffer");
426   std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
427 }
428 
429 void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
430   assert(DstExprs.size() == varlist_size() && "Number of destination "
431                                               "expressions is not the same as "
432                                               "the preallocated buffer");
433   std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
434 }
435 
436 void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
437   assert(AssignmentOps.size() == varlist_size() &&
438          "Number of assignment expressions is not the same as the preallocated "
439          "buffer");
440   std::copy(AssignmentOps.begin(), AssignmentOps.end(),
441             getDestinationExprs().end());
442 }
443 
444 OMPCopyprivateClause *OMPCopyprivateClause::Create(
445     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
446     SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
447     ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
448   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
449   OMPCopyprivateClause *Clause =
450       new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
451   Clause->setVarRefs(VL);
452   Clause->setSourceExprs(SrcExprs);
453   Clause->setDestinationExprs(DstExprs);
454   Clause->setAssignmentOps(AssignmentOps);
455   return Clause;
456 }
457 
458 OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
459                                                         unsigned N) {
460   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
461   return new (Mem) OMPCopyprivateClause(N);
462 }
463 
464 void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
465   assert(Privates.size() == varlist_size() &&
466          "Number of private copies is not the same as the preallocated buffer");
467   std::copy(Privates.begin(), Privates.end(), varlist_end());
468 }
469 
470 void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
471   assert(
472       LHSExprs.size() == varlist_size() &&
473       "Number of LHS expressions is not the same as the preallocated buffer");
474   std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
475 }
476 
477 void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
478   assert(
479       RHSExprs.size() == varlist_size() &&
480       "Number of RHS expressions is not the same as the preallocated buffer");
481   std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
482 }
483 
484 void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
485   assert(ReductionOps.size() == varlist_size() && "Number of reduction "
486                                                   "expressions is not the same "
487                                                   "as the preallocated buffer");
488   std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
489 }
490 
491 OMPReductionClause *OMPReductionClause::Create(
492     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
493     SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
494     NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
495     ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
496     ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
497     Expr *PostUpdate) {
498   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
499   OMPReductionClause *Clause = new (Mem) OMPReductionClause(
500       StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
501   Clause->setVarRefs(VL);
502   Clause->setPrivates(Privates);
503   Clause->setLHSExprs(LHSExprs);
504   Clause->setRHSExprs(RHSExprs);
505   Clause->setReductionOps(ReductionOps);
506   Clause->setPreInitStmt(PreInit);
507   Clause->setPostUpdateExpr(PostUpdate);
508   return Clause;
509 }
510 
511 OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
512                                                     unsigned N) {
513   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
514   return new (Mem) OMPReductionClause(N);
515 }
516 
517 void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
518   assert(Privates.size() == varlist_size() &&
519          "Number of private copies is not the same as the preallocated buffer");
520   std::copy(Privates.begin(), Privates.end(), varlist_end());
521 }
522 
523 void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
524   assert(
525       LHSExprs.size() == varlist_size() &&
526       "Number of LHS expressions is not the same as the preallocated buffer");
527   std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
528 }
529 
530 void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
531   assert(
532       RHSExprs.size() == varlist_size() &&
533       "Number of RHS expressions is not the same as the preallocated buffer");
534   std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
535 }
536 
537 void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
538   assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
539                                                   "expressions is not the same "
540                                                   "as the preallocated buffer");
541   std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
542 }
543 
544 OMPTaskReductionClause *OMPTaskReductionClause::Create(
545     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
546     SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
547     NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
548     ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
549     ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
550     Expr *PostUpdate) {
551   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
552   OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
553       StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
554   Clause->setVarRefs(VL);
555   Clause->setPrivates(Privates);
556   Clause->setLHSExprs(LHSExprs);
557   Clause->setRHSExprs(RHSExprs);
558   Clause->setReductionOps(ReductionOps);
559   Clause->setPreInitStmt(PreInit);
560   Clause->setPostUpdateExpr(PostUpdate);
561   return Clause;
562 }
563 
564 OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
565                                                             unsigned N) {
566   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
567   return new (Mem) OMPTaskReductionClause(N);
568 }
569 
570 void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
571   assert(Privates.size() == varlist_size() &&
572          "Number of private copies is not the same as the preallocated buffer");
573   std::copy(Privates.begin(), Privates.end(), varlist_end());
574 }
575 
576 void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
577   assert(
578       LHSExprs.size() == varlist_size() &&
579       "Number of LHS expressions is not the same as the preallocated buffer");
580   std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
581 }
582 
583 void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
584   assert(
585       RHSExprs.size() == varlist_size() &&
586       "Number of RHS expressions is not the same as the preallocated buffer");
587   std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
588 }
589 
590 void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
591   assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
592                                                   "expressions is not the same "
593                                                   "as the preallocated buffer");
594   std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
595 }
596 
597 void OMPInReductionClause::setTaskgroupDescriptors(
598     ArrayRef<Expr *> TaskgroupDescriptors) {
599   assert(TaskgroupDescriptors.size() == varlist_size() &&
600          "Number of in reduction descriptors is not the same as the "
601          "preallocated buffer");
602   std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(),
603             getReductionOps().end());
604 }
605 
606 OMPInReductionClause *OMPInReductionClause::Create(
607     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
608     SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
609     NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
610     ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
611     ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
612     ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
613   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));
614   OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
615       StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
616   Clause->setVarRefs(VL);
617   Clause->setPrivates(Privates);
618   Clause->setLHSExprs(LHSExprs);
619   Clause->setRHSExprs(RHSExprs);
620   Clause->setReductionOps(ReductionOps);
621   Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
622   Clause->setPreInitStmt(PreInit);
623   Clause->setPostUpdateExpr(PostUpdate);
624   return Clause;
625 }
626 
627 OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
628                                                         unsigned N) {
629   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));
630   return new (Mem) OMPInReductionClause(N);
631 }
632 
633 OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
634                                        SourceLocation StartLoc,
635                                        SourceLocation LParenLoc,
636                                        SourceLocation EndLoc,
637                                        ArrayRef<Expr *> VL) {
638   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
639   OMPFlushClause *Clause =
640       new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
641   Clause->setVarRefs(VL);
642   return Clause;
643 }
644 
645 OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
646   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
647   return new (Mem) OMPFlushClause(N);
648 }
649 
650 OMPDependClause *OMPDependClause::Create(
651     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
652     SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
653     SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL) {
654   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
655   OMPDependClause *Clause =
656       new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size());
657   Clause->setVarRefs(VL);
658   Clause->setDependencyKind(DepKind);
659   Clause->setDependencyLoc(DepLoc);
660   Clause->setColonLoc(ColonLoc);
661   Clause->setCounterValue(nullptr);
662   return Clause;
663 }
664 
665 OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) {
666   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1));
667   return new (Mem) OMPDependClause(N);
668 }
669 
670 void OMPDependClause::setCounterValue(Expr *V) {
671   assert(getDependencyKind() == OMPC_DEPEND_sink ||
672          getDependencyKind() == OMPC_DEPEND_source || V == nullptr);
673   *getVarRefs().end() = V;
674 }
675 
676 const Expr *OMPDependClause::getCounterValue() const {
677   auto *V = *getVarRefs().end();
678   assert(getDependencyKind() == OMPC_DEPEND_sink ||
679          getDependencyKind() == OMPC_DEPEND_source || V == nullptr);
680   return V;
681 }
682 
683 Expr *OMPDependClause::getCounterValue() {
684   auto *V = *getVarRefs().end();
685   assert(getDependencyKind() == OMPC_DEPEND_sink ||
686          getDependencyKind() == OMPC_DEPEND_source || V == nullptr);
687   return V;
688 }
689 
690 unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
691     MappableExprComponentListsRef ComponentLists) {
692   unsigned TotalNum = 0u;
693   for (auto &C : ComponentLists)
694     TotalNum += C.size();
695   return TotalNum;
696 }
697 
698 unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
699     ArrayRef<ValueDecl *> Declarations) {
700   unsigned TotalNum = 0u;
701   llvm::SmallPtrSet<const ValueDecl *, 8> Cache;
702   for (auto *D : Declarations) {
703     const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
704     if (Cache.count(VD))
705       continue;
706     ++TotalNum;
707     Cache.insert(VD);
708   }
709   return TotalNum;
710 }
711 
712 OMPMapClause *
713 OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc,
714                      SourceLocation LParenLoc, SourceLocation EndLoc,
715                      ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
716                      MappableExprComponentListsRef ComponentLists,
717                      OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type,
718                      bool TypeIsImplicit, SourceLocation TypeLoc) {
719 
720   unsigned NumVars = Vars.size();
721   unsigned NumUniqueDeclarations =
722       getUniqueDeclarationsTotalNumber(Declarations);
723   unsigned NumComponentLists = ComponentLists.size();
724   unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
725 
726   // We need to allocate:
727   // NumVars x Expr* - we have an original list expression for each clause list
728   // entry.
729   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
730   // with each component list.
731   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
732   // number of lists for each unique declaration and the size of each component
733   // list.
734   // NumComponents x MappableComponent - the total of all the components in all
735   // the lists.
736   void *Mem = C.Allocate(
737       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
738                        OMPClauseMappableExprCommon::MappableComponent>(
739           NumVars, NumUniqueDeclarations,
740           NumUniqueDeclarations + NumComponentLists, NumComponents));
741   OMPMapClause *Clause = new (Mem) OMPMapClause(
742       TypeModifier, Type, TypeIsImplicit, TypeLoc, StartLoc, LParenLoc, EndLoc,
743       NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents);
744 
745   Clause->setVarRefs(Vars);
746   Clause->setClauseInfo(Declarations, ComponentLists);
747   Clause->setMapTypeModifier(TypeModifier);
748   Clause->setMapType(Type);
749   Clause->setMapLoc(TypeLoc);
750   return Clause;
751 }
752 
753 OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
754                                         unsigned NumUniqueDeclarations,
755                                         unsigned NumComponentLists,
756                                         unsigned NumComponents) {
757   void *Mem = C.Allocate(
758       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
759                        OMPClauseMappableExprCommon::MappableComponent>(
760           NumVars, NumUniqueDeclarations,
761           NumUniqueDeclarations + NumComponentLists, NumComponents));
762   return new (Mem) OMPMapClause(NumVars, NumUniqueDeclarations,
763                                 NumComponentLists, NumComponents);
764 }
765 
766 OMPToClause *OMPToClause::Create(const ASTContext &C, SourceLocation StartLoc,
767                                  SourceLocation LParenLoc,
768                                  SourceLocation EndLoc, ArrayRef<Expr *> Vars,
769                                  ArrayRef<ValueDecl *> Declarations,
770                                  MappableExprComponentListsRef ComponentLists) {
771   unsigned NumVars = Vars.size();
772   unsigned NumUniqueDeclarations =
773       getUniqueDeclarationsTotalNumber(Declarations);
774   unsigned NumComponentLists = ComponentLists.size();
775   unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
776 
777   // We need to allocate:
778   // NumVars x Expr* - we have an original list expression for each clause list
779   // entry.
780   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
781   // with each component list.
782   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
783   // number of lists for each unique declaration and the size of each component
784   // list.
785   // NumComponents x MappableComponent - the total of all the components in all
786   // the lists.
787   void *Mem = C.Allocate(
788       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
789                        OMPClauseMappableExprCommon::MappableComponent>(
790           NumVars, NumUniqueDeclarations,
791           NumUniqueDeclarations + NumComponentLists, NumComponents));
792 
793   OMPToClause *Clause = new (Mem)
794       OMPToClause(StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
795                   NumComponentLists, NumComponents);
796 
797   Clause->setVarRefs(Vars);
798   Clause->setClauseInfo(Declarations, ComponentLists);
799   return Clause;
800 }
801 
802 OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
803                                       unsigned NumUniqueDeclarations,
804                                       unsigned NumComponentLists,
805                                       unsigned NumComponents) {
806   void *Mem = C.Allocate(
807       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
808                        OMPClauseMappableExprCommon::MappableComponent>(
809           NumVars, NumUniqueDeclarations,
810           NumUniqueDeclarations + NumComponentLists, NumComponents));
811   return new (Mem) OMPToClause(NumVars, NumUniqueDeclarations,
812                                NumComponentLists, NumComponents);
813 }
814 
815 OMPFromClause *
816 OMPFromClause::Create(const ASTContext &C, SourceLocation StartLoc,
817                       SourceLocation LParenLoc, SourceLocation EndLoc,
818                       ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
819                       MappableExprComponentListsRef ComponentLists) {
820   unsigned NumVars = Vars.size();
821   unsigned NumUniqueDeclarations =
822       getUniqueDeclarationsTotalNumber(Declarations);
823   unsigned NumComponentLists = ComponentLists.size();
824   unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
825 
826   // We need to allocate:
827   // NumVars x Expr* - we have an original list expression for each clause list
828   // entry.
829   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
830   // with each component list.
831   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
832   // number of lists for each unique declaration and the size of each component
833   // list.
834   // NumComponents x MappableComponent - the total of all the components in all
835   // the lists.
836   void *Mem = C.Allocate(
837       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
838                        OMPClauseMappableExprCommon::MappableComponent>(
839           NumVars, NumUniqueDeclarations,
840           NumUniqueDeclarations + NumComponentLists, NumComponents));
841 
842   OMPFromClause *Clause = new (Mem)
843       OMPFromClause(StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
844                     NumComponentLists, NumComponents);
845 
846   Clause->setVarRefs(Vars);
847   Clause->setClauseInfo(Declarations, ComponentLists);
848   return Clause;
849 }
850 
851 OMPFromClause *OMPFromClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
852                                           unsigned NumUniqueDeclarations,
853                                           unsigned NumComponentLists,
854                                           unsigned NumComponents) {
855   void *Mem = C.Allocate(
856       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
857                        OMPClauseMappableExprCommon::MappableComponent>(
858           NumVars, NumUniqueDeclarations,
859           NumUniqueDeclarations + NumComponentLists, NumComponents));
860   return new (Mem) OMPFromClause(NumVars, NumUniqueDeclarations,
861                                  NumComponentLists, NumComponents);
862 }
863 
864 void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
865   assert(VL.size() == varlist_size() &&
866          "Number of private copies is not the same as the preallocated buffer");
867   std::copy(VL.begin(), VL.end(), varlist_end());
868 }
869 
870 void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
871   assert(VL.size() == varlist_size() &&
872          "Number of inits is not the same as the preallocated buffer");
873   std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
874 }
875 
876 OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
877     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
878     SourceLocation EndLoc, ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars,
879     ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations,
880     MappableExprComponentListsRef ComponentLists) {
881   unsigned NumVars = Vars.size();
882   unsigned NumUniqueDeclarations =
883       getUniqueDeclarationsTotalNumber(Declarations);
884   unsigned NumComponentLists = ComponentLists.size();
885   unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
886 
887   // We need to allocate:
888   // 3 x NumVars x Expr* - we have an original list expression for each clause
889   // list entry and an equal number of private copies and inits.
890   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
891   // with each component list.
892   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
893   // number of lists for each unique declaration and the size of each component
894   // list.
895   // NumComponents x MappableComponent - the total of all the components in all
896   // the lists.
897   void *Mem = C.Allocate(
898       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
899                        OMPClauseMappableExprCommon::MappableComponent>(
900           3 * NumVars, NumUniqueDeclarations,
901           NumUniqueDeclarations + NumComponentLists, NumComponents));
902 
903   OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(
904       StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
905       NumComponentLists, NumComponents);
906 
907   Clause->setVarRefs(Vars);
908   Clause->setPrivateCopies(PrivateVars);
909   Clause->setInits(Inits);
910   Clause->setClauseInfo(Declarations, ComponentLists);
911   return Clause;
912 }
913 
914 OMPUseDevicePtrClause *OMPUseDevicePtrClause::CreateEmpty(
915     const ASTContext &C, unsigned NumVars, unsigned NumUniqueDeclarations,
916     unsigned NumComponentLists, unsigned NumComponents) {
917   void *Mem = C.Allocate(
918       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
919                        OMPClauseMappableExprCommon::MappableComponent>(
920           3 * NumVars, NumUniqueDeclarations,
921           NumUniqueDeclarations + NumComponentLists, NumComponents));
922   return new (Mem) OMPUseDevicePtrClause(NumVars, NumUniqueDeclarations,
923                                          NumComponentLists, NumComponents);
924 }
925 
926 OMPIsDevicePtrClause *
927 OMPIsDevicePtrClause::Create(const ASTContext &C, SourceLocation StartLoc,
928                              SourceLocation LParenLoc, SourceLocation EndLoc,
929                              ArrayRef<Expr *> Vars,
930                              ArrayRef<ValueDecl *> Declarations,
931                              MappableExprComponentListsRef ComponentLists) {
932   unsigned NumVars = Vars.size();
933   unsigned NumUniqueDeclarations =
934       getUniqueDeclarationsTotalNumber(Declarations);
935   unsigned NumComponentLists = ComponentLists.size();
936   unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
937 
938   // We need to allocate:
939   // NumVars x Expr* - we have an original list expression for each clause list
940   // entry.
941   // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
942   // with each component list.
943   // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
944   // number of lists for each unique declaration and the size of each component
945   // list.
946   // NumComponents x MappableComponent - the total of all the components in all
947   // the lists.
948   void *Mem = C.Allocate(
949       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
950                        OMPClauseMappableExprCommon::MappableComponent>(
951           NumVars, NumUniqueDeclarations,
952           NumUniqueDeclarations + NumComponentLists, NumComponents));
953 
954   OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(
955       StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
956       NumComponentLists, NumComponents);
957 
958   Clause->setVarRefs(Vars);
959   Clause->setClauseInfo(Declarations, ComponentLists);
960   return Clause;
961 }
962 
963 OMPIsDevicePtrClause *OMPIsDevicePtrClause::CreateEmpty(
964     const ASTContext &C, unsigned NumVars, unsigned NumUniqueDeclarations,
965     unsigned NumComponentLists, unsigned NumComponents) {
966   void *Mem = C.Allocate(
967       totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
968                        OMPClauseMappableExprCommon::MappableComponent>(
969           NumVars, NumUniqueDeclarations,
970           NumUniqueDeclarations + NumComponentLists, NumComponents));
971   return new (Mem) OMPIsDevicePtrClause(NumVars, NumUniqueDeclarations,
972                                         NumComponentLists, NumComponents);
973 }
974