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