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