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