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