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