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