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