1 //===- OpenACCClause.h - Classes for OpenACC clauses ------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // \file 10 // This file defines OpenACC AST classes for clauses. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_OPENACCCLAUSE_H 15 #define LLVM_CLANG_AST_OPENACCCLAUSE_H 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/StmtIterator.h" 18 #include "clang/Basic/OpenACCKinds.h" 19 20 #include <utility> 21 22 namespace clang { 23 /// This is the base type for all OpenACC Clauses. 24 class OpenACCClause { 25 OpenACCClauseKind Kind; 26 SourceRange Location; 27 28 protected: 29 OpenACCClause(OpenACCClauseKind K, SourceLocation BeginLoc, 30 SourceLocation EndLoc) 31 : Kind(K), Location(BeginLoc, EndLoc) { 32 assert(!BeginLoc.isInvalid() && !EndLoc.isInvalid() && 33 "Begin and end location must be valid for OpenACCClause"); 34 } 35 36 public: 37 OpenACCClauseKind getClauseKind() const { return Kind; } 38 SourceLocation getBeginLoc() const { return Location.getBegin(); } 39 SourceLocation getEndLoc() const { return Location.getEnd(); } 40 41 static bool classof(const OpenACCClause *) { return true; } 42 43 using child_iterator = StmtIterator; 44 using const_child_iterator = ConstStmtIterator; 45 using child_range = llvm::iterator_range<child_iterator>; 46 using const_child_range = llvm::iterator_range<const_child_iterator>; 47 48 child_range children(); 49 const_child_range children() const { 50 auto Children = const_cast<OpenACCClause *>(this)->children(); 51 return const_child_range(Children.begin(), Children.end()); 52 } 53 54 virtual ~OpenACCClause() = default; 55 }; 56 57 // Represents the 'auto' clause. 58 class OpenACCAutoClause : public OpenACCClause { 59 protected: 60 OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc) 61 : OpenACCClause(OpenACCClauseKind::Auto, BeginLoc, EndLoc) {} 62 63 public: 64 static bool classof(const OpenACCClause *C) { 65 return C->getClauseKind() == OpenACCClauseKind::Auto; 66 } 67 68 static OpenACCAutoClause * 69 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 70 71 child_range children() { 72 return child_range(child_iterator(), child_iterator()); 73 } 74 const_child_range children() const { 75 return const_child_range(const_child_iterator(), const_child_iterator()); 76 } 77 }; 78 79 // Represents the 'finalize' clause. 80 class OpenACCFinalizeClause : public OpenACCClause { 81 protected: 82 OpenACCFinalizeClause(SourceLocation BeginLoc, SourceLocation EndLoc) 83 : OpenACCClause(OpenACCClauseKind::Finalize, BeginLoc, EndLoc) {} 84 85 public: 86 static bool classof(const OpenACCClause *C) { 87 return C->getClauseKind() == OpenACCClauseKind::Finalize; 88 } 89 90 static OpenACCFinalizeClause * 91 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 92 93 child_range children() { 94 return child_range(child_iterator(), child_iterator()); 95 } 96 const_child_range children() const { 97 return const_child_range(const_child_iterator(), const_child_iterator()); 98 } 99 }; 100 101 // Represents the 'if_present' clause. 102 class OpenACCIfPresentClause : public OpenACCClause { 103 protected: 104 OpenACCIfPresentClause(SourceLocation BeginLoc, SourceLocation EndLoc) 105 : OpenACCClause(OpenACCClauseKind::IfPresent, BeginLoc, EndLoc) {} 106 107 public: 108 static bool classof(const OpenACCClause *C) { 109 return C->getClauseKind() == OpenACCClauseKind::IfPresent; 110 } 111 112 static OpenACCIfPresentClause * 113 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 114 115 child_range children() { 116 return child_range(child_iterator(), child_iterator()); 117 } 118 const_child_range children() const { 119 return const_child_range(const_child_iterator(), const_child_iterator()); 120 } 121 }; 122 123 // Represents the 'independent' clause. 124 class OpenACCIndependentClause : public OpenACCClause { 125 protected: 126 OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc) 127 : OpenACCClause(OpenACCClauseKind::Independent, BeginLoc, EndLoc) {} 128 129 public: 130 static bool classof(const OpenACCClause *C) { 131 return C->getClauseKind() == OpenACCClauseKind::Independent; 132 } 133 134 static OpenACCIndependentClause * 135 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 136 137 child_range children() { 138 return child_range(child_iterator(), child_iterator()); 139 } 140 const_child_range children() const { 141 return const_child_range(const_child_iterator(), const_child_iterator()); 142 } 143 }; 144 // Represents the 'seq' clause. 145 class OpenACCSeqClause : public OpenACCClause { 146 protected: 147 OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc) 148 : OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {} 149 150 public: 151 static bool classof(const OpenACCClause *C) { 152 return C->getClauseKind() == OpenACCClauseKind::Seq; 153 } 154 155 static OpenACCSeqClause * 156 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 157 158 child_range children() { 159 return child_range(child_iterator(), child_iterator()); 160 } 161 const_child_range children() const { 162 return const_child_range(const_child_iterator(), const_child_iterator()); 163 } 164 }; 165 166 /// Represents a clause that has a list of parameters. 167 class OpenACCClauseWithParams : public OpenACCClause { 168 /// Location of the '('. 169 SourceLocation LParenLoc; 170 171 protected: 172 OpenACCClauseWithParams(OpenACCClauseKind K, SourceLocation BeginLoc, 173 SourceLocation LParenLoc, SourceLocation EndLoc) 174 : OpenACCClause(K, BeginLoc, EndLoc), LParenLoc(LParenLoc) {} 175 176 public: 177 static bool classof(const OpenACCClause *C); 178 179 SourceLocation getLParenLoc() const { return LParenLoc; } 180 181 child_range children() { 182 return child_range(child_iterator(), child_iterator()); 183 } 184 const_child_range children() const { 185 return const_child_range(const_child_iterator(), const_child_iterator()); 186 } 187 }; 188 189 using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>; 190 /// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or 191 /// an identifier. The 'asterisk' means 'the rest'. 192 class OpenACCDeviceTypeClause final 193 : public OpenACCClauseWithParams, 194 private llvm::TrailingObjects<OpenACCDeviceTypeClause, 195 DeviceTypeArgument> { 196 friend TrailingObjects; 197 // Data stored in trailing objects as IdentifierInfo* /SourceLocation pairs. A 198 // nullptr IdentifierInfo* represents an asterisk. 199 unsigned NumArchs; 200 OpenACCDeviceTypeClause(OpenACCClauseKind K, SourceLocation BeginLoc, 201 SourceLocation LParenLoc, 202 ArrayRef<DeviceTypeArgument> Archs, 203 SourceLocation EndLoc) 204 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc), 205 NumArchs(Archs.size()) { 206 assert( 207 (K == OpenACCClauseKind::DeviceType || K == OpenACCClauseKind::DType) && 208 "Invalid clause kind for device-type"); 209 210 assert(!llvm::any_of(Archs, [](const DeviceTypeArgument &Arg) { 211 return Arg.second.isInvalid(); 212 }) && "Invalid SourceLocation for an argument"); 213 214 assert( 215 (Archs.size() == 1 || !llvm::any_of(Archs, 216 [](const DeviceTypeArgument &Arg) { 217 return Arg.first == nullptr; 218 })) && 219 "Only a single asterisk version is permitted, and must be the " 220 "only one"); 221 222 std::uninitialized_copy(Archs.begin(), Archs.end(), 223 getTrailingObjects<DeviceTypeArgument>()); 224 } 225 226 public: 227 static bool classof(const OpenACCClause *C) { 228 return C->getClauseKind() == OpenACCClauseKind::DType || 229 C->getClauseKind() == OpenACCClauseKind::DeviceType; 230 } 231 bool hasAsterisk() const { 232 return getArchitectures().size() > 0 && 233 getArchitectures()[0].first == nullptr; 234 } 235 236 ArrayRef<DeviceTypeArgument> getArchitectures() const { 237 return ArrayRef<DeviceTypeArgument>( 238 getTrailingObjects<DeviceTypeArgument>(), NumArchs); 239 } 240 241 static OpenACCDeviceTypeClause * 242 Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, 243 SourceLocation LParenLoc, ArrayRef<DeviceTypeArgument> Archs, 244 SourceLocation EndLoc); 245 }; 246 247 /// A 'default' clause, has the optional 'none' or 'present' argument. 248 class OpenACCDefaultClause : public OpenACCClauseWithParams { 249 friend class ASTReaderStmt; 250 friend class ASTWriterStmt; 251 252 OpenACCDefaultClauseKind DefaultClauseKind; 253 254 protected: 255 OpenACCDefaultClause(OpenACCDefaultClauseKind K, SourceLocation BeginLoc, 256 SourceLocation LParenLoc, SourceLocation EndLoc) 257 : OpenACCClauseWithParams(OpenACCClauseKind::Default, BeginLoc, LParenLoc, 258 EndLoc), 259 DefaultClauseKind(K) { 260 assert((DefaultClauseKind == OpenACCDefaultClauseKind::None || 261 DefaultClauseKind == OpenACCDefaultClauseKind::Present) && 262 "Invalid Clause Kind"); 263 } 264 265 public: 266 static bool classof(const OpenACCClause *C) { 267 return C->getClauseKind() == OpenACCClauseKind::Default; 268 } 269 OpenACCDefaultClauseKind getDefaultClauseKind() const { 270 return DefaultClauseKind; 271 } 272 273 static OpenACCDefaultClause *Create(const ASTContext &C, 274 OpenACCDefaultClauseKind K, 275 SourceLocation BeginLoc, 276 SourceLocation LParenLoc, 277 SourceLocation EndLoc); 278 }; 279 280 /// Represents one of the handful of classes that has an optional/required 281 /// 'condition' expression as an argument. 282 class OpenACCClauseWithCondition : public OpenACCClauseWithParams { 283 Expr *ConditionExpr = nullptr; 284 285 protected: 286 OpenACCClauseWithCondition(OpenACCClauseKind K, SourceLocation BeginLoc, 287 SourceLocation LParenLoc, Expr *ConditionExpr, 288 SourceLocation EndLoc) 289 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc), 290 ConditionExpr(ConditionExpr) {} 291 292 public: 293 static bool classof(const OpenACCClause *C); 294 295 bool hasConditionExpr() const { return ConditionExpr; } 296 const Expr *getConditionExpr() const { return ConditionExpr; } 297 Expr *getConditionExpr() { return ConditionExpr; } 298 299 child_range children() { 300 if (ConditionExpr) 301 return child_range(reinterpret_cast<Stmt **>(&ConditionExpr), 302 reinterpret_cast<Stmt **>(&ConditionExpr + 1)); 303 return child_range(child_iterator(), child_iterator()); 304 } 305 306 const_child_range children() const { 307 if (ConditionExpr) 308 return const_child_range( 309 reinterpret_cast<Stmt *const *>(&ConditionExpr), 310 reinterpret_cast<Stmt *const *>(&ConditionExpr + 1)); 311 return const_child_range(const_child_iterator(), const_child_iterator()); 312 } 313 }; 314 315 /// An 'if' clause, which has a required condition expression. 316 class OpenACCIfClause : public OpenACCClauseWithCondition { 317 protected: 318 OpenACCIfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 319 Expr *ConditionExpr, SourceLocation EndLoc); 320 321 public: 322 static bool classof(const OpenACCClause *C) { 323 return C->getClauseKind() == OpenACCClauseKind::If; 324 } 325 static OpenACCIfClause *Create(const ASTContext &C, SourceLocation BeginLoc, 326 SourceLocation LParenLoc, Expr *ConditionExpr, 327 SourceLocation EndLoc); 328 }; 329 330 /// A 'self' clause, which has an optional condition expression, or, in the 331 /// event of an 'update' directive, contains a 'VarList'. 332 class OpenACCSelfClause final 333 : public OpenACCClauseWithParams, 334 private llvm::TrailingObjects<OpenACCSelfClause, Expr *> { 335 friend TrailingObjects; 336 // Holds whether this HAS a condition expression. Lacks a value if this is NOT 337 // a condition-expr self clause. 338 std::optional<bool> HasConditionExpr; 339 // Holds the number of stored expressions. In the case of a condition-expr 340 // self clause, this is expected to be ONE (and there to be 1 trailing 341 // object), whether or not that is null. 342 unsigned NumExprs; 343 344 OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 345 Expr *ConditionExpr, SourceLocation EndLoc); 346 OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 347 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 348 349 // Intentionally internal, meant to be an implementation detail of everything 350 // else. All non-internal uses should go through getConditionExpr/getVarList. 351 llvm::ArrayRef<Expr *> getExprs() const { 352 return {getTrailingObjects<Expr *>(), NumExprs}; 353 } 354 355 public: 356 static bool classof(const OpenACCClause *C) { 357 return C->getClauseKind() == OpenACCClauseKind::Self; 358 } 359 360 bool isConditionExprClause() const { return HasConditionExpr.has_value(); } 361 362 bool hasConditionExpr() const { 363 assert(HasConditionExpr.has_value() && 364 "VarList Self Clause asked about condition expression"); 365 return *HasConditionExpr; 366 } 367 368 const Expr *getConditionExpr() const { 369 assert(HasConditionExpr.has_value() && 370 "VarList Self Clause asked about condition expression"); 371 assert(getExprs().size() == 1 && 372 "ConditionExpr Self Clause with too many Exprs"); 373 return getExprs()[0]; 374 } 375 376 Expr *getConditionExpr() { 377 assert(HasConditionExpr.has_value() && 378 "VarList Self Clause asked about condition expression"); 379 assert(getExprs().size() == 1 && 380 "ConditionExpr Self Clause with too many Exprs"); 381 return getExprs()[0]; 382 } 383 384 ArrayRef<Expr *> getVarList() { 385 assert(!HasConditionExpr.has_value() && 386 "Condition Expr self clause asked about var list"); 387 return getExprs(); 388 } 389 ArrayRef<Expr *> getVarList() const { 390 assert(!HasConditionExpr.has_value() && 391 "Condition Expr self clause asked about var list"); 392 return getExprs(); 393 } 394 395 child_range children() { 396 return child_range( 397 reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>()), 398 reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>() + NumExprs)); 399 } 400 401 const_child_range children() const { 402 child_range Children = const_cast<OpenACCSelfClause *>(this)->children(); 403 return const_child_range(Children.begin(), Children.end()); 404 } 405 406 static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc, 407 SourceLocation LParenLoc, 408 Expr *ConditionExpr, SourceLocation EndLoc); 409 static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc, 410 SourceLocation LParenLoc, 411 ArrayRef<Expr *> ConditionExpr, 412 SourceLocation EndLoc); 413 }; 414 415 /// Represents a clause that has one or more expressions associated with it. 416 class OpenACCClauseWithExprs : public OpenACCClauseWithParams { 417 MutableArrayRef<Expr *> Exprs; 418 419 protected: 420 OpenACCClauseWithExprs(OpenACCClauseKind K, SourceLocation BeginLoc, 421 SourceLocation LParenLoc, SourceLocation EndLoc) 422 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {} 423 424 /// Used only for initialization, the leaf class can initialize this to 425 /// trailing storage. 426 void setExprs(MutableArrayRef<Expr *> NewExprs) { 427 assert(Exprs.empty() && "Cannot change Exprs list"); 428 Exprs = NewExprs; 429 } 430 431 /// Gets the entire list of expressions, but leave it to the 432 /// individual clauses to expose this how they'd like. 433 llvm::ArrayRef<Expr *> getExprs() const { return Exprs; } 434 435 public: 436 static bool classof(const OpenACCClause *C); 437 child_range children() { 438 return child_range(reinterpret_cast<Stmt **>(Exprs.begin()), 439 reinterpret_cast<Stmt **>(Exprs.end())); 440 } 441 442 const_child_range children() const { 443 child_range Children = 444 const_cast<OpenACCClauseWithExprs *>(this)->children(); 445 return const_child_range(Children.begin(), Children.end()); 446 } 447 }; 448 449 // Represents the 'devnum' and expressions lists for the 'wait' clause. 450 class OpenACCWaitClause final 451 : public OpenACCClauseWithExprs, 452 private llvm::TrailingObjects<OpenACCWaitClause, Expr *> { 453 friend TrailingObjects; 454 SourceLocation QueuesLoc; 455 OpenACCWaitClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 456 Expr *DevNumExpr, SourceLocation QueuesLoc, 457 ArrayRef<Expr *> QueueIdExprs, SourceLocation EndLoc) 458 : OpenACCClauseWithExprs(OpenACCClauseKind::Wait, BeginLoc, LParenLoc, 459 EndLoc), 460 QueuesLoc(QueuesLoc) { 461 // The first element of the trailing storage is always the devnum expr, 462 // whether it is used or not. 463 std::uninitialized_copy(&DevNumExpr, &DevNumExpr + 1, 464 getTrailingObjects<Expr *>()); 465 std::uninitialized_copy(QueueIdExprs.begin(), QueueIdExprs.end(), 466 getTrailingObjects<Expr *>() + 1); 467 setExprs( 468 MutableArrayRef(getTrailingObjects<Expr *>(), QueueIdExprs.size() + 1)); 469 } 470 471 public: 472 static bool classof(const OpenACCClause *C) { 473 return C->getClauseKind() == OpenACCClauseKind::Wait; 474 } 475 static OpenACCWaitClause *Create(const ASTContext &C, SourceLocation BeginLoc, 476 SourceLocation LParenLoc, Expr *DevNumExpr, 477 SourceLocation QueuesLoc, 478 ArrayRef<Expr *> QueueIdExprs, 479 SourceLocation EndLoc); 480 481 bool hasQueuesTag() const { return !QueuesLoc.isInvalid(); } 482 SourceLocation getQueuesLoc() const { return QueuesLoc; } 483 bool hasDevNumExpr() const { return getExprs()[0]; } 484 Expr *getDevNumExpr() const { return getExprs()[0]; } 485 llvm::ArrayRef<Expr *> getQueueIdExprs() { 486 return OpenACCClauseWithExprs::getExprs().drop_front(); 487 } 488 llvm::ArrayRef<Expr *> getQueueIdExprs() const { 489 return OpenACCClauseWithExprs::getExprs().drop_front(); 490 } 491 }; 492 493 class OpenACCNumGangsClause final 494 : public OpenACCClauseWithExprs, 495 private llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> { 496 friend TrailingObjects; 497 498 OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 499 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) 500 : OpenACCClauseWithExprs(OpenACCClauseKind::NumGangs, BeginLoc, LParenLoc, 501 EndLoc) { 502 std::uninitialized_copy(IntExprs.begin(), IntExprs.end(), 503 getTrailingObjects<Expr *>()); 504 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size())); 505 } 506 507 public: 508 static bool classof(const OpenACCClause *C) { 509 return C->getClauseKind() == OpenACCClauseKind::NumGangs; 510 } 511 static OpenACCNumGangsClause * 512 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 513 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc); 514 515 llvm::ArrayRef<Expr *> getIntExprs() { 516 return OpenACCClauseWithExprs::getExprs(); 517 } 518 519 llvm::ArrayRef<Expr *> getIntExprs() const { 520 return OpenACCClauseWithExprs::getExprs(); 521 } 522 }; 523 524 class OpenACCTileClause final 525 : public OpenACCClauseWithExprs, 526 private llvm::TrailingObjects<OpenACCTileClause, Expr *> { 527 friend TrailingObjects; 528 OpenACCTileClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 529 ArrayRef<Expr *> SizeExprs, SourceLocation EndLoc) 530 : OpenACCClauseWithExprs(OpenACCClauseKind::Tile, BeginLoc, LParenLoc, 531 EndLoc) { 532 std::uninitialized_copy(SizeExprs.begin(), SizeExprs.end(), 533 getTrailingObjects<Expr *>()); 534 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), SizeExprs.size())); 535 } 536 537 public: 538 static bool classof(const OpenACCClause *C) { 539 return C->getClauseKind() == OpenACCClauseKind::Tile; 540 } 541 static OpenACCTileClause *Create(const ASTContext &C, SourceLocation BeginLoc, 542 SourceLocation LParenLoc, 543 ArrayRef<Expr *> SizeExprs, 544 SourceLocation EndLoc); 545 llvm::ArrayRef<Expr *> getSizeExprs() { 546 return OpenACCClauseWithExprs::getExprs(); 547 } 548 549 llvm::ArrayRef<Expr *> getSizeExprs() const { 550 return OpenACCClauseWithExprs::getExprs(); 551 } 552 }; 553 554 /// Represents one of a handful of clauses that have a single integer 555 /// expression. 556 class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs { 557 Expr *IntExpr; 558 559 protected: 560 OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc, 561 SourceLocation LParenLoc, Expr *IntExpr, 562 SourceLocation EndLoc) 563 : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc), 564 IntExpr(IntExpr) { 565 if (IntExpr) 566 setExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1}); 567 } 568 569 public: 570 static bool classof(const OpenACCClause *C); 571 bool hasIntExpr() const { return !getExprs().empty(); } 572 const Expr *getIntExpr() const { 573 return hasIntExpr() ? getExprs()[0] : nullptr; 574 } 575 576 Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; }; 577 }; 578 579 class OpenACCGangClause final 580 : public OpenACCClauseWithExprs, 581 private llvm::TrailingObjects<OpenACCGangClause, Expr *, OpenACCGangKind> { 582 friend TrailingObjects; 583 protected: 584 OpenACCGangClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 585 ArrayRef<OpenACCGangKind> GangKinds, 586 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc); 587 588 OpenACCGangKind getGangKind(unsigned I) const { 589 return getTrailingObjects<OpenACCGangKind>()[I]; 590 } 591 592 public: 593 static bool classof(const OpenACCClause *C) { 594 return C->getClauseKind() == OpenACCClauseKind::Gang; 595 } 596 597 size_t numTrailingObjects(OverloadToken<Expr *>) const { 598 return getNumExprs(); 599 } 600 601 unsigned getNumExprs() const { return getExprs().size(); } 602 std::pair<OpenACCGangKind, const Expr *> getExpr(unsigned I) const { 603 return {getGangKind(I), getExprs()[I]}; 604 } 605 606 bool hasExprOfKind(OpenACCGangKind GK) const { 607 for (unsigned I = 0; I < getNumExprs(); ++I) { 608 if (getGangKind(I) == GK) 609 return true; 610 } 611 return false; 612 } 613 614 static OpenACCGangClause * 615 Create(const ASTContext &Ctx, SourceLocation BeginLoc, 616 SourceLocation LParenLoc, ArrayRef<OpenACCGangKind> GangKinds, 617 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc); 618 }; 619 620 class OpenACCWorkerClause : public OpenACCClauseWithSingleIntExpr { 621 protected: 622 OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 623 Expr *IntExpr, SourceLocation EndLoc); 624 625 public: 626 static bool classof(const OpenACCClause *C) { 627 return C->getClauseKind() == OpenACCClauseKind::Worker; 628 } 629 630 static OpenACCWorkerClause *Create(const ASTContext &Ctx, 631 SourceLocation BeginLoc, 632 SourceLocation LParenLoc, Expr *IntExpr, 633 SourceLocation EndLoc); 634 }; 635 636 class OpenACCVectorClause : public OpenACCClauseWithSingleIntExpr { 637 protected: 638 OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 639 Expr *IntExpr, SourceLocation EndLoc); 640 641 public: 642 static bool classof(const OpenACCClause *C) { 643 return C->getClauseKind() == OpenACCClauseKind::Vector; 644 } 645 646 static OpenACCVectorClause *Create(const ASTContext &Ctx, 647 SourceLocation BeginLoc, 648 SourceLocation LParenLoc, Expr *IntExpr, 649 SourceLocation EndLoc); 650 }; 651 652 class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr { 653 OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 654 Expr *IntExpr, SourceLocation EndLoc); 655 656 public: 657 static bool classof(const OpenACCClause *C) { 658 return C->getClauseKind() == OpenACCClauseKind::NumWorkers; 659 } 660 static OpenACCNumWorkersClause *Create(const ASTContext &C, 661 SourceLocation BeginLoc, 662 SourceLocation LParenLoc, 663 Expr *IntExpr, SourceLocation EndLoc); 664 }; 665 666 class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr { 667 OpenACCVectorLengthClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 668 Expr *IntExpr, SourceLocation EndLoc); 669 670 public: 671 static bool classof(const OpenACCClause *C) { 672 return C->getClauseKind() == OpenACCClauseKind::VectorLength; 673 } 674 static OpenACCVectorLengthClause * 675 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 676 Expr *IntExpr, SourceLocation EndLoc); 677 }; 678 679 class OpenACCAsyncClause : public OpenACCClauseWithSingleIntExpr { 680 OpenACCAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 681 Expr *IntExpr, SourceLocation EndLoc); 682 683 public: 684 static bool classof(const OpenACCClause *C) { 685 return C->getClauseKind() == OpenACCClauseKind::Async; 686 } 687 static OpenACCAsyncClause *Create(const ASTContext &C, 688 SourceLocation BeginLoc, 689 SourceLocation LParenLoc, Expr *IntExpr, 690 SourceLocation EndLoc); 691 }; 692 693 class OpenACCDeviceNumClause : public OpenACCClauseWithSingleIntExpr { 694 OpenACCDeviceNumClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 695 Expr *IntExpr, SourceLocation EndLoc); 696 697 public: 698 static bool classof(const OpenACCClause *C) { 699 return C->getClauseKind() == OpenACCClauseKind::DeviceNum; 700 } 701 static OpenACCDeviceNumClause *Create(const ASTContext &C, 702 SourceLocation BeginLoc, 703 SourceLocation LParenLoc, Expr *IntExpr, 704 SourceLocation EndLoc); 705 }; 706 707 class OpenACCDefaultAsyncClause : public OpenACCClauseWithSingleIntExpr { 708 OpenACCDefaultAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 709 Expr *IntExpr, SourceLocation EndLoc); 710 711 public: 712 static bool classof(const OpenACCClause *C) { 713 return C->getClauseKind() == OpenACCClauseKind::DefaultAsync; 714 } 715 static OpenACCDefaultAsyncClause * 716 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 717 Expr *IntExpr, SourceLocation EndLoc); 718 }; 719 720 /// Represents a 'collapse' clause on a 'loop' construct. This clause takes an 721 /// integer constant expression 'N' that represents how deep to collapse the 722 /// construct. It also takes an optional 'force' tag that permits intervening 723 /// code in the loops. 724 class OpenACCCollapseClause : public OpenACCClauseWithSingleIntExpr { 725 bool HasForce = false; 726 727 OpenACCCollapseClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 728 bool HasForce, Expr *LoopCount, SourceLocation EndLoc); 729 730 public: 731 const Expr *getLoopCount() const { return getIntExpr(); } 732 Expr *getLoopCount() { return getIntExpr(); } 733 734 bool hasForce() const { return HasForce; } 735 736 static bool classof(const OpenACCClause *C) { 737 return C->getClauseKind() == OpenACCClauseKind::Collapse; 738 } 739 740 static OpenACCCollapseClause *Create(const ASTContext &C, 741 SourceLocation BeginLoc, 742 SourceLocation LParenLoc, bool HasForce, 743 Expr *LoopCount, SourceLocation EndLoc); 744 }; 745 746 /// Represents a clause with one or more 'var' objects, represented as an expr, 747 /// as its arguments. Var-list is expected to be stored in trailing storage. 748 /// For now, we're just storing the original expression in its entirety, unlike 749 /// OMP which has to do a bunch of work to create a private. 750 class OpenACCClauseWithVarList : public OpenACCClauseWithExprs { 751 protected: 752 OpenACCClauseWithVarList(OpenACCClauseKind K, SourceLocation BeginLoc, 753 SourceLocation LParenLoc, SourceLocation EndLoc) 754 : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {} 755 756 public: 757 static bool classof(const OpenACCClause *C); 758 ArrayRef<Expr *> getVarList() { return getExprs(); } 759 ArrayRef<Expr *> getVarList() const { return getExprs(); } 760 }; 761 762 class OpenACCPrivateClause final 763 : public OpenACCClauseWithVarList, 764 private llvm::TrailingObjects<OpenACCPrivateClause, Expr *> { 765 friend TrailingObjects; 766 767 OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 768 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 769 : OpenACCClauseWithVarList(OpenACCClauseKind::Private, BeginLoc, 770 LParenLoc, EndLoc) { 771 std::uninitialized_copy(VarList.begin(), VarList.end(), 772 getTrailingObjects<Expr *>()); 773 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 774 } 775 776 public: 777 static bool classof(const OpenACCClause *C) { 778 return C->getClauseKind() == OpenACCClauseKind::Private; 779 } 780 static OpenACCPrivateClause * 781 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 782 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 783 }; 784 785 class OpenACCFirstPrivateClause final 786 : public OpenACCClauseWithVarList, 787 private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *> { 788 friend TrailingObjects; 789 790 OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 791 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 792 : OpenACCClauseWithVarList(OpenACCClauseKind::FirstPrivate, BeginLoc, 793 LParenLoc, EndLoc) { 794 std::uninitialized_copy(VarList.begin(), VarList.end(), 795 getTrailingObjects<Expr *>()); 796 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 797 } 798 799 public: 800 static bool classof(const OpenACCClause *C) { 801 return C->getClauseKind() == OpenACCClauseKind::FirstPrivate; 802 } 803 static OpenACCFirstPrivateClause * 804 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 805 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 806 }; 807 808 class OpenACCDevicePtrClause final 809 : public OpenACCClauseWithVarList, 810 private llvm::TrailingObjects<OpenACCDevicePtrClause, Expr *> { 811 friend TrailingObjects; 812 813 OpenACCDevicePtrClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 814 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 815 : OpenACCClauseWithVarList(OpenACCClauseKind::DevicePtr, BeginLoc, 816 LParenLoc, EndLoc) { 817 std::uninitialized_copy(VarList.begin(), VarList.end(), 818 getTrailingObjects<Expr *>()); 819 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 820 } 821 822 public: 823 static bool classof(const OpenACCClause *C) { 824 return C->getClauseKind() == OpenACCClauseKind::DevicePtr; 825 } 826 static OpenACCDevicePtrClause * 827 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 828 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 829 }; 830 831 class OpenACCAttachClause final 832 : public OpenACCClauseWithVarList, 833 private llvm::TrailingObjects<OpenACCAttachClause, Expr *> { 834 friend TrailingObjects; 835 836 OpenACCAttachClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 837 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 838 : OpenACCClauseWithVarList(OpenACCClauseKind::Attach, BeginLoc, LParenLoc, 839 EndLoc) { 840 std::uninitialized_copy(VarList.begin(), VarList.end(), 841 getTrailingObjects<Expr *>()); 842 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 843 } 844 845 public: 846 static bool classof(const OpenACCClause *C) { 847 return C->getClauseKind() == OpenACCClauseKind::Attach; 848 } 849 static OpenACCAttachClause * 850 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 851 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 852 }; 853 854 class OpenACCDetachClause final 855 : public OpenACCClauseWithVarList, 856 private llvm::TrailingObjects<OpenACCDetachClause, Expr *> { 857 friend TrailingObjects; 858 859 OpenACCDetachClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 860 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 861 : OpenACCClauseWithVarList(OpenACCClauseKind::Detach, BeginLoc, LParenLoc, 862 EndLoc) { 863 std::uninitialized_copy(VarList.begin(), VarList.end(), 864 getTrailingObjects<Expr *>()); 865 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 866 } 867 868 public: 869 static bool classof(const OpenACCClause *C) { 870 return C->getClauseKind() == OpenACCClauseKind::Detach; 871 } 872 static OpenACCDetachClause * 873 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 874 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 875 }; 876 877 class OpenACCDeleteClause final 878 : public OpenACCClauseWithVarList, 879 private llvm::TrailingObjects<OpenACCDeleteClause, Expr *> { 880 friend TrailingObjects; 881 882 OpenACCDeleteClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 883 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 884 : OpenACCClauseWithVarList(OpenACCClauseKind::Delete, BeginLoc, LParenLoc, 885 EndLoc) { 886 std::uninitialized_copy(VarList.begin(), VarList.end(), 887 getTrailingObjects<Expr *>()); 888 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 889 } 890 891 public: 892 static bool classof(const OpenACCClause *C) { 893 return C->getClauseKind() == OpenACCClauseKind::Delete; 894 } 895 static OpenACCDeleteClause * 896 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 897 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 898 }; 899 900 class OpenACCUseDeviceClause final 901 : public OpenACCClauseWithVarList, 902 private llvm::TrailingObjects<OpenACCUseDeviceClause, Expr *> { 903 friend TrailingObjects; 904 905 OpenACCUseDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 906 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 907 : OpenACCClauseWithVarList(OpenACCClauseKind::UseDevice, BeginLoc, 908 LParenLoc, EndLoc) { 909 std::uninitialized_copy(VarList.begin(), VarList.end(), 910 getTrailingObjects<Expr *>()); 911 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 912 } 913 914 public: 915 static bool classof(const OpenACCClause *C) { 916 return C->getClauseKind() == OpenACCClauseKind::UseDevice; 917 } 918 static OpenACCUseDeviceClause * 919 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 920 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 921 }; 922 923 class OpenACCNoCreateClause final 924 : public OpenACCClauseWithVarList, 925 private llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> { 926 friend TrailingObjects; 927 928 OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 929 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 930 : OpenACCClauseWithVarList(OpenACCClauseKind::NoCreate, BeginLoc, 931 LParenLoc, EndLoc) { 932 std::uninitialized_copy(VarList.begin(), VarList.end(), 933 getTrailingObjects<Expr *>()); 934 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 935 } 936 937 public: 938 static bool classof(const OpenACCClause *C) { 939 return C->getClauseKind() == OpenACCClauseKind::NoCreate; 940 } 941 static OpenACCNoCreateClause * 942 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 943 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 944 }; 945 946 class OpenACCPresentClause final 947 : public OpenACCClauseWithVarList, 948 private llvm::TrailingObjects<OpenACCPresentClause, Expr *> { 949 friend TrailingObjects; 950 951 OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 952 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 953 : OpenACCClauseWithVarList(OpenACCClauseKind::Present, BeginLoc, 954 LParenLoc, EndLoc) { 955 std::uninitialized_copy(VarList.begin(), VarList.end(), 956 getTrailingObjects<Expr *>()); 957 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 958 } 959 960 public: 961 static bool classof(const OpenACCClause *C) { 962 return C->getClauseKind() == OpenACCClauseKind::Present; 963 } 964 static OpenACCPresentClause * 965 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 966 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 967 }; 968 class OpenACCHostClause final 969 : public OpenACCClauseWithVarList, 970 private llvm::TrailingObjects<OpenACCHostClause, Expr *> { 971 friend TrailingObjects; 972 973 OpenACCHostClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 974 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 975 : OpenACCClauseWithVarList(OpenACCClauseKind::Host, BeginLoc, LParenLoc, 976 EndLoc) { 977 std::uninitialized_copy(VarList.begin(), VarList.end(), 978 getTrailingObjects<Expr *>()); 979 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 980 } 981 982 public: 983 static bool classof(const OpenACCClause *C) { 984 return C->getClauseKind() == OpenACCClauseKind::Host; 985 } 986 static OpenACCHostClause *Create(const ASTContext &C, SourceLocation BeginLoc, 987 SourceLocation LParenLoc, 988 ArrayRef<Expr *> VarList, 989 SourceLocation EndLoc); 990 }; 991 992 class OpenACCDeviceClause final 993 : public OpenACCClauseWithVarList, 994 private llvm::TrailingObjects<OpenACCDeviceClause, Expr *> { 995 friend TrailingObjects; 996 997 OpenACCDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 998 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 999 : OpenACCClauseWithVarList(OpenACCClauseKind::Device, BeginLoc, LParenLoc, 1000 EndLoc) { 1001 std::uninitialized_copy(VarList.begin(), VarList.end(), 1002 getTrailingObjects<Expr *>()); 1003 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 1004 } 1005 1006 public: 1007 static bool classof(const OpenACCClause *C) { 1008 return C->getClauseKind() == OpenACCClauseKind::Device; 1009 } 1010 static OpenACCDeviceClause * 1011 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 1012 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 1013 }; 1014 1015 class OpenACCCopyClause final 1016 : public OpenACCClauseWithVarList, 1017 private llvm::TrailingObjects<OpenACCCopyClause, Expr *> { 1018 friend TrailingObjects; 1019 1020 OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, 1021 SourceLocation LParenLoc, ArrayRef<Expr *> VarList, 1022 SourceLocation EndLoc) 1023 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc) { 1024 assert((Spelling == OpenACCClauseKind::Copy || 1025 Spelling == OpenACCClauseKind::PCopy || 1026 Spelling == OpenACCClauseKind::PresentOrCopy) && 1027 "Invalid clause kind for copy-clause"); 1028 std::uninitialized_copy(VarList.begin(), VarList.end(), 1029 getTrailingObjects<Expr *>()); 1030 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 1031 } 1032 1033 public: 1034 static bool classof(const OpenACCClause *C) { 1035 return C->getClauseKind() == OpenACCClauseKind::Copy || 1036 C->getClauseKind() == OpenACCClauseKind::PCopy || 1037 C->getClauseKind() == OpenACCClauseKind::PresentOrCopy; 1038 } 1039 static OpenACCCopyClause * 1040 Create(const ASTContext &C, OpenACCClauseKind Spelling, 1041 SourceLocation BeginLoc, SourceLocation LParenLoc, 1042 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 1043 }; 1044 1045 class OpenACCCopyInClause final 1046 : public OpenACCClauseWithVarList, 1047 private llvm::TrailingObjects<OpenACCCopyInClause, Expr *> { 1048 friend TrailingObjects; 1049 bool IsReadOnly; 1050 1051 OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, 1052 SourceLocation LParenLoc, bool IsReadOnly, 1053 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 1054 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), 1055 IsReadOnly(IsReadOnly) { 1056 assert((Spelling == OpenACCClauseKind::CopyIn || 1057 Spelling == OpenACCClauseKind::PCopyIn || 1058 Spelling == OpenACCClauseKind::PresentOrCopyIn) && 1059 "Invalid clause kind for copyin-clause"); 1060 std::uninitialized_copy(VarList.begin(), VarList.end(), 1061 getTrailingObjects<Expr *>()); 1062 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 1063 } 1064 1065 public: 1066 static bool classof(const OpenACCClause *C) { 1067 return C->getClauseKind() == OpenACCClauseKind::CopyIn || 1068 C->getClauseKind() == OpenACCClauseKind::PCopyIn || 1069 C->getClauseKind() == OpenACCClauseKind::PresentOrCopyIn; 1070 } 1071 bool isReadOnly() const { return IsReadOnly; } 1072 static OpenACCCopyInClause * 1073 Create(const ASTContext &C, OpenACCClauseKind Spelling, 1074 SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, 1075 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 1076 }; 1077 1078 class OpenACCCopyOutClause final 1079 : public OpenACCClauseWithVarList, 1080 private llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> { 1081 friend TrailingObjects; 1082 bool IsZero; 1083 1084 OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, 1085 SourceLocation LParenLoc, bool IsZero, 1086 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 1087 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), 1088 IsZero(IsZero) { 1089 assert((Spelling == OpenACCClauseKind::CopyOut || 1090 Spelling == OpenACCClauseKind::PCopyOut || 1091 Spelling == OpenACCClauseKind::PresentOrCopyOut) && 1092 "Invalid clause kind for copyout-clause"); 1093 std::uninitialized_copy(VarList.begin(), VarList.end(), 1094 getTrailingObjects<Expr *>()); 1095 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 1096 } 1097 1098 public: 1099 static bool classof(const OpenACCClause *C) { 1100 return C->getClauseKind() == OpenACCClauseKind::CopyOut || 1101 C->getClauseKind() == OpenACCClauseKind::PCopyOut || 1102 C->getClauseKind() == OpenACCClauseKind::PresentOrCopyOut; 1103 } 1104 bool isZero() const { return IsZero; } 1105 static OpenACCCopyOutClause * 1106 Create(const ASTContext &C, OpenACCClauseKind Spelling, 1107 SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, 1108 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 1109 }; 1110 1111 class OpenACCCreateClause final 1112 : public OpenACCClauseWithVarList, 1113 private llvm::TrailingObjects<OpenACCCreateClause, Expr *> { 1114 friend TrailingObjects; 1115 bool IsZero; 1116 1117 OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, 1118 SourceLocation LParenLoc, bool IsZero, 1119 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 1120 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), 1121 IsZero(IsZero) { 1122 assert((Spelling == OpenACCClauseKind::Create || 1123 Spelling == OpenACCClauseKind::PCreate || 1124 Spelling == OpenACCClauseKind::PresentOrCreate) && 1125 "Invalid clause kind for create-clause"); 1126 std::uninitialized_copy(VarList.begin(), VarList.end(), 1127 getTrailingObjects<Expr *>()); 1128 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 1129 } 1130 1131 public: 1132 static bool classof(const OpenACCClause *C) { 1133 return C->getClauseKind() == OpenACCClauseKind::Create || 1134 C->getClauseKind() == OpenACCClauseKind::PCreate || 1135 C->getClauseKind() == OpenACCClauseKind::PresentOrCreate; 1136 } 1137 bool isZero() const { return IsZero; } 1138 static OpenACCCreateClause * 1139 Create(const ASTContext &C, OpenACCClauseKind Spelling, 1140 SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, 1141 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 1142 }; 1143 1144 class OpenACCReductionClause final 1145 : public OpenACCClauseWithVarList, 1146 private llvm::TrailingObjects<OpenACCReductionClause, Expr *> { 1147 friend TrailingObjects; 1148 OpenACCReductionOperator Op; 1149 1150 OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 1151 OpenACCReductionOperator Operator, 1152 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 1153 : OpenACCClauseWithVarList(OpenACCClauseKind::Reduction, BeginLoc, 1154 LParenLoc, EndLoc), 1155 Op(Operator) { 1156 std::uninitialized_copy(VarList.begin(), VarList.end(), 1157 getTrailingObjects<Expr *>()); 1158 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 1159 } 1160 1161 public: 1162 static bool classof(const OpenACCClause *C) { 1163 return C->getClauseKind() == OpenACCClauseKind::Reduction; 1164 } 1165 1166 static OpenACCReductionClause * 1167 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 1168 OpenACCReductionOperator Operator, ArrayRef<Expr *> VarList, 1169 SourceLocation EndLoc); 1170 1171 OpenACCReductionOperator getReductionOp() const { return Op; } 1172 }; 1173 1174 template <class Impl> class OpenACCClauseVisitor { 1175 Impl &getDerived() { return static_cast<Impl &>(*this); } 1176 1177 public: 1178 void VisitClauseList(ArrayRef<const OpenACCClause *> List) { 1179 for (const OpenACCClause *Clause : List) 1180 Visit(Clause); 1181 } 1182 1183 void Visit(const OpenACCClause *C) { 1184 if (!C) 1185 return; 1186 1187 switch (C->getClauseKind()) { 1188 #define VISIT_CLAUSE(CLAUSE_NAME) \ 1189 case OpenACCClauseKind::CLAUSE_NAME: \ 1190 Visit##CLAUSE_NAME##Clause(*cast<OpenACC##CLAUSE_NAME##Clause>(C)); \ 1191 return; 1192 #define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \ 1193 case OpenACCClauseKind::ALIAS_NAME: \ 1194 Visit##CLAUSE_NAME##Clause(*cast<OpenACC##CLAUSE_NAME##Clause>(C)); \ 1195 return; 1196 #include "clang/Basic/OpenACCClauses.def" 1197 1198 default: 1199 llvm_unreachable("Clause visitor not yet implemented"); 1200 } 1201 llvm_unreachable("Invalid Clause kind"); 1202 } 1203 1204 #define VISIT_CLAUSE(CLAUSE_NAME) \ 1205 void Visit##CLAUSE_NAME##Clause( \ 1206 const OpenACC##CLAUSE_NAME##Clause &Clause) { \ 1207 return getDerived().Visit##CLAUSE_NAME##Clause(Clause); \ 1208 } 1209 1210 #include "clang/Basic/OpenACCClauses.def" 1211 }; 1212 1213 class OpenACCClausePrinter final 1214 : public OpenACCClauseVisitor<OpenACCClausePrinter> { 1215 raw_ostream &OS; 1216 const PrintingPolicy &Policy; 1217 1218 void printExpr(const Expr *E); 1219 1220 public: 1221 void VisitClauseList(ArrayRef<const OpenACCClause *> List) { 1222 for (const OpenACCClause *Clause : List) { 1223 Visit(Clause); 1224 1225 if (Clause != List.back()) 1226 OS << ' '; 1227 } 1228 } 1229 OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) 1230 : OS(OS), Policy(Policy) {} 1231 1232 #define VISIT_CLAUSE(CLAUSE_NAME) \ 1233 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause); 1234 #include "clang/Basic/OpenACCClauses.def" 1235 }; 1236 1237 } // namespace clang 1238 1239 #endif // LLVM_CLANG_AST_OPENACCCLAUSE_H 1240