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