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