1//===- OpenMPClause.cpp - Classes for OpenMP clauses ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the subclesses of Stmt class declared in OpenMPClause.h
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/OpenMPClause.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Attr.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclOpenMP.h"
18#include "clang/Basic/LLVM.h"
19#include "clang/Basic/OpenMPKinds.h"
20#include "clang/Basic/TargetInfo.h"
21#include "llvm/ADT/SmallPtrSet.h"
22#include "llvm/Support/Casting.h"
23#include "llvm/Support/ErrorHandling.h"
24#include <algorithm>
25#include <cassert>
26#include <optional>
27
28using namespace clang;
29using namespace llvm;
30using namespace omp;
31
32OMPClause::child_range OMPClause::children() {
33  switch (getClauseKind()) {
34  default:
35    break;
36#define GEN_CLANG_CLAUSE_CLASS
37#define CLAUSE_CLASS(Enum, Str, Class)                                         \
38  case Enum:                                                                   \
39    return static_cast<Class *>(this)->children();
40#include "llvm/Frontend/OpenMP/OMP.inc"
41  }
42  llvm_unreachable("unknown OMPClause");
43}
44
45OMPClause::child_range OMPClause::used_children() {
46  switch (getClauseKind()) {
47#define GEN_CLANG_CLAUSE_CLASS
48#define CLAUSE_CLASS(Enum, Str, Class)                                         \
49  case Enum:                                                                   \
50    return static_cast<Class *>(this)->used_children();
51#define CLAUSE_NO_CLASS(Enum, Str)                                             \
52  case Enum:                                                                   \
53    break;
54#include "llvm/Frontend/OpenMP/OMP.inc"
55  }
56  llvm_unreachable("unknown OMPClause");
57}
58
59OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {
60  auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
61  return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
62}
63
64const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
65  switch (C->getClauseKind()) {
66  case OMPC_schedule:
67    return static_cast<const OMPScheduleClause *>(C);
68  case OMPC_dist_schedule:
69    return static_cast<const OMPDistScheduleClause *>(C);
70  case OMPC_firstprivate:
71    return static_cast<const OMPFirstprivateClause *>(C);
72  case OMPC_lastprivate:
73    return static_cast<const OMPLastprivateClause *>(C);
74  case OMPC_reduction:
75    return static_cast<const OMPReductionClause *>(C);
76  case OMPC_task_reduction:
77    return static_cast<const OMPTaskReductionClause *>(C);
78  case OMPC_in_reduction:
79    return static_cast<const OMPInReductionClause *>(C);
80  case OMPC_linear:
81    return static_cast<const OMPLinearClause *>(C);
82  case OMPC_if:
83    return static_cast<const OMPIfClause *>(C);
84  case OMPC_num_threads:
85    return static_cast<const OMPNumThreadsClause *>(C);
86  case OMPC_num_teams:
87    return static_cast<const OMPNumTeamsClause *>(C);
88  case OMPC_thread_limit:
89    return static_cast<const OMPThreadLimitClause *>(C);
90  case OMPC_device:
91    return static_cast<const OMPDeviceClause *>(C);
92  case OMPC_grainsize:
93    return static_cast<const OMPGrainsizeClause *>(C);
94  case OMPC_num_tasks:
95    return static_cast<const OMPNumTasksClause *>(C);
96  case OMPC_final:
97    return static_cast<const OMPFinalClause *>(C);
98  case OMPC_priority:
99    return static_cast<const OMPPriorityClause *>(C);
100  case OMPC_novariants:
101    return static_cast<const OMPNovariantsClause *>(C);
102  case OMPC_nocontext:
103    return static_cast<const OMPNocontextClause *>(C);
104  case OMPC_filter:
105    return static_cast<const OMPFilterClause *>(C);
106  case OMPC_ompx_dyn_cgroup_mem:
107    return static_cast<const OMPXDynCGroupMemClause *>(C);
108  case OMPC_default:
109  case OMPC_proc_bind:
110  case OMPC_safelen:
111  case OMPC_simdlen:
112  case OMPC_sizes:
113  case OMPC_allocator:
114  case OMPC_allocate:
115  case OMPC_collapse:
116  case OMPC_private:
117  case OMPC_shared:
118  case OMPC_aligned:
119  case OMPC_copyin:
120  case OMPC_copyprivate:
121  case OMPC_ordered:
122  case OMPC_nowait:
123  case OMPC_untied:
124  case OMPC_mergeable:
125  case OMPC_threadprivate:
126  case OMPC_flush:
127  case OMPC_depobj:
128  case OMPC_read:
129  case OMPC_write:
130  case OMPC_update:
131  case OMPC_capture:
132  case OMPC_compare:
133  case OMPC_seq_cst:
134  case OMPC_acq_rel:
135  case OMPC_acquire:
136  case OMPC_release:
137  case OMPC_relaxed:
138  case OMPC_depend:
139  case OMPC_threads:
140  case OMPC_simd:
141  case OMPC_map:
142  case OMPC_nogroup:
143  case OMPC_hint:
144  case OMPC_defaultmap:
145  case OMPC_unknown:
146  case OMPC_uniform:
147  case OMPC_to:
148  case OMPC_from:
149  case OMPC_use_device_ptr:
150  case OMPC_use_device_addr:
151  case OMPC_is_device_ptr:
152  case OMPC_has_device_addr:
153  case OMPC_unified_address:
154  case OMPC_unified_shared_memory:
155  case OMPC_reverse_offload:
156  case OMPC_dynamic_allocators:
157  case OMPC_atomic_default_mem_order:
158  case OMPC_at:
159  case OMPC_severity:
160  case OMPC_message:
161  case OMPC_device_type:
162  case OMPC_match:
163  case OMPC_nontemporal:
164  case OMPC_order:
165  case OMPC_destroy:
166  case OMPC_detach:
167  case OMPC_inclusive:
168  case OMPC_exclusive:
169  case OMPC_uses_allocators:
170  case OMPC_affinity:
171  case OMPC_when:
172  case OMPC_bind:
173    break;
174  default:
175    break;
176  }
177
178  return nullptr;
179}
180
181OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) {
182  auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));
183  return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
184}
185
186const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) {
187  switch (C->getClauseKind()) {
188  case OMPC_lastprivate:
189    return static_cast<const OMPLastprivateClause *>(C);
190  case OMPC_reduction:
191    return static_cast<const OMPReductionClause *>(C);
192  case OMPC_task_reduction:
193    return static_cast<const OMPTaskReductionClause *>(C);
194  case OMPC_in_reduction:
195    return static_cast<const OMPInReductionClause *>(C);
196  case OMPC_linear:
197    return static_cast<const OMPLinearClause *>(C);
198  case OMPC_schedule:
199  case OMPC_dist_schedule:
200  case OMPC_firstprivate:
201  case OMPC_default:
202  case OMPC_proc_bind:
203  case OMPC_if:
204  case OMPC_final:
205  case OMPC_num_threads:
206  case OMPC_safelen:
207  case OMPC_simdlen:
208  case OMPC_sizes:
209  case OMPC_allocator:
210  case OMPC_allocate:
211  case OMPC_collapse:
212  case OMPC_private:
213  case OMPC_shared:
214  case OMPC_aligned:
215  case OMPC_copyin:
216  case OMPC_copyprivate:
217  case OMPC_ordered:
218  case OMPC_nowait:
219  case OMPC_untied:
220  case OMPC_mergeable:
221  case OMPC_threadprivate:
222  case OMPC_flush:
223  case OMPC_depobj:
224  case OMPC_read:
225  case OMPC_write:
226  case OMPC_update:
227  case OMPC_capture:
228  case OMPC_compare:
229  case OMPC_seq_cst:
230  case OMPC_acq_rel:
231  case OMPC_acquire:
232  case OMPC_release:
233  case OMPC_relaxed:
234  case OMPC_depend:
235  case OMPC_device:
236  case OMPC_threads:
237  case OMPC_simd:
238  case OMPC_map:
239  case OMPC_num_teams:
240  case OMPC_thread_limit:
241  case OMPC_priority:
242  case OMPC_grainsize:
243  case OMPC_nogroup:
244  case OMPC_num_tasks:
245  case OMPC_hint:
246  case OMPC_defaultmap:
247  case OMPC_unknown:
248  case OMPC_uniform:
249  case OMPC_to:
250  case OMPC_from:
251  case OMPC_use_device_ptr:
252  case OMPC_use_device_addr:
253  case OMPC_is_device_ptr:
254  case OMPC_has_device_addr:
255  case OMPC_unified_address:
256  case OMPC_unified_shared_memory:
257  case OMPC_reverse_offload:
258  case OMPC_dynamic_allocators:
259  case OMPC_atomic_default_mem_order:
260  case OMPC_at:
261  case OMPC_severity:
262  case OMPC_message:
263  case OMPC_device_type:
264  case OMPC_match:
265  case OMPC_nontemporal:
266  case OMPC_order:
267  case OMPC_destroy:
268  case OMPC_novariants:
269  case OMPC_nocontext:
270  case OMPC_detach:
271  case OMPC_inclusive:
272  case OMPC_exclusive:
273  case OMPC_uses_allocators:
274  case OMPC_affinity:
275  case OMPC_when:
276  case OMPC_bind:
277    break;
278  default:
279    break;
280  }
281
282  return nullptr;
283}
284
285/// Gets the address of the original, non-captured, expression used in the
286/// clause as the preinitializer.
287static Stmt **getAddrOfExprAsWritten(Stmt *S) {
288  if (!S)
289    return nullptr;
290  if (auto *DS = dyn_cast<DeclStmt>(S)) {
291    assert(DS->isSingleDecl() && "Only single expression must be captured.");
292    if (auto *OED = dyn_cast<OMPCapturedExprDecl>(DS->getSingleDecl()))
293      return OED->getInitAddress();
294  }
295  return nullptr;
296}
297
298OMPClause::child_range OMPIfClause::used_children() {
299  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
300    return child_range(C, C + 1);
301  return child_range(&Condition, &Condition + 1);
302}
303
304OMPClause::child_range OMPGrainsizeClause::used_children() {
305  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
306    return child_range(C, C + 1);
307  return child_range(&Grainsize, &Grainsize + 1);
308}
309
310OMPClause::child_range OMPNumTasksClause::used_children() {
311  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
312    return child_range(C, C + 1);
313  return child_range(&NumTasks, &NumTasks + 1);
314}
315
316OMPClause::child_range OMPFinalClause::used_children() {
317  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
318    return child_range(C, C + 1);
319  return children();
320}
321
322OMPClause::child_range OMPPriorityClause::used_children() {
323  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
324    return child_range(C, C + 1);
325  return child_range(&Priority, &Priority + 1);
326}
327
328OMPClause::child_range OMPNovariantsClause::used_children() {
329  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
330    return child_range(C, C + 1);
331  return children();
332}
333
334OMPClause::child_range OMPNocontextClause::used_children() {
335  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
336    return child_range(C, C + 1);
337  return children();
338}
339
340OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,
341                                           unsigned NumLoops,
342                                           SourceLocation StartLoc,
343                                           SourceLocation LParenLoc,
344                                           SourceLocation EndLoc) {
345  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
346  auto *Clause =
347      new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);
348  for (unsigned I = 0; I < NumLoops; ++I) {
349    Clause->setLoopNumIterations(I, nullptr);
350    Clause->setLoopCounter(I, nullptr);
351  }
352  return Clause;
353}
354
355OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C,
356                                                unsigned NumLoops) {
357  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
358  auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
359  for (unsigned I = 0; I < NumLoops; ++I) {
360    Clause->setLoopNumIterations(I, nullptr);
361    Clause->setLoopCounter(I, nullptr);
362  }
363  return Clause;
364}
365
366void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop,
367                                            Expr *NumIterations) {
368  assert(NumLoop < NumberOfLoops && "out of loops number.");
369  getTrailingObjects<Expr *>()[NumLoop] = NumIterations;
370}
371
372ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations() const {
373  return llvm::ArrayRef(getTrailingObjects<Expr *>(), NumberOfLoops);
374}
375
376void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {
377  assert(NumLoop < NumberOfLoops && "out of loops number.");
378  getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop] = Counter;
379}
380
381Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) {
382  assert(NumLoop < NumberOfLoops && "out of loops number.");
383  return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
384}
385
386const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
387  assert(NumLoop < NumberOfLoops && "out of loops number.");
388  return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
389}
390
391OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C,
392                                         SourceLocation StartLoc,
393                                         SourceLocation EndLoc) {
394  return new (C) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/false);
395}
396
397OMPUpdateClause *
398OMPUpdateClause::Create(const ASTContext &C, SourceLocation StartLoc,
399                        SourceLocation LParenLoc, SourceLocation ArgumentLoc,
400                        OpenMPDependClauseKind DK, SourceLocation EndLoc) {
401  void *Mem =
402      C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
403                 alignof(OMPUpdateClause));
404  auto *Clause =
405      new (Mem) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/true);
406  Clause->setLParenLoc(LParenLoc);
407  Clause->setArgumentLoc(ArgumentLoc);
408  Clause->setDependencyKind(DK);
409  return Clause;
410}
411
412OMPUpdateClause *OMPUpdateClause::CreateEmpty(const ASTContext &C,
413                                              bool IsExtended) {
414  if (!IsExtended)
415    return new (C) OMPUpdateClause(/*IsExtended=*/false);
416  void *Mem =
417      C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
418                 alignof(OMPUpdateClause));
419  auto *Clause = new (Mem) OMPUpdateClause(/*IsExtended=*/true);
420  Clause->IsExtended = true;
421  return Clause;
422}
423
424void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
425  assert(VL.size() == varlist_size() &&
426         "Number of private copies is not the same as the preallocated buffer");
427  std::copy(VL.begin(), VL.end(), varlist_end());
428}
429
430OMPPrivateClause *
431OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
432                         SourceLocation LParenLoc, SourceLocation EndLoc,
433                         ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
434  // Allocate space for private variables and initializer expressions.
435  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
436  OMPPrivateClause *Clause =
437      new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
438  Clause->setVarRefs(VL);
439  Clause->setPrivateCopies(PrivateVL);
440  return Clause;
441}
442
443OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
444                                                unsigned N) {
445  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
446  return new (Mem) OMPPrivateClause(N);
447}
448
449void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
450  assert(VL.size() == varlist_size() &&
451         "Number of private copies is not the same as the preallocated buffer");
452  std::copy(VL.begin(), VL.end(), varlist_end());
453}
454
455void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
456  assert(VL.size() == varlist_size() &&
457         "Number of inits is not the same as the preallocated buffer");
458  std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
459}
460
461OMPFirstprivateClause *
462OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
463                              SourceLocation LParenLoc, SourceLocation EndLoc,
464                              ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
465                              ArrayRef<Expr *> InitVL, Stmt *PreInit) {
466  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));
467  OMPFirstprivateClause *Clause =
468      new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
469  Clause->setVarRefs(VL);
470  Clause->setPrivateCopies(PrivateVL);
471  Clause->setInits(InitVL);
472  Clause->setPreInitStmt(PreInit);
473  return Clause;
474}
475
476OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
477                                                          unsigned N) {
478  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));
479  return new (Mem) OMPFirstprivateClause(N);
480}
481
482void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
483  assert(PrivateCopies.size() == varlist_size() &&
484         "Number of private copies is not the same as the preallocated buffer");
485  std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
486}
487
488void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
489  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
490                                              "not the same as the "
491                                              "preallocated buffer");
492  std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
493}
494
495void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
496  assert(DstExprs.size() == varlist_size() && "Number of destination "
497                                              "expressions is not the same as "
498                                              "the preallocated buffer");
499  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
500}
501
502void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
503  assert(AssignmentOps.size() == varlist_size() &&
504         "Number of assignment expressions is not the same as the preallocated "
505         "buffer");
506  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
507            getDestinationExprs().end());
508}
509
510OMPLastprivateClause *OMPLastprivateClause::Create(
511    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
512    SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
513    ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
514    OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,
515    SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {
516  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
517  OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(
518      StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());
519  Clause->setVarRefs(VL);
520  Clause->setSourceExprs(SrcExprs);
521  Clause->setDestinationExprs(DstExprs);
522  Clause->setAssignmentOps(AssignmentOps);
523  Clause->setPreInitStmt(PreInit);
524  Clause->setPostUpdateExpr(PostUpdate);
525  return Clause;
526}
527
528OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
529                                                        unsigned N) {
530  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
531  return new (Mem) OMPLastprivateClause(N);
532}
533
534OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
535                                         SourceLocation StartLoc,
536                                         SourceLocation LParenLoc,
537                                         SourceLocation EndLoc,
538                                         ArrayRef<Expr *> VL) {
539  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
540  OMPSharedClause *Clause =
541      new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
542  Clause->setVarRefs(VL);
543  return Clause;
544}
545
546OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
547  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
548  return new (Mem) OMPSharedClause(N);
549}
550
551void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
552  assert(PL.size() == varlist_size() &&
553         "Number of privates is not the same as the preallocated buffer");
554  std::copy(PL.begin(), PL.end(), varlist_end());
555}
556
557void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
558  assert(IL.size() == varlist_size() &&
559         "Number of inits is not the same as the preallocated buffer");
560  std::copy(IL.begin(), IL.end(), getPrivates().end());
561}
562
563void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
564  assert(UL.size() == varlist_size() &&
565         "Number of updates is not the same as the preallocated buffer");
566  std::copy(UL.begin(), UL.end(), getInits().end());
567}
568
569void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
570  assert(FL.size() == varlist_size() &&
571         "Number of final updates is not the same as the preallocated buffer");
572  std::copy(FL.begin(), FL.end(), getUpdates().end());
573}
574
575void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {
576  assert(
577      UE.size() == varlist_size() + 1 &&
578      "Number of used expressions is not the same as the preallocated buffer");
579  std::copy(UE.begin(), UE.end(), getFinals().end() + 2);
580}
581
582OMPLinearClause *OMPLinearClause::Create(
583    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
584    OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
585    SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
586    ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
587    Stmt *PreInit, Expr *PostUpdate) {
588  // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
589  // (Step and CalcStep), list of used expression + step.
590  void *Mem =
591      C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));
592  OMPLinearClause *Clause = new (Mem) OMPLinearClause(
593      StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
594  Clause->setVarRefs(VL);
595  Clause->setPrivates(PL);
596  Clause->setInits(IL);
597  // Fill update and final expressions with zeroes, they are provided later,
598  // after the directive construction.
599  std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
600            nullptr);
601  std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
602            nullptr);
603  std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),
604            nullptr);
605  Clause->setStep(Step);
606  Clause->setCalcStep(CalcStep);
607  Clause->setPreInitStmt(PreInit);
608  Clause->setPostUpdateExpr(PostUpdate);
609  return Clause;
610}
611
612OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
613                                              unsigned NumVars) {
614  // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
615  // (Step and CalcStep), list of used expression + step.
616  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2 + NumVars  +1));
617  return new (Mem) OMPLinearClause(NumVars);
618}
619
620OMPClause::child_range OMPLinearClause::used_children() {
621  // Range includes only non-nullptr elements.
622  return child_range(
623      reinterpret_cast<Stmt **>(getUsedExprs().begin()),
624      reinterpret_cast<Stmt **>(llvm::find(getUsedExprs(), nullptr)));
625}
626
627OMPAlignedClause *
628OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
629                         SourceLocation LParenLoc, SourceLocation ColonLoc,
630                         SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
631  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
632  OMPAlignedClause *Clause = new (Mem)
633      OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
634  Clause->setVarRefs(VL);
635  Clause->setAlignment(A);
636  return Clause;
637}
638
639OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
640                                                unsigned NumVars) {
641  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));
642  return new (Mem) OMPAlignedClause(NumVars);
643}
644
645OMPAlignClause *OMPAlignClause::Create(const ASTContext &C, Expr *A,
646                                       SourceLocation StartLoc,
647                                       SourceLocation LParenLoc,
648                                       SourceLocation EndLoc) {
649  return new (C) OMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
650}
651
652void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
653  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
654                                              "not the same as the "
655                                              "preallocated buffer");
656  std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
657}
658
659void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
660  assert(DstExprs.size() == varlist_size() && "Number of destination "
661                                              "expressions is not the same as "
662                                              "the preallocated buffer");
663  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
664}
665
666void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
667  assert(AssignmentOps.size() == varlist_size() &&
668         "Number of assignment expressions is not the same as the preallocated "
669         "buffer");
670  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
671            getDestinationExprs().end());
672}
673
674OMPCopyinClause *OMPCopyinClause::Create(
675    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
676    SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
677    ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
678  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
679  OMPCopyinClause *Clause =
680      new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
681  Clause->setVarRefs(VL);
682  Clause->setSourceExprs(SrcExprs);
683  Clause->setDestinationExprs(DstExprs);
684  Clause->setAssignmentOps(AssignmentOps);
685  return Clause;
686}
687
688OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
689  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
690  return new (Mem) OMPCopyinClause(N);
691}
692
693void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
694  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
695                                              "not the same as the "
696                                              "preallocated buffer");
697  std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
698}
699
700void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
701  assert(DstExprs.size() == varlist_size() && "Number of destination "
702                                              "expressions is not the same as "
703                                              "the preallocated buffer");
704  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
705}
706
707void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
708  assert(AssignmentOps.size() == varlist_size() &&
709         "Number of assignment expressions is not the same as the preallocated "
710         "buffer");
711  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
712            getDestinationExprs().end());
713}
714
715OMPCopyprivateClause *OMPCopyprivateClause::Create(
716    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
717    SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
718    ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
719  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
720  OMPCopyprivateClause *Clause =
721      new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
722  Clause->setVarRefs(VL);
723  Clause->setSourceExprs(SrcExprs);
724  Clause->setDestinationExprs(DstExprs);
725  Clause->setAssignmentOps(AssignmentOps);
726  return Clause;
727}
728
729OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
730                                                        unsigned N) {
731  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
732  return new (Mem) OMPCopyprivateClause(N);
733}
734
735void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
736  assert(Privates.size() == varlist_size() &&
737         "Number of private copies is not the same as the preallocated buffer");
738  std::copy(Privates.begin(), Privates.end(), varlist_end());
739}
740
741void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
742  assert(
743      LHSExprs.size() == varlist_size() &&
744      "Number of LHS expressions is not the same as the preallocated buffer");
745  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
746}
747
748void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
749  assert(
750      RHSExprs.size() == varlist_size() &&
751      "Number of RHS expressions is not the same as the preallocated buffer");
752  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
753}
754
755void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
756  assert(ReductionOps.size() == varlist_size() && "Number of reduction "
757                                                  "expressions is not the same "
758                                                  "as the preallocated buffer");
759  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
760}
761
762void OMPReductionClause::setInscanCopyOps(ArrayRef<Expr *> Ops) {
763  assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
764  assert(Ops.size() == varlist_size() && "Number of copy "
765                                         "expressions is not the same "
766                                         "as the preallocated buffer");
767  llvm::copy(Ops, getReductionOps().end());
768}
769
770void OMPReductionClause::setInscanCopyArrayTemps(
771    ArrayRef<Expr *> CopyArrayTemps) {
772  assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
773  assert(CopyArrayTemps.size() == varlist_size() &&
774         "Number of copy temp expressions is not the same as the preallocated "
775         "buffer");
776  llvm::copy(CopyArrayTemps, getInscanCopyOps().end());
777}
778
779void OMPReductionClause::setInscanCopyArrayElems(
780    ArrayRef<Expr *> CopyArrayElems) {
781  assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
782  assert(CopyArrayElems.size() == varlist_size() &&
783         "Number of copy temp expressions is not the same as the preallocated "
784         "buffer");
785  llvm::copy(CopyArrayElems, getInscanCopyArrayTemps().end());
786}
787
788OMPReductionClause *OMPReductionClause::Create(
789    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
790    SourceLocation ModifierLoc, SourceLocation EndLoc, SourceLocation ColonLoc,
791    OpenMPReductionClauseModifier Modifier, ArrayRef<Expr *> VL,
792    NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
793    ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
794    ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
795    ArrayRef<Expr *> CopyOps, ArrayRef<Expr *> CopyArrayTemps,
796    ArrayRef<Expr *> CopyArrayElems, Stmt *PreInit, Expr *PostUpdate) {
797  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(
798      (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size()));
799  auto *Clause = new (Mem)
800      OMPReductionClause(StartLoc, LParenLoc, ModifierLoc, EndLoc, ColonLoc,
801                         Modifier, VL.size(), QualifierLoc, NameInfo);
802  Clause->setVarRefs(VL);
803  Clause->setPrivates(Privates);
804  Clause->setLHSExprs(LHSExprs);
805  Clause->setRHSExprs(RHSExprs);
806  Clause->setReductionOps(ReductionOps);
807  Clause->setPreInitStmt(PreInit);
808  Clause->setPostUpdateExpr(PostUpdate);
809  if (Modifier == OMPC_REDUCTION_inscan) {
810    Clause->setInscanCopyOps(CopyOps);
811    Clause->setInscanCopyArrayTemps(CopyArrayTemps);
812    Clause->setInscanCopyArrayElems(CopyArrayElems);
813  } else {
814    assert(CopyOps.empty() &&
815           "copy operations are expected in inscan reductions only.");
816    assert(CopyArrayTemps.empty() &&
817           "copy array temps are expected in inscan reductions only.");
818    assert(CopyArrayElems.empty() &&
819           "copy array temps are expected in inscan reductions only.");
820  }
821  return Clause;
822}
823
824OMPReductionClause *
825OMPReductionClause::CreateEmpty(const ASTContext &C, unsigned N,
826                                OpenMPReductionClauseModifier Modifier) {
827  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(
828      (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N));
829  auto *Clause = new (Mem) OMPReductionClause(N);
830  Clause->setModifier(Modifier);
831  return Clause;
832}
833
834void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
835  assert(Privates.size() == varlist_size() &&
836         "Number of private copies is not the same as the preallocated buffer");
837  std::copy(Privates.begin(), Privates.end(), varlist_end());
838}
839
840void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
841  assert(
842      LHSExprs.size() == varlist_size() &&
843      "Number of LHS expressions is not the same as the preallocated buffer");
844  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
845}
846
847void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
848  assert(
849      RHSExprs.size() == varlist_size() &&
850      "Number of RHS expressions is not the same as the preallocated buffer");
851  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
852}
853
854void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
855  assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
856                                                  "expressions is not the same "
857                                                  "as the preallocated buffer");
858  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
859}
860
861OMPTaskReductionClause *OMPTaskReductionClause::Create(
862    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
863    SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
864    NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
865    ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
866    ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
867    Expr *PostUpdate) {
868  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
869  OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
870      StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
871  Clause->setVarRefs(VL);
872  Clause->setPrivates(Privates);
873  Clause->setLHSExprs(LHSExprs);
874  Clause->setRHSExprs(RHSExprs);
875  Clause->setReductionOps(ReductionOps);
876  Clause->setPreInitStmt(PreInit);
877  Clause->setPostUpdateExpr(PostUpdate);
878  return Clause;
879}
880
881OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
882                                                            unsigned N) {
883  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
884  return new (Mem) OMPTaskReductionClause(N);
885}
886
887void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
888  assert(Privates.size() == varlist_size() &&
889         "Number of private copies is not the same as the preallocated buffer");
890  std::copy(Privates.begin(), Privates.end(), varlist_end());
891}
892
893void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
894  assert(
895      LHSExprs.size() == varlist_size() &&
896      "Number of LHS expressions is not the same as the preallocated buffer");
897  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
898}
899
900void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
901  assert(
902      RHSExprs.size() == varlist_size() &&
903      "Number of RHS expressions is not the same as the preallocated buffer");
904  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
905}
906
907void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
908  assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
909                                                  "expressions is not the same "
910                                                  "as the preallocated buffer");
911  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
912}
913
914void OMPInReductionClause::setTaskgroupDescriptors(
915    ArrayRef<Expr *> TaskgroupDescriptors) {
916  assert(TaskgroupDescriptors.size() == varlist_size() &&
917         "Number of in reduction descriptors is not the same as the "
918         "preallocated buffer");
919  std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(),
920            getReductionOps().end());
921}
922
923OMPInReductionClause *OMPInReductionClause::Create(
924    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
925    SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
926    NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
927    ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
928    ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
929    ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
930  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));
931  OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
932      StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
933  Clause->setVarRefs(VL);
934  Clause->setPrivates(Privates);
935  Clause->setLHSExprs(LHSExprs);
936  Clause->setRHSExprs(RHSExprs);
937  Clause->setReductionOps(ReductionOps);
938  Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
939  Clause->setPreInitStmt(PreInit);
940  Clause->setPostUpdateExpr(PostUpdate);
941  return Clause;
942}
943
944OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
945                                                        unsigned N) {
946  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));
947  return new (Mem) OMPInReductionClause(N);
948}
949
950OMPSizesClause *OMPSizesClause::Create(const ASTContext &C,
951                                       SourceLocation StartLoc,
952                                       SourceLocation LParenLoc,
953                                       SourceLocation EndLoc,
954                                       ArrayRef<Expr *> Sizes) {
955  OMPSizesClause *Clause = CreateEmpty(C, Sizes.size());
956  Clause->setLocStart(StartLoc);
957  Clause->setLParenLoc(LParenLoc);
958  Clause->setLocEnd(EndLoc);
959  Clause->setSizesRefs(Sizes);
960  return Clause;
961}
962
963OMPSizesClause *OMPSizesClause::CreateEmpty(const ASTContext &C,
964                                            unsigned NumSizes) {
965  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumSizes));
966  return new (Mem) OMPSizesClause(NumSizes);
967}
968
969OMPFullClause *OMPFullClause::Create(const ASTContext &C,
970                                     SourceLocation StartLoc,
971                                     SourceLocation EndLoc) {
972  OMPFullClause *Clause = CreateEmpty(C);
973  Clause->setLocStart(StartLoc);
974  Clause->setLocEnd(EndLoc);
975  return Clause;
976}
977
978OMPFullClause *OMPFullClause::CreateEmpty(const ASTContext &C) {
979  return new (C) OMPFullClause();
980}
981
982OMPPartialClause *OMPPartialClause::Create(const ASTContext &C,
983                                           SourceLocation StartLoc,
984                                           SourceLocation LParenLoc,
985                                           SourceLocation EndLoc,
986                                           Expr *Factor) {
987  OMPPartialClause *Clause = CreateEmpty(C);
988  Clause->setLocStart(StartLoc);
989  Clause->setLParenLoc(LParenLoc);
990  Clause->setLocEnd(EndLoc);
991  Clause->setFactor(Factor);
992  return Clause;
993}
994
995OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
996  return new (C) OMPPartialClause();
997}
998
999OMPAllocateClause *
1000OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
1001                          SourceLocation LParenLoc, Expr *Allocator,
1002                          SourceLocation ColonLoc, SourceLocation EndLoc,
1003                          ArrayRef<Expr *> VL) {
1004  // Allocate space for private variables and initializer expressions.
1005  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1006  auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
1007                                             ColonLoc, EndLoc, VL.size());
1008  Clause->setVarRefs(VL);
1009  return Clause;
1010}
1011
1012OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,
1013                                                  unsigned N) {
1014  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1015  return new (Mem) OMPAllocateClause(N);
1016}
1017
1018OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
1019                                       SourceLocation StartLoc,
1020                                       SourceLocation LParenLoc,
1021                                       SourceLocation EndLoc,
1022                                       ArrayRef<Expr *> VL) {
1023  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
1024  OMPFlushClause *Clause =
1025      new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
1026  Clause->setVarRefs(VL);
1027  return Clause;
1028}
1029
1030OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
1031  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1032  return new (Mem) OMPFlushClause(N);
1033}
1034
1035OMPDepobjClause *OMPDepobjClause::Create(const ASTContext &C,
1036                                         SourceLocation StartLoc,
1037                                         SourceLocation LParenLoc,
1038                                         SourceLocation RParenLoc,
1039                                         Expr *Depobj) {
1040  auto *Clause = new (C) OMPDepobjClause(StartLoc, LParenLoc, RParenLoc);
1041  Clause->setDepobj(Depobj);
1042  return Clause;
1043}
1044
1045OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) {
1046  return new (C) OMPDepobjClause();
1047}
1048
1049OMPDependClause *
1050OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
1051                        SourceLocation LParenLoc, SourceLocation EndLoc,
1052                        DependDataTy Data, Expr *DepModifier,
1053                        ArrayRef<Expr *> VL, unsigned NumLoops) {
1054  void *Mem = C.Allocate(
1055      totalSizeToAlloc<Expr *>(VL.size() + /*depend-modifier*/ 1 + NumLoops),
1056      alignof(OMPDependClause));
1057  OMPDependClause *Clause = new (Mem)
1058      OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
1059  Clause->setDependencyKind(Data.DepKind);
1060  Clause->setDependencyLoc(Data.DepLoc);
1061  Clause->setColonLoc(Data.ColonLoc);
1062  Clause->setOmpAllMemoryLoc(Data.OmpAllMemoryLoc);
1063  Clause->setModifier(DepModifier);
1064  Clause->setVarRefs(VL);
1065  for (unsigned I = 0 ; I < NumLoops; ++I)
1066    Clause->setLoopData(I, nullptr);
1067  return Clause;
1068}
1069
1070OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,
1071                                              unsigned NumLoops) {
1072  void *Mem =
1073      C.Allocate(totalSizeToAlloc<Expr *>(N + /*depend-modifier*/ 1 + NumLoops),
1074                 alignof(OMPDependClause));
1075  return new (Mem) OMPDependClause(N, NumLoops);
1076}
1077
1078void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
1079  assert((getDependencyKind() == OMPC_DEPEND_sink ||
1080          getDependencyKind() == OMPC_DEPEND_source) &&
1081         NumLoop < NumLoops &&
1082         "Expected sink or source depend + loop index must be less number of "
1083         "loops.");
1084  auto *It = std::next(getVarRefs().end(), NumLoop + 1);
1085  *It = Cnt;
1086}
1087
1088Expr *OMPDependClause::getLoopData(unsigned NumLoop) {
1089  assert((getDependencyKind() == OMPC_DEPEND_sink ||
1090          getDependencyKind() == OMPC_DEPEND_source) &&
1091         NumLoop < NumLoops &&
1092         "Expected sink or source depend + loop index must be less number of "
1093         "loops.");
1094  auto *It = std::next(getVarRefs().end(), NumLoop + 1);
1095  return *It;
1096}
1097
1098const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {
1099  assert((getDependencyKind() == OMPC_DEPEND_sink ||
1100          getDependencyKind() == OMPC_DEPEND_source) &&
1101         NumLoop < NumLoops &&
1102         "Expected sink or source depend + loop index must be less number of "
1103         "loops.");
1104  const auto *It = std::next(getVarRefs().end(), NumLoop + 1);
1105  return *It;
1106}
1107
1108void OMPDependClause::setModifier(Expr *DepModifier) {
1109  *getVarRefs().end() = DepModifier;
1110}
1111Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); }
1112
1113unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
1114    MappableExprComponentListsRef ComponentLists) {
1115  unsigned TotalNum = 0u;
1116  for (auto &C : ComponentLists)
1117    TotalNum += C.size();
1118  return TotalNum;
1119}
1120
1121unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
1122    ArrayRef<const ValueDecl *> Declarations) {
1123  unsigned TotalNum = 0u;
1124  llvm::SmallPtrSet<const ValueDecl *, 8> Cache;
1125  for (const ValueDecl *D : Declarations) {
1126    const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
1127    if (Cache.count(VD))
1128      continue;
1129    ++TotalNum;
1130    Cache.insert(VD);
1131  }
1132  return TotalNum;
1133}
1134
1135OMPMapClause *OMPMapClause::Create(
1136    const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1137    ArrayRef<ValueDecl *> Declarations,
1138    MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1139    Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapModifiers,
1140    ArrayRef<SourceLocation> MapModifiersLoc,
1141    NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
1142    OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
1143  OMPMappableExprListSizeTy Sizes;
1144  Sizes.NumVars = Vars.size();
1145  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1146  Sizes.NumComponentLists = ComponentLists.size();
1147  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1148
1149  // We need to allocate:
1150  // 2 x NumVars x Expr* - we have an original list expression and an associated
1151  // user-defined mapper for each clause list entry.
1152  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1153  // with each component list.
1154  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1155  // number of lists for each unique declaration and the size of each component
1156  // list.
1157  // NumComponents x MappableComponent - the total of all the components in all
1158  // the lists.
1159  void *Mem = C.Allocate(
1160      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1161                       OMPClauseMappableExprCommon::MappableComponent>(
1162          2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1163          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1164          Sizes.NumComponents));
1165  OMPMapClause *Clause = new (Mem)
1166      OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
1167                   Type, TypeIsImplicit, TypeLoc, Locs, Sizes);
1168
1169  Clause->setVarRefs(Vars);
1170  Clause->setUDMapperRefs(UDMapperRefs);
1171  Clause->setIteratorModifier(IteratorModifier);
1172  Clause->setClauseInfo(Declarations, ComponentLists);
1173  Clause->setMapType(Type);
1174  Clause->setMapLoc(TypeLoc);
1175  return Clause;
1176}
1177
1178OMPMapClause *
1179OMPMapClause::CreateEmpty(const ASTContext &C,
1180                          const OMPMappableExprListSizeTy &Sizes) {
1181  void *Mem = C.Allocate(
1182      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1183                       OMPClauseMappableExprCommon::MappableComponent>(
1184          2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
1185          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1186          Sizes.NumComponents));
1187  OMPMapClause *Clause = new (Mem) OMPMapClause(Sizes);
1188  Clause->setIteratorModifier(nullptr);
1189  return Clause;
1190}
1191
1192OMPToClause *OMPToClause::Create(
1193    const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1194    ArrayRef<ValueDecl *> Declarations,
1195    MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1196    ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
1197    ArrayRef<SourceLocation> MotionModifiersLoc,
1198    NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1199  OMPMappableExprListSizeTy Sizes;
1200  Sizes.NumVars = Vars.size();
1201  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1202  Sizes.NumComponentLists = ComponentLists.size();
1203  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1204
1205  // We need to allocate:
1206  // 2 x NumVars x Expr* - we have an original list expression and an associated
1207  // user-defined mapper for each clause list entry.
1208  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1209  // with each component list.
1210  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1211  // number of lists for each unique declaration and the size of each component
1212  // list.
1213  // NumComponents x MappableComponent - the total of all the components in all
1214  // the lists.
1215  void *Mem = C.Allocate(
1216      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1217                       OMPClauseMappableExprCommon::MappableComponent>(
1218          2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1219          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1220          Sizes.NumComponents));
1221
1222  auto *Clause = new (Mem) OMPToClause(MotionModifiers, MotionModifiersLoc,
1223                                       UDMQualifierLoc, MapperId, Locs, Sizes);
1224
1225  Clause->setVarRefs(Vars);
1226  Clause->setUDMapperRefs(UDMapperRefs);
1227  Clause->setClauseInfo(Declarations, ComponentLists);
1228  return Clause;
1229}
1230
1231OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C,
1232                                      const OMPMappableExprListSizeTy &Sizes) {
1233  void *Mem = C.Allocate(
1234      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1235                       OMPClauseMappableExprCommon::MappableComponent>(
1236          2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1237          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1238          Sizes.NumComponents));
1239  return new (Mem) OMPToClause(Sizes);
1240}
1241
1242OMPFromClause *OMPFromClause::Create(
1243    const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1244    ArrayRef<ValueDecl *> Declarations,
1245    MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1246    ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
1247    ArrayRef<SourceLocation> MotionModifiersLoc,
1248    NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1249  OMPMappableExprListSizeTy Sizes;
1250  Sizes.NumVars = Vars.size();
1251  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1252  Sizes.NumComponentLists = ComponentLists.size();
1253  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1254
1255  // We need to allocate:
1256  // 2 x NumVars x Expr* - we have an original list expression and an associated
1257  // user-defined mapper for each clause list entry.
1258  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1259  // with each component list.
1260  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1261  // number of lists for each unique declaration and the size of each component
1262  // list.
1263  // NumComponents x MappableComponent - the total of all the components in all
1264  // the lists.
1265  void *Mem = C.Allocate(
1266      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1267                       OMPClauseMappableExprCommon::MappableComponent>(
1268          2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1269          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1270          Sizes.NumComponents));
1271
1272  auto *Clause =
1273      new (Mem) OMPFromClause(MotionModifiers, MotionModifiersLoc,
1274                              UDMQualifierLoc, MapperId, Locs, Sizes);
1275
1276  Clause->setVarRefs(Vars);
1277  Clause->setUDMapperRefs(UDMapperRefs);
1278  Clause->setClauseInfo(Declarations, ComponentLists);
1279  return Clause;
1280}
1281
1282OMPFromClause *
1283OMPFromClause::CreateEmpty(const ASTContext &C,
1284                           const OMPMappableExprListSizeTy &Sizes) {
1285  void *Mem = C.Allocate(
1286      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1287                       OMPClauseMappableExprCommon::MappableComponent>(
1288          2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1289          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1290          Sizes.NumComponents));
1291  return new (Mem) OMPFromClause(Sizes);
1292}
1293
1294void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
1295  assert(VL.size() == varlist_size() &&
1296         "Number of private copies is not the same as the preallocated buffer");
1297  std::copy(VL.begin(), VL.end(), varlist_end());
1298}
1299
1300void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
1301  assert(VL.size() == varlist_size() &&
1302         "Number of inits is not the same as the preallocated buffer");
1303  std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
1304}
1305
1306OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
1307    const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1308    ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
1309    ArrayRef<ValueDecl *> Declarations,
1310    MappableExprComponentListsRef ComponentLists) {
1311  OMPMappableExprListSizeTy Sizes;
1312  Sizes.NumVars = Vars.size();
1313  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1314  Sizes.NumComponentLists = ComponentLists.size();
1315  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1316
1317  // We need to allocate:
1318  // NumVars x Expr* - we have an original list expression for each clause
1319  // list entry.
1320  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1321  // with each component list.
1322  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1323  // number of lists for each unique declaration and the size of each component
1324  // list.
1325  // NumComponents x MappableComponent - the total of all the components in all
1326  // the lists.
1327  void *Mem = C.Allocate(
1328      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1329                       OMPClauseMappableExprCommon::MappableComponent>(
1330          3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1331          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1332          Sizes.NumComponents));
1333
1334  OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
1335
1336  Clause->setVarRefs(Vars);
1337  Clause->setPrivateCopies(PrivateVars);
1338  Clause->setInits(Inits);
1339  Clause->setClauseInfo(Declarations, ComponentLists);
1340  return Clause;
1341}
1342
1343OMPUseDevicePtrClause *
1344OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C,
1345                                   const OMPMappableExprListSizeTy &Sizes) {
1346  void *Mem = C.Allocate(
1347      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1348                       OMPClauseMappableExprCommon::MappableComponent>(
1349          3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1350          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1351          Sizes.NumComponents));
1352  return new (Mem) OMPUseDevicePtrClause(Sizes);
1353}
1354
1355OMPUseDeviceAddrClause *
1356OMPUseDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1357                               ArrayRef<Expr *> Vars,
1358                               ArrayRef<ValueDecl *> Declarations,
1359                               MappableExprComponentListsRef ComponentLists) {
1360  OMPMappableExprListSizeTy Sizes;
1361  Sizes.NumVars = Vars.size();
1362  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1363  Sizes.NumComponentLists = ComponentLists.size();
1364  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1365
1366  // We need to allocate:
1367  // 3 x NumVars x Expr* - we have an original list expression for each clause
1368  // list entry and an equal number of private copies and inits.
1369  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1370  // with each component list.
1371  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1372  // number of lists for each unique declaration and the size of each component
1373  // list.
1374  // NumComponents x MappableComponent - the total of all the components in all
1375  // the lists.
1376  void *Mem = C.Allocate(
1377      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1378                       OMPClauseMappableExprCommon::MappableComponent>(
1379          Sizes.NumVars, Sizes.NumUniqueDeclarations,
1380          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1381          Sizes.NumComponents));
1382
1383  auto *Clause = new (Mem) OMPUseDeviceAddrClause(Locs, Sizes);
1384
1385  Clause->setVarRefs(Vars);
1386  Clause->setClauseInfo(Declarations, ComponentLists);
1387  return Clause;
1388}
1389
1390OMPUseDeviceAddrClause *
1391OMPUseDeviceAddrClause::CreateEmpty(const ASTContext &C,
1392                                    const OMPMappableExprListSizeTy &Sizes) {
1393  void *Mem = C.Allocate(
1394      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1395                       OMPClauseMappableExprCommon::MappableComponent>(
1396          Sizes.NumVars, Sizes.NumUniqueDeclarations,
1397          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1398          Sizes.NumComponents));
1399  return new (Mem) OMPUseDeviceAddrClause(Sizes);
1400}
1401
1402OMPIsDevicePtrClause *
1403OMPIsDevicePtrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1404                             ArrayRef<Expr *> Vars,
1405                             ArrayRef<ValueDecl *> Declarations,
1406                             MappableExprComponentListsRef ComponentLists) {
1407  OMPMappableExprListSizeTy Sizes;
1408  Sizes.NumVars = Vars.size();
1409  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1410  Sizes.NumComponentLists = ComponentLists.size();
1411  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1412
1413  // We need to allocate:
1414  // NumVars x Expr* - we have an original list expression for each clause list
1415  // entry.
1416  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1417  // with each component list.
1418  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1419  // number of lists for each unique declaration and the size of each component
1420  // list.
1421  // NumComponents x MappableComponent - the total of all the components in all
1422  // the lists.
1423  void *Mem = C.Allocate(
1424      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1425                       OMPClauseMappableExprCommon::MappableComponent>(
1426          Sizes.NumVars, Sizes.NumUniqueDeclarations,
1427          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1428          Sizes.NumComponents));
1429
1430  OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);
1431
1432  Clause->setVarRefs(Vars);
1433  Clause->setClauseInfo(Declarations, ComponentLists);
1434  return Clause;
1435}
1436
1437OMPIsDevicePtrClause *
1438OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,
1439                                  const OMPMappableExprListSizeTy &Sizes) {
1440  void *Mem = C.Allocate(
1441      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1442                       OMPClauseMappableExprCommon::MappableComponent>(
1443          Sizes.NumVars, Sizes.NumUniqueDeclarations,
1444          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1445          Sizes.NumComponents));
1446  return new (Mem) OMPIsDevicePtrClause(Sizes);
1447}
1448
1449OMPHasDeviceAddrClause *
1450OMPHasDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
1451                               ArrayRef<Expr *> Vars,
1452                               ArrayRef<ValueDecl *> Declarations,
1453                               MappableExprComponentListsRef ComponentLists) {
1454  OMPMappableExprListSizeTy Sizes;
1455  Sizes.NumVars = Vars.size();
1456  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1457  Sizes.NumComponentLists = ComponentLists.size();
1458  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1459
1460  // We need to allocate:
1461  // NumVars x Expr* - we have an original list expression for each clause list
1462  // entry.
1463  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1464  // with each component list.
1465  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1466  // number of lists for each unique declaration and the size of each component
1467  // list.
1468  // NumComponents x MappableComponent - the total of all the components in all
1469  // the lists.
1470  void *Mem = C.Allocate(
1471      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1472                       OMPClauseMappableExprCommon::MappableComponent>(
1473          Sizes.NumVars, Sizes.NumUniqueDeclarations,
1474          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1475          Sizes.NumComponents));
1476
1477  auto *Clause = new (Mem) OMPHasDeviceAddrClause(Locs, Sizes);
1478
1479  Clause->setVarRefs(Vars);
1480  Clause->setClauseInfo(Declarations, ComponentLists);
1481  return Clause;
1482}
1483
1484OMPHasDeviceAddrClause *
1485OMPHasDeviceAddrClause::CreateEmpty(const ASTContext &C,
1486                                    const OMPMappableExprListSizeTy &Sizes) {
1487  void *Mem = C.Allocate(
1488      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1489                       OMPClauseMappableExprCommon::MappableComponent>(
1490          Sizes.NumVars, Sizes.NumUniqueDeclarations,
1491          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
1492          Sizes.NumComponents));
1493  return new (Mem) OMPHasDeviceAddrClause(Sizes);
1494}
1495
1496OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
1497                                                   SourceLocation StartLoc,
1498                                                   SourceLocation LParenLoc,
1499                                                   SourceLocation EndLoc,
1500                                                   ArrayRef<Expr *> VL) {
1501  // Allocate space for nontemporal variables + private references.
1502  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
1503  auto *Clause =
1504      new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
1505  Clause->setVarRefs(VL);
1506  return Clause;
1507}
1508
1509OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,
1510                                                        unsigned N) {
1511  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
1512  return new (Mem) OMPNontemporalClause(N);
1513}
1514
1515void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {
1516  assert(VL.size() == varlist_size() && "Number of private references is not "
1517                                        "the same as the preallocated buffer");
1518  std::copy(VL.begin(), VL.end(), varlist_end());
1519}
1520
1521OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C,
1522                                               SourceLocation StartLoc,
1523                                               SourceLocation LParenLoc,
1524                                               SourceLocation EndLoc,
1525                                               ArrayRef<Expr *> VL) {
1526  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1527  auto *Clause =
1528      new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1529  Clause->setVarRefs(VL);
1530  return Clause;
1531}
1532
1533OMPInclusiveClause *OMPInclusiveClause::CreateEmpty(const ASTContext &C,
1534                                                    unsigned N) {
1535  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1536  return new (Mem) OMPInclusiveClause(N);
1537}
1538
1539OMPExclusiveClause *OMPExclusiveClause::Create(const ASTContext &C,
1540                                               SourceLocation StartLoc,
1541                                               SourceLocation LParenLoc,
1542                                               SourceLocation EndLoc,
1543                                               ArrayRef<Expr *> VL) {
1544  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
1545  auto *Clause =
1546      new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
1547  Clause->setVarRefs(VL);
1548  return Clause;
1549}
1550
1551OMPExclusiveClause *OMPExclusiveClause::CreateEmpty(const ASTContext &C,
1552                                                    unsigned N) {
1553  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1554  return new (Mem) OMPExclusiveClause(N);
1555}
1556
1557void OMPUsesAllocatorsClause::setAllocatorsData(
1558    ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
1559  assert(Data.size() == NumOfAllocators &&
1560         "Size of allocators data is not the same as the preallocated buffer.");
1561  for (unsigned I = 0, E = Data.size(); I < E; ++I) {
1562    const OMPUsesAllocatorsClause::Data &D = Data[I];
1563    getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1564                                 static_cast<int>(ExprOffsets::Allocator)] =
1565        D.Allocator;
1566    getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1567                                 static_cast<int>(
1568                                     ExprOffsets::AllocatorTraits)] =
1569        D.AllocatorTraits;
1570    getTrailingObjects<
1571        SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1572                          static_cast<int>(ParenLocsOffsets::LParen)] =
1573        D.LParenLoc;
1574    getTrailingObjects<
1575        SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1576                          static_cast<int>(ParenLocsOffsets::RParen)] =
1577        D.RParenLoc;
1578  }
1579}
1580
1581OMPUsesAllocatorsClause::Data
1582OMPUsesAllocatorsClause::getAllocatorData(unsigned I) const {
1583  OMPUsesAllocatorsClause::Data Data;
1584  Data.Allocator =
1585      getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1586                                   static_cast<int>(ExprOffsets::Allocator)];
1587  Data.AllocatorTraits =
1588      getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
1589                                   static_cast<int>(
1590                                       ExprOffsets::AllocatorTraits)];
1591  Data.LParenLoc = getTrailingObjects<
1592      SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1593                        static_cast<int>(ParenLocsOffsets::LParen)];
1594  Data.RParenLoc = getTrailingObjects<
1595      SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
1596                        static_cast<int>(ParenLocsOffsets::RParen)];
1597  return Data;
1598}
1599
1600OMPUsesAllocatorsClause *
1601OMPUsesAllocatorsClause::Create(const ASTContext &C, SourceLocation StartLoc,
1602                                SourceLocation LParenLoc, SourceLocation EndLoc,
1603                                ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
1604  void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
1605      static_cast<int>(ExprOffsets::Total) * Data.size(),
1606      static_cast<int>(ParenLocsOffsets::Total) * Data.size()));
1607  auto *Clause = new (Mem)
1608      OMPUsesAllocatorsClause(StartLoc, LParenLoc, EndLoc, Data.size());
1609  Clause->setAllocatorsData(Data);
1610  return Clause;
1611}
1612
1613OMPUsesAllocatorsClause *
1614OMPUsesAllocatorsClause::CreateEmpty(const ASTContext &C, unsigned N) {
1615  void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
1616      static_cast<int>(ExprOffsets::Total) * N,
1617      static_cast<int>(ParenLocsOffsets::Total) * N));
1618  return new (Mem) OMPUsesAllocatorsClause(N);
1619}
1620
1621OMPAffinityClause *
1622OMPAffinityClause::Create(const ASTContext &C, SourceLocation StartLoc,
1623                          SourceLocation LParenLoc, SourceLocation ColonLoc,
1624                          SourceLocation EndLoc, Expr *Modifier,
1625                          ArrayRef<Expr *> Locators) {
1626  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Locators.size() + 1));
1627  auto *Clause = new (Mem)
1628      OMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, Locators.size());
1629  Clause->setModifier(Modifier);
1630  Clause->setVarRefs(Locators);
1631  return Clause;
1632}
1633
1634OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C,
1635                                                  unsigned N) {
1636  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1));
1637  return new (Mem) OMPAffinityClause(N);
1638}
1639
1640OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar,
1641                                     OMPInteropInfo &InteropInfo,
1642                                     SourceLocation StartLoc,
1643                                     SourceLocation LParenLoc,
1644                                     SourceLocation VarLoc,
1645                                     SourceLocation EndLoc) {
1646
1647  void *Mem =
1648      C.Allocate(totalSizeToAlloc<Expr *>(InteropInfo.PreferTypes.size() + 1));
1649  auto *Clause = new (Mem) OMPInitClause(
1650      InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc, LParenLoc,
1651      VarLoc, EndLoc, InteropInfo.PreferTypes.size() + 1);
1652  Clause->setInteropVar(InteropVar);
1653  llvm::copy(InteropInfo.PreferTypes, Clause->getTrailingObjects<Expr *>() + 1);
1654  return Clause;
1655}
1656
1657OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {
1658  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
1659  return new (Mem) OMPInitClause(N);
1660}
1661
1662OMPBindClause *
1663OMPBindClause::Create(const ASTContext &C, OpenMPBindClauseKind K,
1664                      SourceLocation KLoc, SourceLocation StartLoc,
1665                      SourceLocation LParenLoc, SourceLocation EndLoc) {
1666  return new (C) OMPBindClause(K, KLoc, StartLoc, LParenLoc, EndLoc);
1667}
1668
1669OMPBindClause *OMPBindClause::CreateEmpty(const ASTContext &C) {
1670  return new (C) OMPBindClause();
1671}
1672//===----------------------------------------------------------------------===//
1673//  OpenMP clauses printing methods
1674//===----------------------------------------------------------------------===//
1675
1676void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
1677  OS << "if(";
1678  if (Node->getNameModifier() != OMPD_unknown)
1679    OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
1680  Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1681  OS << ")";
1682}
1683
1684void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
1685  OS << "final(";
1686  Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1687  OS << ")";
1688}
1689
1690void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
1691  OS << "num_threads(";
1692  Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
1693  OS << ")";
1694}
1695
1696void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
1697  OS << "align(";
1698  Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
1699  OS << ")";
1700}
1701
1702void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
1703  OS << "safelen(";
1704  Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
1705  OS << ")";
1706}
1707
1708void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
1709  OS << "simdlen(";
1710  Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);
1711  OS << ")";
1712}
1713
1714void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {
1715  OS << "sizes(";
1716  bool First = true;
1717  for (auto *Size : Node->getSizesRefs()) {
1718    if (!First)
1719      OS << ", ";
1720    Size->printPretty(OS, nullptr, Policy, 0);
1721    First = false;
1722  }
1723  OS << ")";
1724}
1725
1726void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }
1727
1728void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
1729  OS << "partial";
1730
1731  if (Expr *Factor = Node->getFactor()) {
1732    OS << '(';
1733    Factor->printPretty(OS, nullptr, Policy, 0);
1734    OS << ')';
1735  }
1736}
1737
1738void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
1739  OS << "allocator(";
1740  Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
1741  OS << ")";
1742}
1743
1744void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
1745  OS << "collapse(";
1746  Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
1747  OS << ")";
1748}
1749
1750void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
1751  OS << "detach(";
1752  Node->getEventHandler()->printPretty(OS, nullptr, Policy, 0);
1753  OS << ")";
1754}
1755
1756void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
1757  OS << "default("
1758     << getOpenMPSimpleClauseTypeName(OMPC_default,
1759                                      unsigned(Node->getDefaultKind()))
1760     << ")";
1761}
1762
1763void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
1764  OS << "proc_bind("
1765     << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
1766                                      unsigned(Node->getProcBindKind()))
1767     << ")";
1768}
1769
1770void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
1771  OS << "unified_address";
1772}
1773
1774void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
1775    OMPUnifiedSharedMemoryClause *) {
1776  OS << "unified_shared_memory";
1777}
1778
1779void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
1780  OS << "reverse_offload";
1781}
1782
1783void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
1784    OMPDynamicAllocatorsClause *) {
1785  OS << "dynamic_allocators";
1786}
1787
1788void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
1789    OMPAtomicDefaultMemOrderClause *Node) {
1790  OS << "atomic_default_mem_order("
1791     << getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order,
1792                                      Node->getAtomicDefaultMemOrderKind())
1793     << ")";
1794}
1795
1796void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
1797  OS << "at(" << getOpenMPSimpleClauseTypeName(OMPC_at, Node->getAtKind())
1798     << ")";
1799}
1800
1801void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
1802  OS << "severity("
1803     << getOpenMPSimpleClauseTypeName(OMPC_severity, Node->getSeverityKind())
1804     << ")";
1805}
1806
1807void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
1808  OS << "message(\""
1809     << cast<StringLiteral>(Node->getMessageString())->getString() << "\")";
1810}
1811
1812void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
1813  OS << "schedule(";
1814  if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1815    OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
1816                                        Node->getFirstScheduleModifier());
1817    if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1818      OS << ", ";
1819      OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
1820                                          Node->getSecondScheduleModifier());
1821    }
1822    OS << ": ";
1823  }
1824  OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
1825  if (auto *E = Node->getChunkSize()) {
1826    OS << ", ";
1827    E->printPretty(OS, nullptr, Policy);
1828  }
1829  OS << ")";
1830}
1831
1832void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
1833  OS << "ordered";
1834  if (auto *Num = Node->getNumForLoops()) {
1835    OS << "(";
1836    Num->printPretty(OS, nullptr, Policy, 0);
1837    OS << ")";
1838  }
1839}
1840
1841void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
1842  OS << "nowait";
1843}
1844
1845void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
1846  OS << "untied";
1847}
1848
1849void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
1850  OS << "nogroup";
1851}
1852
1853void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
1854  OS << "mergeable";
1855}
1856
1857void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
1858
1859void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
1860
1861void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
1862  OS << "update";
1863  if (Node->isExtended()) {
1864    OS << "(";
1865    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
1866                                        Node->getDependencyKind());
1867    OS << ")";
1868  }
1869}
1870
1871void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
1872  OS << "capture";
1873}
1874
1875void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
1876  OS << "compare";
1877}
1878
1879void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
1880  OS << "seq_cst";
1881}
1882
1883void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
1884  OS << "acq_rel";
1885}
1886
1887void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
1888  OS << "acquire";
1889}
1890
1891void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
1892  OS << "release";
1893}
1894
1895void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
1896  OS << "relaxed";
1897}
1898
1899void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
1900  OS << "threads";
1901}
1902
1903void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
1904
1905void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
1906  OS << "device(";
1907  OpenMPDeviceClauseModifier Modifier = Node->getModifier();
1908  if (Modifier != OMPC_DEVICE_unknown) {
1909    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
1910       << ": ";
1911  }
1912  Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
1913  OS << ")";
1914}
1915
1916void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
1917  OS << "num_teams(";
1918  Node->getNumTeams()->printPretty(OS, nullptr, Policy, 0);
1919  OS << ")";
1920}
1921
1922void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
1923  OS << "thread_limit(";
1924  Node->getThreadLimit()->printPretty(OS, nullptr, Policy, 0);
1925  OS << ")";
1926}
1927
1928void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
1929  OS << "priority(";
1930  Node->getPriority()->printPretty(OS, nullptr, Policy, 0);
1931  OS << ")";
1932}
1933
1934void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
1935  OS << "grainsize(";
1936  OpenMPGrainsizeClauseModifier Modifier = Node->getModifier();
1937  if (Modifier != OMPC_GRAINSIZE_unknown) {
1938    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
1939       << ": ";
1940  }
1941  Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);
1942  OS << ")";
1943}
1944
1945void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
1946  OS << "num_tasks(";
1947  OpenMPNumTasksClauseModifier Modifier = Node->getModifier();
1948  if (Modifier != OMPC_NUMTASKS_unknown) {
1949    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
1950       << ": ";
1951  }
1952  Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
1953  OS << ")";
1954}
1955
1956void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
1957  OS << "hint(";
1958  Node->getHint()->printPretty(OS, nullptr, Policy, 0);
1959  OS << ")";
1960}
1961
1962void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
1963  OS << "init(";
1964  bool First = true;
1965  for (const Expr *E : Node->prefs()) {
1966    if (First)
1967      OS << "prefer_type(";
1968    else
1969      OS << ",";
1970    E->printPretty(OS, nullptr, Policy);
1971    First = false;
1972  }
1973  if (!First)
1974    OS << "), ";
1975  if (Node->getIsTarget())
1976    OS << "target";
1977  if (Node->getIsTargetSync()) {
1978    if (Node->getIsTarget())
1979      OS << ", ";
1980    OS << "targetsync";
1981  }
1982  OS << " : ";
1983  Node->getInteropVar()->printPretty(OS, nullptr, Policy);
1984  OS << ")";
1985}
1986
1987void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
1988  OS << "use(";
1989  Node->getInteropVar()->printPretty(OS, nullptr, Policy);
1990  OS << ")";
1991}
1992
1993void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {
1994  OS << "destroy";
1995  if (Expr *E = Node->getInteropVar()) {
1996    OS << "(";
1997    E->printPretty(OS, nullptr, Policy);
1998    OS << ")";
1999  }
2000}
2001
2002void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {
2003  OS << "novariants";
2004  if (Expr *E = Node->getCondition()) {
2005    OS << "(";
2006    E->printPretty(OS, nullptr, Policy, 0);
2007    OS << ")";
2008  }
2009}
2010
2011void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {
2012  OS << "nocontext";
2013  if (Expr *E = Node->getCondition()) {
2014    OS << "(";
2015    E->printPretty(OS, nullptr, Policy, 0);
2016    OS << ")";
2017  }
2018}
2019
2020template<typename T>
2021void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
2022  for (typename T::varlist_iterator I = Node->varlist_begin(),
2023                                    E = Node->varlist_end();
2024       I != E; ++I) {
2025    assert(*I && "Expected non-null Stmt");
2026    OS << (I == Node->varlist_begin() ? StartSym : ',');
2027    if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
2028      if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
2029        DRE->printPretty(OS, nullptr, Policy, 0);
2030      else
2031        DRE->getDecl()->printQualifiedName(OS);
2032    } else
2033      (*I)->printPretty(OS, nullptr, Policy, 0);
2034  }
2035}
2036
2037void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
2038  if (Node->varlist_empty())
2039    return;
2040  OS << "allocate";
2041  if (Expr *Allocator = Node->getAllocator()) {
2042    OS << "(";
2043    Allocator->printPretty(OS, nullptr, Policy, 0);
2044    OS << ":";
2045    VisitOMPClauseList(Node, ' ');
2046  } else {
2047    VisitOMPClauseList(Node, '(');
2048  }
2049  OS << ")";
2050}
2051
2052void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
2053  if (!Node->varlist_empty()) {
2054    OS << "private";
2055    VisitOMPClauseList(Node, '(');
2056    OS << ")";
2057  }
2058}
2059
2060void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
2061  if (!Node->varlist_empty()) {
2062    OS << "firstprivate";
2063    VisitOMPClauseList(Node, '(');
2064    OS << ")";
2065  }
2066}
2067
2068void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
2069  if (!Node->varlist_empty()) {
2070    OS << "lastprivate";
2071    OpenMPLastprivateModifier LPKind = Node->getKind();
2072    if (LPKind != OMPC_LASTPRIVATE_unknown) {
2073      OS << "("
2074         << getOpenMPSimpleClauseTypeName(OMPC_lastprivate, Node->getKind())
2075         << ":";
2076    }
2077    VisitOMPClauseList(Node, LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
2078    OS << ")";
2079  }
2080}
2081
2082void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
2083  if (!Node->varlist_empty()) {
2084    OS << "shared";
2085    VisitOMPClauseList(Node, '(');
2086    OS << ")";
2087  }
2088}
2089
2090void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
2091  if (!Node->varlist_empty()) {
2092    OS << "reduction(";
2093    if (Node->getModifierLoc().isValid())
2094      OS << getOpenMPSimpleClauseTypeName(OMPC_reduction, Node->getModifier())
2095         << ", ";
2096    NestedNameSpecifier *QualifierLoc =
2097        Node->getQualifierLoc().getNestedNameSpecifier();
2098    OverloadedOperatorKind OOK =
2099        Node->getNameInfo().getName().getCXXOverloadedOperator();
2100    if (QualifierLoc == nullptr && OOK != OO_None) {
2101      // Print reduction identifier in C format
2102      OS << getOperatorSpelling(OOK);
2103    } else {
2104      // Use C++ format
2105      if (QualifierLoc != nullptr)
2106        QualifierLoc->print(OS, Policy);
2107      OS << Node->getNameInfo();
2108    }
2109    OS << ":";
2110    VisitOMPClauseList(Node, ' ');
2111    OS << ")";
2112  }
2113}
2114
2115void OMPClausePrinter::VisitOMPTaskReductionClause(
2116    OMPTaskReductionClause *Node) {
2117  if (!Node->varlist_empty()) {
2118    OS << "task_reduction(";
2119    NestedNameSpecifier *QualifierLoc =
2120        Node->getQualifierLoc().getNestedNameSpecifier();
2121    OverloadedOperatorKind OOK =
2122        Node->getNameInfo().getName().getCXXOverloadedOperator();
2123    if (QualifierLoc == nullptr && OOK != OO_None) {
2124      // Print reduction identifier in C format
2125      OS << getOperatorSpelling(OOK);
2126    } else {
2127      // Use C++ format
2128      if (QualifierLoc != nullptr)
2129        QualifierLoc->print(OS, Policy);
2130      OS << Node->getNameInfo();
2131    }
2132    OS << ":";
2133    VisitOMPClauseList(Node, ' ');
2134    OS << ")";
2135  }
2136}
2137
2138void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
2139  if (!Node->varlist_empty()) {
2140    OS << "in_reduction(";
2141    NestedNameSpecifier *QualifierLoc =
2142        Node->getQualifierLoc().getNestedNameSpecifier();
2143    OverloadedOperatorKind OOK =
2144        Node->getNameInfo().getName().getCXXOverloadedOperator();
2145    if (QualifierLoc == nullptr && OOK != OO_None) {
2146      // Print reduction identifier in C format
2147      OS << getOperatorSpelling(OOK);
2148    } else {
2149      // Use C++ format
2150      if (QualifierLoc != nullptr)
2151        QualifierLoc->print(OS, Policy);
2152      OS << Node->getNameInfo();
2153    }
2154    OS << ":";
2155    VisitOMPClauseList(Node, ' ');
2156    OS << ")";
2157  }
2158}
2159
2160void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
2161  if (!Node->varlist_empty()) {
2162    OS << "linear";
2163    if (Node->getModifierLoc().isValid()) {
2164      OS << '('
2165         << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
2166    }
2167    VisitOMPClauseList(Node, '(');
2168    if (Node->getModifierLoc().isValid())
2169      OS << ')';
2170    if (Node->getStep() != nullptr) {
2171      OS << ": ";
2172      Node->getStep()->printPretty(OS, nullptr, Policy, 0);
2173    }
2174    OS << ")";
2175  }
2176}
2177
2178void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
2179  if (!Node->varlist_empty()) {
2180    OS << "aligned";
2181    VisitOMPClauseList(Node, '(');
2182    if (Node->getAlignment() != nullptr) {
2183      OS << ": ";
2184      Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
2185    }
2186    OS << ")";
2187  }
2188}
2189
2190void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
2191  if (!Node->varlist_empty()) {
2192    OS << "copyin";
2193    VisitOMPClauseList(Node, '(');
2194    OS << ")";
2195  }
2196}
2197
2198void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
2199  if (!Node->varlist_empty()) {
2200    OS << "copyprivate";
2201    VisitOMPClauseList(Node, '(');
2202    OS << ")";
2203  }
2204}
2205
2206void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
2207  if (!Node->varlist_empty()) {
2208    VisitOMPClauseList(Node, '(');
2209    OS << ")";
2210  }
2211}
2212
2213void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
2214  OS << "(";
2215  Node->getDepobj()->printPretty(OS, nullptr, Policy, 0);
2216  OS << ")";
2217}
2218
2219void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
2220  OS << "depend(";
2221  if (Expr *DepModifier = Node->getModifier()) {
2222    DepModifier->printPretty(OS, nullptr, Policy);
2223    OS << ", ";
2224  }
2225  OpenMPDependClauseKind DepKind = Node->getDependencyKind();
2226  OpenMPDependClauseKind PrintKind = DepKind;
2227  bool IsOmpAllMemory = false;
2228  if (PrintKind == OMPC_DEPEND_outallmemory) {
2229    PrintKind = OMPC_DEPEND_out;
2230    IsOmpAllMemory = true;
2231  } else if (PrintKind == OMPC_DEPEND_inoutallmemory) {
2232    PrintKind = OMPC_DEPEND_inout;
2233    IsOmpAllMemory = true;
2234  }
2235  OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), PrintKind);
2236  if (!Node->varlist_empty() || IsOmpAllMemory)
2237    OS << " :";
2238  VisitOMPClauseList(Node, ' ');
2239  if (IsOmpAllMemory) {
2240    OS << (Node->varlist_empty() ? " " : ",");
2241    OS << "omp_all_memory";
2242  }
2243  OS << ")";
2244}
2245
2246template <typename T>
2247static void PrintMapper(raw_ostream &OS, T *Node,
2248                        const PrintingPolicy &Policy) {
2249  OS << '(';
2250  NestedNameSpecifier *MapperNNS =
2251      Node->getMapperQualifierLoc().getNestedNameSpecifier();
2252  if (MapperNNS)
2253    MapperNNS->print(OS, Policy);
2254  OS << Node->getMapperIdInfo() << ')';
2255}
2256
2257template <typename T>
2258static void PrintIterator(raw_ostream &OS, T *Node,
2259                          const PrintingPolicy &Policy) {
2260  if (Expr *IteratorModifier = Node->getIteratorModifier())
2261    IteratorModifier->printPretty(OS, nullptr, Policy);
2262}
2263
2264void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
2265  if (!Node->varlist_empty()) {
2266    OS << "map(";
2267    if (Node->getMapType() != OMPC_MAP_unknown) {
2268      for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
2269        if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) {
2270          if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator) {
2271            PrintIterator(OS, Node, Policy);
2272          } else {
2273            OS << getOpenMPSimpleClauseTypeName(OMPC_map,
2274                                                Node->getMapTypeModifier(I));
2275            if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper)
2276              PrintMapper(OS, Node, Policy);
2277          }
2278          OS << ',';
2279        }
2280      }
2281      OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
2282      OS << ':';
2283    }
2284    VisitOMPClauseList(Node, ' ');
2285    OS << ")";
2286  }
2287}
2288
2289template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {
2290  if (Node->varlist_empty())
2291    return;
2292  OS << getOpenMPClauseName(Node->getClauseKind());
2293  unsigned ModifierCount = 0;
2294  for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2295    if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)
2296      ++ModifierCount;
2297  }
2298  if (ModifierCount) {
2299    OS << '(';
2300    for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2301      if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {
2302        OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
2303                                            Node->getMotionModifier(I));
2304        if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)
2305          PrintMapper(OS, Node, Policy);
2306        if (I < ModifierCount - 1)
2307          OS << ", ";
2308      }
2309    }
2310    OS << ':';
2311    VisitOMPClauseList(Node, ' ');
2312  } else {
2313    VisitOMPClauseList(Node, '(');
2314  }
2315  OS << ")";
2316}
2317
2318void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
2319  VisitOMPMotionClause(Node);
2320}
2321
2322void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
2323  VisitOMPMotionClause(Node);
2324}
2325
2326void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
2327  OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
2328                           OMPC_dist_schedule, Node->getDistScheduleKind());
2329  if (auto *E = Node->getChunkSize()) {
2330    OS << ", ";
2331    E->printPretty(OS, nullptr, Policy);
2332  }
2333  OS << ")";
2334}
2335
2336void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
2337  OS << "defaultmap(";
2338  OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
2339                                      Node->getDefaultmapModifier());
2340  if (Node->getDefaultmapKind() != OMPC_DEFAULTMAP_unknown) {
2341    OS << ": ";
2342    OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
2343                                        Node->getDefaultmapKind());
2344  }
2345  OS << ")";
2346}
2347
2348void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
2349  if (!Node->varlist_empty()) {
2350    OS << "use_device_ptr";
2351    VisitOMPClauseList(Node, '(');
2352    OS << ")";
2353  }
2354}
2355
2356void OMPClausePrinter::VisitOMPUseDeviceAddrClause(
2357    OMPUseDeviceAddrClause *Node) {
2358  if (!Node->varlist_empty()) {
2359    OS << "use_device_addr";
2360    VisitOMPClauseList(Node, '(');
2361    OS << ")";
2362  }
2363}
2364
2365void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
2366  if (!Node->varlist_empty()) {
2367    OS << "is_device_ptr";
2368    VisitOMPClauseList(Node, '(');
2369    OS << ")";
2370  }
2371}
2372
2373void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {
2374  if (!Node->varlist_empty()) {
2375    OS << "has_device_addr";
2376    VisitOMPClauseList(Node, '(');
2377    OS << ")";
2378  }
2379}
2380
2381void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
2382  if (!Node->varlist_empty()) {
2383    OS << "nontemporal";
2384    VisitOMPClauseList(Node, '(');
2385    OS << ")";
2386  }
2387}
2388
2389void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
2390  OS << "order(";
2391  if (Node->getModifier() != OMPC_ORDER_MODIFIER_unknown) {
2392    OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getModifier());
2393    OS << ": ";
2394  }
2395  OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind()) << ")";
2396}
2397
2398void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
2399  if (!Node->varlist_empty()) {
2400    OS << "inclusive";
2401    VisitOMPClauseList(Node, '(');
2402    OS << ")";
2403  }
2404}
2405
2406void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
2407  if (!Node->varlist_empty()) {
2408    OS << "exclusive";
2409    VisitOMPClauseList(Node, '(');
2410    OS << ")";
2411  }
2412}
2413
2414void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
2415    OMPUsesAllocatorsClause *Node) {
2416  if (Node->getNumberOfAllocators() == 0)
2417    return;
2418  OS << "uses_allocators(";
2419  for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {
2420    OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);
2421    Data.Allocator->printPretty(OS, nullptr, Policy);
2422    if (Data.AllocatorTraits) {
2423      OS << "(";
2424      Data.AllocatorTraits->printPretty(OS, nullptr, Policy);
2425      OS << ")";
2426    }
2427    if (I < E - 1)
2428      OS << ",";
2429  }
2430  OS << ")";
2431}
2432
2433void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
2434  if (Node->varlist_empty())
2435    return;
2436  OS << "affinity";
2437  char StartSym = '(';
2438  if (Expr *Modifier = Node->getModifier()) {
2439    OS << "(";
2440    Modifier->printPretty(OS, nullptr, Policy);
2441    OS << " :";
2442    StartSym = ' ';
2443  }
2444  VisitOMPClauseList(Node, StartSym);
2445  OS << ")";
2446}
2447
2448void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
2449  OS << "filter(";
2450  Node->getThreadID()->printPretty(OS, nullptr, Policy, 0);
2451  OS << ")";
2452}
2453
2454void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
2455  OS << "bind("
2456     << getOpenMPSimpleClauseTypeName(OMPC_bind, unsigned(Node->getBindKind()))
2457     << ")";
2458}
2459
2460void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
2461    OMPXDynCGroupMemClause *Node) {
2462  OS << "ompx_dyn_cgroup_mem(";
2463  Node->getSize()->printPretty(OS, nullptr, Policy, 0);
2464  OS << ")";
2465}
2466
2467void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
2468                                         VariantMatchInfo &VMI) const {
2469  for (const OMPTraitSet &Set : Sets) {
2470    for (const OMPTraitSelector &Selector : Set.Selectors) {
2471
2472      // User conditions are special as we evaluate the condition here.
2473      if (Selector.Kind == TraitSelector::user_condition) {
2474        assert(Selector.ScoreOrCondition &&
2475               "Ill-formed user condition, expected condition expression!");
2476        assert(Selector.Properties.size() == 1 &&
2477               Selector.Properties.front().Kind ==
2478                   TraitProperty::user_condition_unknown &&
2479               "Ill-formed user condition, expected unknown trait property!");
2480
2481        if (std::optional<APSInt> CondVal =
2482                Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx))
2483          VMI.addTrait(CondVal->isZero() ? TraitProperty::user_condition_false
2484                                         : TraitProperty::user_condition_true,
2485                       "<condition>");
2486        else
2487          VMI.addTrait(TraitProperty::user_condition_false, "<condition>");
2488        continue;
2489      }
2490
2491      std::optional<llvm::APSInt> Score;
2492      llvm::APInt *ScorePtr = nullptr;
2493      if (Selector.ScoreOrCondition) {
2494        if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx)))
2495          ScorePtr = &*Score;
2496        else
2497          VMI.addTrait(TraitProperty::user_condition_false,
2498                       "<non-constant-score>");
2499      }
2500
2501      for (const OMPTraitProperty &Property : Selector.Properties)
2502        VMI.addTrait(Set.Kind, Property.Kind, Property.RawString, ScorePtr);
2503
2504      if (Set.Kind != TraitSet::construct)
2505        continue;
2506
2507      // TODO: This might not hold once we implement SIMD properly.
2508      assert(Selector.Properties.size() == 1 &&
2509             Selector.Properties.front().Kind ==
2510                 getOpenMPContextTraitPropertyForSelector(
2511                     Selector.Kind) &&
2512             "Ill-formed construct selector!");
2513    }
2514  }
2515}
2516
2517void OMPTraitInfo::print(llvm::raw_ostream &OS,
2518                         const PrintingPolicy &Policy) const {
2519  bool FirstSet = true;
2520  for (const OMPTraitSet &Set : Sets) {
2521    if (!FirstSet)
2522      OS << ", ";
2523    FirstSet = false;
2524    OS << getOpenMPContextTraitSetName(Set.Kind) << "={";
2525
2526    bool FirstSelector = true;
2527    for (const OMPTraitSelector &Selector : Set.Selectors) {
2528      if (!FirstSelector)
2529        OS << ", ";
2530      FirstSelector = false;
2531      OS << getOpenMPContextTraitSelectorName(Selector.Kind);
2532
2533      bool AllowsTraitScore = false;
2534      bool RequiresProperty = false;
2535      isValidTraitSelectorForTraitSet(
2536          Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
2537
2538      if (!RequiresProperty)
2539        continue;
2540
2541      OS << "(";
2542      if (Selector.Kind == TraitSelector::user_condition) {
2543        if (Selector.ScoreOrCondition)
2544          Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
2545        else
2546          OS << "...";
2547      } else {
2548
2549        if (Selector.ScoreOrCondition) {
2550          OS << "score(";
2551          Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
2552          OS << "): ";
2553        }
2554
2555        bool FirstProperty = true;
2556        for (const OMPTraitProperty &Property : Selector.Properties) {
2557          if (!FirstProperty)
2558            OS << ", ";
2559          FirstProperty = false;
2560          OS << getOpenMPContextTraitPropertyName(Property.Kind,
2561                                                  Property.RawString);
2562        }
2563      }
2564      OS << ")";
2565    }
2566    OS << "}";
2567  }
2568}
2569
2570std::string OMPTraitInfo::getMangledName() const {
2571  std::string MangledName;
2572  llvm::raw_string_ostream OS(MangledName);
2573  for (const OMPTraitSet &Set : Sets) {
2574    OS << '$' << 'S' << unsigned(Set.Kind);
2575    for (const OMPTraitSelector &Selector : Set.Selectors) {
2576
2577      bool AllowsTraitScore = false;
2578      bool RequiresProperty = false;
2579      isValidTraitSelectorForTraitSet(
2580          Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
2581      OS << '$' << 's' << unsigned(Selector.Kind);
2582
2583      if (!RequiresProperty ||
2584          Selector.Kind == TraitSelector::user_condition)
2585        continue;
2586
2587      for (const OMPTraitProperty &Property : Selector.Properties)
2588        OS << '$' << 'P'
2589           << getOpenMPContextTraitPropertyName(Property.Kind,
2590                                                Property.RawString);
2591    }
2592  }
2593  return MangledName;
2594}
2595
2596OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
2597  unsigned long U;
2598  do {
2599    if (!MangledName.consume_front("$S"))
2600      break;
2601    if (MangledName.consumeInteger(10, U))
2602      break;
2603    Sets.push_back(OMPTraitSet());
2604    OMPTraitSet &Set = Sets.back();
2605    Set.Kind = TraitSet(U);
2606    do {
2607      if (!MangledName.consume_front("$s"))
2608        break;
2609      if (MangledName.consumeInteger(10, U))
2610        break;
2611      Set.Selectors.push_back(OMPTraitSelector());
2612      OMPTraitSelector &Selector = Set.Selectors.back();
2613      Selector.Kind = TraitSelector(U);
2614      do {
2615        if (!MangledName.consume_front("$P"))
2616          break;
2617        Selector.Properties.push_back(OMPTraitProperty());
2618        OMPTraitProperty &Property = Selector.Properties.back();
2619        std::pair<StringRef, StringRef> PropRestPair = MangledName.split('$');
2620        Property.RawString = PropRestPair.first;
2621        Property.Kind = getOpenMPContextTraitPropertyKind(
2622            Set.Kind, Selector.Kind, PropRestPair.first);
2623        MangledName = MangledName.drop_front(PropRestPair.first.size());
2624      } while (true);
2625    } while (true);
2626  } while (true);
2627}
2628
2629llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
2630                                     const OMPTraitInfo &TI) {
2631  LangOptions LO;
2632  PrintingPolicy Policy(LO);
2633  TI.print(OS, Policy);
2634  return OS;
2635}
2636llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
2637                                     const OMPTraitInfo *TI) {
2638  return TI ? OS << *TI : OS;
2639}
2640
2641TargetOMPContext::TargetOMPContext(
2642    ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
2643    const FunctionDecl *CurrentFunctionDecl,
2644    ArrayRef<llvm::omp::TraitProperty> ConstructTraits)
2645    : OMPContext(ASTCtx.getLangOpts().OpenMPIsDevice,
2646                 ASTCtx.getTargetInfo().getTriple()),
2647      FeatureValidityCheck([&](StringRef FeatureName) {
2648        return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);
2649      }),
2650      DiagUnknownTrait(std::move(DiagUnknownTrait)) {
2651  ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);
2652
2653  for (llvm::omp::TraitProperty Property : ConstructTraits)
2654    addTrait(Property);
2655}
2656
2657bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
2658  auto It = FeatureMap.find(RawString);
2659  if (It != FeatureMap.end())
2660    return It->second;
2661  if (!FeatureValidityCheck(RawString))
2662    DiagUnknownTrait(RawString);
2663  return false;
2664}
2665