xref: /freebsd/contrib/llvm-project/clang/lib/AST/OpenMPClause.cpp (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
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 //  OpenMP clauses printing methods
1674 //===----------------------------------------------------------------------===//
1675 
1676 void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
1677   OS << "if(";
1678   if (Node->getNameModifier() != OMPD_unknown)
1679     OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
1680   Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1681   OS << ")";
1682 }
1683 
1684 void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
1685   OS << "final(";
1686   Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1687   OS << ")";
1688 }
1689 
1690 void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
1691   OS << "num_threads(";
1692   Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
1693   OS << ")";
1694 }
1695 
1696 void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
1697   OS << "align(";
1698   Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
1699   OS << ")";
1700 }
1701 
1702 void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
1703   OS << "safelen(";
1704   Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
1705   OS << ")";
1706 }
1707 
1708 void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
1709   OS << "simdlen(";
1710   Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);
1711   OS << ")";
1712 }
1713 
1714 void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {
1715   OS << "sizes(";
1716   bool First = true;
1717   for (auto *Size : Node->getSizesRefs()) {
1718     if (!First)
1719       OS << ", ";
1720     Size->printPretty(OS, nullptr, Policy, 0);
1721     First = false;
1722   }
1723   OS << ")";
1724 }
1725 
1726 void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }
1727 
1728 void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
1729   OS << "partial";
1730 
1731   if (Expr *Factor = Node->getFactor()) {
1732     OS << '(';
1733     Factor->printPretty(OS, nullptr, Policy, 0);
1734     OS << ')';
1735   }
1736 }
1737 
1738 void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
1739   OS << "allocator(";
1740   Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
1741   OS << ")";
1742 }
1743 
1744 void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
1745   OS << "collapse(";
1746   Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
1747   OS << ")";
1748 }
1749 
1750 void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
1751   OS << "detach(";
1752   Node->getEventHandler()->printPretty(OS, nullptr, Policy, 0);
1753   OS << ")";
1754 }
1755 
1756 void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
1757   OS << "default("
1758      << getOpenMPSimpleClauseTypeName(OMPC_default,
1759                                       unsigned(Node->getDefaultKind()))
1760      << ")";
1761 }
1762 
1763 void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
1764   OS << "proc_bind("
1765      << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
1766                                       unsigned(Node->getProcBindKind()))
1767      << ")";
1768 }
1769 
1770 void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
1771   OS << "unified_address";
1772 }
1773 
1774 void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
1775     OMPUnifiedSharedMemoryClause *) {
1776   OS << "unified_shared_memory";
1777 }
1778 
1779 void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
1780   OS << "reverse_offload";
1781 }
1782 
1783 void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
1784     OMPDynamicAllocatorsClause *) {
1785   OS << "dynamic_allocators";
1786 }
1787 
1788 void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
1789     OMPAtomicDefaultMemOrderClause *Node) {
1790   OS << "atomic_default_mem_order("
1791      << getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order,
1792                                       Node->getAtomicDefaultMemOrderKind())
1793      << ")";
1794 }
1795 
1796 void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
1797   OS << "at(" << getOpenMPSimpleClauseTypeName(OMPC_at, Node->getAtKind())
1798      << ")";
1799 }
1800 
1801 void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
1802   OS << "severity("
1803      << getOpenMPSimpleClauseTypeName(OMPC_severity, Node->getSeverityKind())
1804      << ")";
1805 }
1806 
1807 void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
1808   OS << "message(\""
1809      << cast<StringLiteral>(Node->getMessageString())->getString() << "\")";
1810 }
1811 
1812 void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
1813   OS << "schedule(";
1814   if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1815     OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
1816                                         Node->getFirstScheduleModifier());
1817     if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
1818       OS << ", ";
1819       OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
1820                                           Node->getSecondScheduleModifier());
1821     }
1822     OS << ": ";
1823   }
1824   OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
1825   if (auto *E = Node->getChunkSize()) {
1826     OS << ", ";
1827     E->printPretty(OS, nullptr, Policy);
1828   }
1829   OS << ")";
1830 }
1831 
1832 void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
1833   OS << "ordered";
1834   if (auto *Num = Node->getNumForLoops()) {
1835     OS << "(";
1836     Num->printPretty(OS, nullptr, Policy, 0);
1837     OS << ")";
1838   }
1839 }
1840 
1841 void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
1842   OS << "nowait";
1843 }
1844 
1845 void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
1846   OS << "untied";
1847 }
1848 
1849 void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
1850   OS << "nogroup";
1851 }
1852 
1853 void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
1854   OS << "mergeable";
1855 }
1856 
1857 void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
1858 
1859 void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
1860 
1861 void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
1862   OS << "update";
1863   if (Node->isExtended()) {
1864     OS << "(";
1865     OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
1866                                         Node->getDependencyKind());
1867     OS << ")";
1868   }
1869 }
1870 
1871 void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
1872   OS << "capture";
1873 }
1874 
1875 void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
1876   OS << "compare";
1877 }
1878 
1879 void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
1880   OS << "seq_cst";
1881 }
1882 
1883 void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
1884   OS << "acq_rel";
1885 }
1886 
1887 void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
1888   OS << "acquire";
1889 }
1890 
1891 void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
1892   OS << "release";
1893 }
1894 
1895 void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
1896   OS << "relaxed";
1897 }
1898 
1899 void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
1900   OS << "threads";
1901 }
1902 
1903 void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
1904 
1905 void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
1906   OS << "device(";
1907   OpenMPDeviceClauseModifier Modifier = Node->getModifier();
1908   if (Modifier != OMPC_DEVICE_unknown) {
1909     OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
1910        << ": ";
1911   }
1912   Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
1913   OS << ")";
1914 }
1915 
1916 void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
1917   OS << "num_teams(";
1918   Node->getNumTeams()->printPretty(OS, nullptr, Policy, 0);
1919   OS << ")";
1920 }
1921 
1922 void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
1923   OS << "thread_limit(";
1924   Node->getThreadLimit()->printPretty(OS, nullptr, Policy, 0);
1925   OS << ")";
1926 }
1927 
1928 void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
1929   OS << "priority(";
1930   Node->getPriority()->printPretty(OS, nullptr, Policy, 0);
1931   OS << ")";
1932 }
1933 
1934 void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
1935   OS << "grainsize(";
1936   OpenMPGrainsizeClauseModifier Modifier = Node->getModifier();
1937   if (Modifier != OMPC_GRAINSIZE_unknown) {
1938     OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
1939        << ": ";
1940   }
1941   Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);
1942   OS << ")";
1943 }
1944 
1945 void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
1946   OS << "num_tasks(";
1947   OpenMPNumTasksClauseModifier Modifier = Node->getModifier();
1948   if (Modifier != OMPC_NUMTASKS_unknown) {
1949     OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
1950        << ": ";
1951   }
1952   Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
1953   OS << ")";
1954 }
1955 
1956 void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
1957   OS << "hint(";
1958   Node->getHint()->printPretty(OS, nullptr, Policy, 0);
1959   OS << ")";
1960 }
1961 
1962 void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
1963   OS << "init(";
1964   bool First = true;
1965   for (const Expr *E : Node->prefs()) {
1966     if (First)
1967       OS << "prefer_type(";
1968     else
1969       OS << ",";
1970     E->printPretty(OS, nullptr, Policy);
1971     First = false;
1972   }
1973   if (!First)
1974     OS << "), ";
1975   if (Node->getIsTarget())
1976     OS << "target";
1977   if (Node->getIsTargetSync()) {
1978     if (Node->getIsTarget())
1979       OS << ", ";
1980     OS << "targetsync";
1981   }
1982   OS << " : ";
1983   Node->getInteropVar()->printPretty(OS, nullptr, Policy);
1984   OS << ")";
1985 }
1986 
1987 void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
1988   OS << "use(";
1989   Node->getInteropVar()->printPretty(OS, nullptr, Policy);
1990   OS << ")";
1991 }
1992 
1993 void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {
1994   OS << "destroy";
1995   if (Expr *E = Node->getInteropVar()) {
1996     OS << "(";
1997     E->printPretty(OS, nullptr, Policy);
1998     OS << ")";
1999   }
2000 }
2001 
2002 void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {
2003   OS << "novariants";
2004   if (Expr *E = Node->getCondition()) {
2005     OS << "(";
2006     E->printPretty(OS, nullptr, Policy, 0);
2007     OS << ")";
2008   }
2009 }
2010 
2011 void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {
2012   OS << "nocontext";
2013   if (Expr *E = Node->getCondition()) {
2014     OS << "(";
2015     E->printPretty(OS, nullptr, Policy, 0);
2016     OS << ")";
2017   }
2018 }
2019 
2020 template<typename T>
2021 void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
2022   for (typename T::varlist_iterator I = Node->varlist_begin(),
2023                                     E = Node->varlist_end();
2024        I != E; ++I) {
2025     assert(*I && "Expected non-null Stmt");
2026     OS << (I == Node->varlist_begin() ? StartSym : ',');
2027     if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
2028       if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
2029         DRE->printPretty(OS, nullptr, Policy, 0);
2030       else
2031         DRE->getDecl()->printQualifiedName(OS);
2032     } else
2033       (*I)->printPretty(OS, nullptr, Policy, 0);
2034   }
2035 }
2036 
2037 void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
2038   if (Node->varlist_empty())
2039     return;
2040   OS << "allocate";
2041   if (Expr *Allocator = Node->getAllocator()) {
2042     OS << "(";
2043     Allocator->printPretty(OS, nullptr, Policy, 0);
2044     OS << ":";
2045     VisitOMPClauseList(Node, ' ');
2046   } else {
2047     VisitOMPClauseList(Node, '(');
2048   }
2049   OS << ")";
2050 }
2051 
2052 void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
2053   if (!Node->varlist_empty()) {
2054     OS << "private";
2055     VisitOMPClauseList(Node, '(');
2056     OS << ")";
2057   }
2058 }
2059 
2060 void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
2061   if (!Node->varlist_empty()) {
2062     OS << "firstprivate";
2063     VisitOMPClauseList(Node, '(');
2064     OS << ")";
2065   }
2066 }
2067 
2068 void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
2069   if (!Node->varlist_empty()) {
2070     OS << "lastprivate";
2071     OpenMPLastprivateModifier LPKind = Node->getKind();
2072     if (LPKind != OMPC_LASTPRIVATE_unknown) {
2073       OS << "("
2074          << getOpenMPSimpleClauseTypeName(OMPC_lastprivate, Node->getKind())
2075          << ":";
2076     }
2077     VisitOMPClauseList(Node, LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
2078     OS << ")";
2079   }
2080 }
2081 
2082 void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
2083   if (!Node->varlist_empty()) {
2084     OS << "shared";
2085     VisitOMPClauseList(Node, '(');
2086     OS << ")";
2087   }
2088 }
2089 
2090 void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
2091   if (!Node->varlist_empty()) {
2092     OS << "reduction(";
2093     if (Node->getModifierLoc().isValid())
2094       OS << getOpenMPSimpleClauseTypeName(OMPC_reduction, Node->getModifier())
2095          << ", ";
2096     NestedNameSpecifier *QualifierLoc =
2097         Node->getQualifierLoc().getNestedNameSpecifier();
2098     OverloadedOperatorKind OOK =
2099         Node->getNameInfo().getName().getCXXOverloadedOperator();
2100     if (QualifierLoc == nullptr && OOK != OO_None) {
2101       // Print reduction identifier in C format
2102       OS << getOperatorSpelling(OOK);
2103     } else {
2104       // Use C++ format
2105       if (QualifierLoc != nullptr)
2106         QualifierLoc->print(OS, Policy);
2107       OS << Node->getNameInfo();
2108     }
2109     OS << ":";
2110     VisitOMPClauseList(Node, ' ');
2111     OS << ")";
2112   }
2113 }
2114 
2115 void OMPClausePrinter::VisitOMPTaskReductionClause(
2116     OMPTaskReductionClause *Node) {
2117   if (!Node->varlist_empty()) {
2118     OS << "task_reduction(";
2119     NestedNameSpecifier *QualifierLoc =
2120         Node->getQualifierLoc().getNestedNameSpecifier();
2121     OverloadedOperatorKind OOK =
2122         Node->getNameInfo().getName().getCXXOverloadedOperator();
2123     if (QualifierLoc == nullptr && OOK != OO_None) {
2124       // Print reduction identifier in C format
2125       OS << getOperatorSpelling(OOK);
2126     } else {
2127       // Use C++ format
2128       if (QualifierLoc != nullptr)
2129         QualifierLoc->print(OS, Policy);
2130       OS << Node->getNameInfo();
2131     }
2132     OS << ":";
2133     VisitOMPClauseList(Node, ' ');
2134     OS << ")";
2135   }
2136 }
2137 
2138 void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
2139   if (!Node->varlist_empty()) {
2140     OS << "in_reduction(";
2141     NestedNameSpecifier *QualifierLoc =
2142         Node->getQualifierLoc().getNestedNameSpecifier();
2143     OverloadedOperatorKind OOK =
2144         Node->getNameInfo().getName().getCXXOverloadedOperator();
2145     if (QualifierLoc == nullptr && OOK != OO_None) {
2146       // Print reduction identifier in C format
2147       OS << getOperatorSpelling(OOK);
2148     } else {
2149       // Use C++ format
2150       if (QualifierLoc != nullptr)
2151         QualifierLoc->print(OS, Policy);
2152       OS << Node->getNameInfo();
2153     }
2154     OS << ":";
2155     VisitOMPClauseList(Node, ' ');
2156     OS << ")";
2157   }
2158 }
2159 
2160 void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
2161   if (!Node->varlist_empty()) {
2162     OS << "linear";
2163     if (Node->getModifierLoc().isValid()) {
2164       OS << '('
2165          << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
2166     }
2167     VisitOMPClauseList(Node, '(');
2168     if (Node->getModifierLoc().isValid())
2169       OS << ')';
2170     if (Node->getStep() != nullptr) {
2171       OS << ": ";
2172       Node->getStep()->printPretty(OS, nullptr, Policy, 0);
2173     }
2174     OS << ")";
2175   }
2176 }
2177 
2178 void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
2179   if (!Node->varlist_empty()) {
2180     OS << "aligned";
2181     VisitOMPClauseList(Node, '(');
2182     if (Node->getAlignment() != nullptr) {
2183       OS << ": ";
2184       Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
2185     }
2186     OS << ")";
2187   }
2188 }
2189 
2190 void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
2191   if (!Node->varlist_empty()) {
2192     OS << "copyin";
2193     VisitOMPClauseList(Node, '(');
2194     OS << ")";
2195   }
2196 }
2197 
2198 void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
2199   if (!Node->varlist_empty()) {
2200     OS << "copyprivate";
2201     VisitOMPClauseList(Node, '(');
2202     OS << ")";
2203   }
2204 }
2205 
2206 void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
2207   if (!Node->varlist_empty()) {
2208     VisitOMPClauseList(Node, '(');
2209     OS << ")";
2210   }
2211 }
2212 
2213 void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
2214   OS << "(";
2215   Node->getDepobj()->printPretty(OS, nullptr, Policy, 0);
2216   OS << ")";
2217 }
2218 
2219 void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
2220   OS << "depend(";
2221   if (Expr *DepModifier = Node->getModifier()) {
2222     DepModifier->printPretty(OS, nullptr, Policy);
2223     OS << ", ";
2224   }
2225   OpenMPDependClauseKind DepKind = Node->getDependencyKind();
2226   OpenMPDependClauseKind PrintKind = DepKind;
2227   bool IsOmpAllMemory = false;
2228   if (PrintKind == OMPC_DEPEND_outallmemory) {
2229     PrintKind = OMPC_DEPEND_out;
2230     IsOmpAllMemory = true;
2231   } else if (PrintKind == OMPC_DEPEND_inoutallmemory) {
2232     PrintKind = OMPC_DEPEND_inout;
2233     IsOmpAllMemory = true;
2234   }
2235   OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), PrintKind);
2236   if (!Node->varlist_empty() || IsOmpAllMemory)
2237     OS << " :";
2238   VisitOMPClauseList(Node, ' ');
2239   if (IsOmpAllMemory) {
2240     OS << (Node->varlist_empty() ? " " : ",");
2241     OS << "omp_all_memory";
2242   }
2243   OS << ")";
2244 }
2245 
2246 template <typename T>
2247 static void PrintMapper(raw_ostream &OS, T *Node,
2248                         const PrintingPolicy &Policy) {
2249   OS << '(';
2250   NestedNameSpecifier *MapperNNS =
2251       Node->getMapperQualifierLoc().getNestedNameSpecifier();
2252   if (MapperNNS)
2253     MapperNNS->print(OS, Policy);
2254   OS << Node->getMapperIdInfo() << ')';
2255 }
2256 
2257 template <typename T>
2258 static void PrintIterator(raw_ostream &OS, T *Node,
2259                           const PrintingPolicy &Policy) {
2260   if (Expr *IteratorModifier = Node->getIteratorModifier())
2261     IteratorModifier->printPretty(OS, nullptr, Policy);
2262 }
2263 
2264 void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
2265   if (!Node->varlist_empty()) {
2266     OS << "map(";
2267     if (Node->getMapType() != OMPC_MAP_unknown) {
2268       for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
2269         if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) {
2270           if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator) {
2271             PrintIterator(OS, Node, Policy);
2272           } else {
2273             OS << getOpenMPSimpleClauseTypeName(OMPC_map,
2274                                                 Node->getMapTypeModifier(I));
2275             if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper)
2276               PrintMapper(OS, Node, Policy);
2277           }
2278           OS << ',';
2279         }
2280       }
2281       OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
2282       OS << ':';
2283     }
2284     VisitOMPClauseList(Node, ' ');
2285     OS << ")";
2286   }
2287 }
2288 
2289 template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {
2290   if (Node->varlist_empty())
2291     return;
2292   OS << getOpenMPClauseName(Node->getClauseKind());
2293   unsigned ModifierCount = 0;
2294   for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2295     if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)
2296       ++ModifierCount;
2297   }
2298   if (ModifierCount) {
2299     OS << '(';
2300     for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
2301       if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {
2302         OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
2303                                             Node->getMotionModifier(I));
2304         if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)
2305           PrintMapper(OS, Node, Policy);
2306         if (I < ModifierCount - 1)
2307           OS << ", ";
2308       }
2309     }
2310     OS << ':';
2311     VisitOMPClauseList(Node, ' ');
2312   } else {
2313     VisitOMPClauseList(Node, '(');
2314   }
2315   OS << ")";
2316 }
2317 
2318 void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
2319   VisitOMPMotionClause(Node);
2320 }
2321 
2322 void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
2323   VisitOMPMotionClause(Node);
2324 }
2325 
2326 void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
2327   OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
2328                            OMPC_dist_schedule, Node->getDistScheduleKind());
2329   if (auto *E = Node->getChunkSize()) {
2330     OS << ", ";
2331     E->printPretty(OS, nullptr, Policy);
2332   }
2333   OS << ")";
2334 }
2335 
2336 void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
2337   OS << "defaultmap(";
2338   OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
2339                                       Node->getDefaultmapModifier());
2340   if (Node->getDefaultmapKind() != OMPC_DEFAULTMAP_unknown) {
2341     OS << ": ";
2342     OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
2343                                         Node->getDefaultmapKind());
2344   }
2345   OS << ")";
2346 }
2347 
2348 void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
2349   if (!Node->varlist_empty()) {
2350     OS << "use_device_ptr";
2351     VisitOMPClauseList(Node, '(');
2352     OS << ")";
2353   }
2354 }
2355 
2356 void OMPClausePrinter::VisitOMPUseDeviceAddrClause(
2357     OMPUseDeviceAddrClause *Node) {
2358   if (!Node->varlist_empty()) {
2359     OS << "use_device_addr";
2360     VisitOMPClauseList(Node, '(');
2361     OS << ")";
2362   }
2363 }
2364 
2365 void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
2366   if (!Node->varlist_empty()) {
2367     OS << "is_device_ptr";
2368     VisitOMPClauseList(Node, '(');
2369     OS << ")";
2370   }
2371 }
2372 
2373 void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {
2374   if (!Node->varlist_empty()) {
2375     OS << "has_device_addr";
2376     VisitOMPClauseList(Node, '(');
2377     OS << ")";
2378   }
2379 }
2380 
2381 void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
2382   if (!Node->varlist_empty()) {
2383     OS << "nontemporal";
2384     VisitOMPClauseList(Node, '(');
2385     OS << ")";
2386   }
2387 }
2388 
2389 void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
2390   OS << "order(";
2391   if (Node->getModifier() != OMPC_ORDER_MODIFIER_unknown) {
2392     OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getModifier());
2393     OS << ": ";
2394   }
2395   OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind()) << ")";
2396 }
2397 
2398 void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
2399   if (!Node->varlist_empty()) {
2400     OS << "inclusive";
2401     VisitOMPClauseList(Node, '(');
2402     OS << ")";
2403   }
2404 }
2405 
2406 void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
2407   if (!Node->varlist_empty()) {
2408     OS << "exclusive";
2409     VisitOMPClauseList(Node, '(');
2410     OS << ")";
2411   }
2412 }
2413 
2414 void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
2415     OMPUsesAllocatorsClause *Node) {
2416   if (Node->getNumberOfAllocators() == 0)
2417     return;
2418   OS << "uses_allocators(";
2419   for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {
2420     OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);
2421     Data.Allocator->printPretty(OS, nullptr, Policy);
2422     if (Data.AllocatorTraits) {
2423       OS << "(";
2424       Data.AllocatorTraits->printPretty(OS, nullptr, Policy);
2425       OS << ")";
2426     }
2427     if (I < E - 1)
2428       OS << ",";
2429   }
2430   OS << ")";
2431 }
2432 
2433 void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
2434   if (Node->varlist_empty())
2435     return;
2436   OS << "affinity";
2437   char StartSym = '(';
2438   if (Expr *Modifier = Node->getModifier()) {
2439     OS << "(";
2440     Modifier->printPretty(OS, nullptr, Policy);
2441     OS << " :";
2442     StartSym = ' ';
2443   }
2444   VisitOMPClauseList(Node, StartSym);
2445   OS << ")";
2446 }
2447 
2448 void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
2449   OS << "filter(";
2450   Node->getThreadID()->printPretty(OS, nullptr, Policy, 0);
2451   OS << ")";
2452 }
2453 
2454 void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
2455   OS << "bind("
2456      << getOpenMPSimpleClauseTypeName(OMPC_bind, unsigned(Node->getBindKind()))
2457      << ")";
2458 }
2459 
2460 void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
2461     OMPXDynCGroupMemClause *Node) {
2462   OS << "ompx_dyn_cgroup_mem(";
2463   Node->getSize()->printPretty(OS, nullptr, Policy, 0);
2464   OS << ")";
2465 }
2466 
2467 void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
2468                                          VariantMatchInfo &VMI) const {
2469   for (const OMPTraitSet &Set : Sets) {
2470     for (const OMPTraitSelector &Selector : Set.Selectors) {
2471 
2472       // User conditions are special as we evaluate the condition here.
2473       if (Selector.Kind == TraitSelector::user_condition) {
2474         assert(Selector.ScoreOrCondition &&
2475                "Ill-formed user condition, expected condition expression!");
2476         assert(Selector.Properties.size() == 1 &&
2477                Selector.Properties.front().Kind ==
2478                    TraitProperty::user_condition_unknown &&
2479                "Ill-formed user condition, expected unknown trait property!");
2480 
2481         if (std::optional<APSInt> CondVal =
2482                 Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx))
2483           VMI.addTrait(CondVal->isZero() ? TraitProperty::user_condition_false
2484                                          : TraitProperty::user_condition_true,
2485                        "<condition>");
2486         else
2487           VMI.addTrait(TraitProperty::user_condition_false, "<condition>");
2488         continue;
2489       }
2490 
2491       std::optional<llvm::APSInt> Score;
2492       llvm::APInt *ScorePtr = nullptr;
2493       if (Selector.ScoreOrCondition) {
2494         if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx)))
2495           ScorePtr = &*Score;
2496         else
2497           VMI.addTrait(TraitProperty::user_condition_false,
2498                        "<non-constant-score>");
2499       }
2500 
2501       for (const OMPTraitProperty &Property : Selector.Properties)
2502         VMI.addTrait(Set.Kind, Property.Kind, Property.RawString, ScorePtr);
2503 
2504       if (Set.Kind != TraitSet::construct)
2505         continue;
2506 
2507       // TODO: This might not hold once we implement SIMD properly.
2508       assert(Selector.Properties.size() == 1 &&
2509              Selector.Properties.front().Kind ==
2510                  getOpenMPContextTraitPropertyForSelector(
2511                      Selector.Kind) &&
2512              "Ill-formed construct selector!");
2513     }
2514   }
2515 }
2516 
2517 void OMPTraitInfo::print(llvm::raw_ostream &OS,
2518                          const PrintingPolicy &Policy) const {
2519   bool FirstSet = true;
2520   for (const OMPTraitSet &Set : Sets) {
2521     if (!FirstSet)
2522       OS << ", ";
2523     FirstSet = false;
2524     OS << getOpenMPContextTraitSetName(Set.Kind) << "={";
2525 
2526     bool FirstSelector = true;
2527     for (const OMPTraitSelector &Selector : Set.Selectors) {
2528       if (!FirstSelector)
2529         OS << ", ";
2530       FirstSelector = false;
2531       OS << getOpenMPContextTraitSelectorName(Selector.Kind);
2532 
2533       bool AllowsTraitScore = false;
2534       bool RequiresProperty = false;
2535       isValidTraitSelectorForTraitSet(
2536           Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
2537 
2538       if (!RequiresProperty)
2539         continue;
2540 
2541       OS << "(";
2542       if (Selector.Kind == TraitSelector::user_condition) {
2543         if (Selector.ScoreOrCondition)
2544           Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
2545         else
2546           OS << "...";
2547       } else {
2548 
2549         if (Selector.ScoreOrCondition) {
2550           OS << "score(";
2551           Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
2552           OS << "): ";
2553         }
2554 
2555         bool FirstProperty = true;
2556         for (const OMPTraitProperty &Property : Selector.Properties) {
2557           if (!FirstProperty)
2558             OS << ", ";
2559           FirstProperty = false;
2560           OS << getOpenMPContextTraitPropertyName(Property.Kind,
2561                                                   Property.RawString);
2562         }
2563       }
2564       OS << ")";
2565     }
2566     OS << "}";
2567   }
2568 }
2569 
2570 std::string OMPTraitInfo::getMangledName() const {
2571   std::string MangledName;
2572   llvm::raw_string_ostream OS(MangledName);
2573   for (const OMPTraitSet &Set : Sets) {
2574     OS << '$' << 'S' << unsigned(Set.Kind);
2575     for (const OMPTraitSelector &Selector : Set.Selectors) {
2576 
2577       bool AllowsTraitScore = false;
2578       bool RequiresProperty = false;
2579       isValidTraitSelectorForTraitSet(
2580           Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
2581       OS << '$' << 's' << unsigned(Selector.Kind);
2582 
2583       if (!RequiresProperty ||
2584           Selector.Kind == TraitSelector::user_condition)
2585         continue;
2586 
2587       for (const OMPTraitProperty &Property : Selector.Properties)
2588         OS << '$' << 'P'
2589            << getOpenMPContextTraitPropertyName(Property.Kind,
2590                                                 Property.RawString);
2591     }
2592   }
2593   return MangledName;
2594 }
2595 
2596 OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
2597   unsigned long U;
2598   do {
2599     if (!MangledName.consume_front("$S"))
2600       break;
2601     if (MangledName.consumeInteger(10, U))
2602       break;
2603     Sets.push_back(OMPTraitSet());
2604     OMPTraitSet &Set = Sets.back();
2605     Set.Kind = TraitSet(U);
2606     do {
2607       if (!MangledName.consume_front("$s"))
2608         break;
2609       if (MangledName.consumeInteger(10, U))
2610         break;
2611       Set.Selectors.push_back(OMPTraitSelector());
2612       OMPTraitSelector &Selector = Set.Selectors.back();
2613       Selector.Kind = TraitSelector(U);
2614       do {
2615         if (!MangledName.consume_front("$P"))
2616           break;
2617         Selector.Properties.push_back(OMPTraitProperty());
2618         OMPTraitProperty &Property = Selector.Properties.back();
2619         std::pair<StringRef, StringRef> PropRestPair = MangledName.split('$');
2620         Property.RawString = PropRestPair.first;
2621         Property.Kind = getOpenMPContextTraitPropertyKind(
2622             Set.Kind, Selector.Kind, PropRestPair.first);
2623         MangledName = MangledName.drop_front(PropRestPair.first.size());
2624       } while (true);
2625     } while (true);
2626   } while (true);
2627 }
2628 
2629 llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
2630                                      const OMPTraitInfo &TI) {
2631   LangOptions LO;
2632   PrintingPolicy Policy(LO);
2633   TI.print(OS, Policy);
2634   return OS;
2635 }
2636 llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
2637                                      const OMPTraitInfo *TI) {
2638   return TI ? OS << *TI : OS;
2639 }
2640 
2641 TargetOMPContext::TargetOMPContext(
2642     ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
2643     const FunctionDecl *CurrentFunctionDecl,
2644     ArrayRef<llvm::omp::TraitProperty> ConstructTraits)
2645     : OMPContext(ASTCtx.getLangOpts().OpenMPIsDevice,
2646                  ASTCtx.getTargetInfo().getTriple()),
2647       FeatureValidityCheck([&](StringRef FeatureName) {
2648         return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);
2649       }),
2650       DiagUnknownTrait(std::move(DiagUnknownTrait)) {
2651   ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);
2652 
2653   for (llvm::omp::TraitProperty Property : ConstructTraits)
2654     addTrait(Property);
2655 }
2656 
2657 bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
2658   auto It = FeatureMap.find(RawString);
2659   if (It != FeatureMap.end())
2660     return It->second;
2661   if (!FeatureValidityCheck(RawString))
2662     DiagUnknownTrait(RawString);
2663   return false;
2664 }
2665