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