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