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