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