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