brintos

brintos / llvm-project-archived public Read only

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