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