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