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