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