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