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