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: OpenACCClause(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation EndLoc)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: getClauseKind()37 OpenACCClauseKind getClauseKind() const { return Kind; } getBeginLoc()38 SourceLocation getBeginLoc() const { return Location.getBegin(); } getEndLoc()39 SourceLocation getEndLoc() const { return Location.getEnd(); } 40 classof(const OpenACCClause *)41 static bool classof(const OpenACCClause *) { return false; } 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(); 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: OpenACCAutoClause(SourceLocation BeginLoc,SourceLocation EndLoc)60 OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc) 61 : OpenACCClause(OpenACCClauseKind::Auto, BeginLoc, EndLoc) {} 62 63 public: classof(const OpenACCClause * C)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 children()71 child_range children() { 72 return child_range(child_iterator(), child_iterator()); 73 } children()74 const_child_range children() const { 75 return const_child_range(const_child_iterator(), const_child_iterator()); 76 } 77 }; 78 79 // Represents the 'independent' clause. 80 class OpenACCIndependentClause : public OpenACCClause { 81 protected: OpenACCIndependentClause(SourceLocation BeginLoc,SourceLocation EndLoc)82 OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc) 83 : OpenACCClause(OpenACCClauseKind::Independent, BeginLoc, EndLoc) {} 84 85 public: classof(const OpenACCClause * C)86 static bool classof(const OpenACCClause *C) { 87 return C->getClauseKind() == OpenACCClauseKind::Independent; 88 } 89 90 static OpenACCIndependentClause * 91 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 92 children()93 child_range children() { 94 return child_range(child_iterator(), child_iterator()); 95 } children()96 const_child_range children() const { 97 return const_child_range(const_child_iterator(), const_child_iterator()); 98 } 99 }; 100 // Represents the 'seq' clause. 101 class OpenACCSeqClause : public OpenACCClause { 102 protected: OpenACCSeqClause(SourceLocation BeginLoc,SourceLocation EndLoc)103 OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc) 104 : OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {} 105 106 public: classof(const OpenACCClause * C)107 static bool classof(const OpenACCClause *C) { 108 return C->getClauseKind() == OpenACCClauseKind::Seq; 109 } 110 111 static OpenACCSeqClause * 112 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 113 children()114 child_range children() { 115 return child_range(child_iterator(), child_iterator()); 116 } children()117 const_child_range children() const { 118 return const_child_range(const_child_iterator(), const_child_iterator()); 119 } 120 }; 121 122 // Not yet implemented, but the type name is necessary for 'seq' diagnostics, so 123 // this provides a basic, do-nothing implementation. We still need to add this 124 // type to the visitors/etc, as well as get it to take its proper arguments. 125 class OpenACCGangClause : public OpenACCClause { 126 protected: OpenACCGangClause(SourceLocation BeginLoc,SourceLocation EndLoc)127 OpenACCGangClause(SourceLocation BeginLoc, SourceLocation EndLoc) 128 : OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) { 129 llvm_unreachable("Not yet implemented"); 130 } 131 132 public: classof(const OpenACCClause * C)133 static bool classof(const OpenACCClause *C) { 134 return C->getClauseKind() == OpenACCClauseKind::Gang; 135 } 136 137 static OpenACCGangClause * 138 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 139 children()140 child_range children() { 141 return child_range(child_iterator(), child_iterator()); 142 } children()143 const_child_range children() const { 144 return const_child_range(const_child_iterator(), const_child_iterator()); 145 } 146 }; 147 148 // Not yet implemented, but the type name is necessary for 'seq' diagnostics, so 149 // this provides a basic, do-nothing implementation. We still need to add this 150 // type to the visitors/etc, as well as get it to take its proper arguments. 151 class OpenACCVectorClause : public OpenACCClause { 152 protected: OpenACCVectorClause(SourceLocation BeginLoc,SourceLocation EndLoc)153 OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation EndLoc) 154 : OpenACCClause(OpenACCClauseKind::Vector, BeginLoc, EndLoc) { 155 llvm_unreachable("Not yet implemented"); 156 } 157 158 public: classof(const OpenACCClause * C)159 static bool classof(const OpenACCClause *C) { 160 return C->getClauseKind() == OpenACCClauseKind::Gang; 161 } 162 163 static OpenACCVectorClause * 164 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 165 children()166 child_range children() { 167 return child_range(child_iterator(), child_iterator()); 168 } children()169 const_child_range children() const { 170 return const_child_range(const_child_iterator(), const_child_iterator()); 171 } 172 }; 173 174 // Not yet implemented, but the type name is necessary for 'seq' diagnostics, so 175 // this provides a basic, do-nothing implementation. We still need to add this 176 // type to the visitors/etc, as well as get it to take its proper arguments. 177 class OpenACCWorkerClause : public OpenACCClause { 178 protected: OpenACCWorkerClause(SourceLocation BeginLoc,SourceLocation EndLoc)179 OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation EndLoc) 180 : OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) { 181 llvm_unreachable("Not yet implemented"); 182 } 183 184 public: classof(const OpenACCClause * C)185 static bool classof(const OpenACCClause *C) { 186 return C->getClauseKind() == OpenACCClauseKind::Gang; 187 } 188 189 static OpenACCWorkerClause * 190 Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); 191 children()192 child_range children() { 193 return child_range(child_iterator(), child_iterator()); 194 } children()195 const_child_range children() const { 196 return const_child_range(const_child_iterator(), const_child_iterator()); 197 } 198 }; 199 200 /// Represents a clause that has a list of parameters. 201 class OpenACCClauseWithParams : public OpenACCClause { 202 /// Location of the '('. 203 SourceLocation LParenLoc; 204 205 protected: OpenACCClauseWithParams(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,SourceLocation EndLoc)206 OpenACCClauseWithParams(OpenACCClauseKind K, SourceLocation BeginLoc, 207 SourceLocation LParenLoc, SourceLocation EndLoc) 208 : OpenACCClause(K, BeginLoc, EndLoc), LParenLoc(LParenLoc) {} 209 210 public: 211 static bool classof(const OpenACCClause *C); 212 getLParenLoc()213 SourceLocation getLParenLoc() const { return LParenLoc; } 214 children()215 child_range children() { 216 return child_range(child_iterator(), child_iterator()); 217 } children()218 const_child_range children() const { 219 return const_child_range(const_child_iterator(), const_child_iterator()); 220 } 221 }; 222 223 using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>; 224 /// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or 225 /// an identifier. The 'asterisk' means 'the rest'. 226 class OpenACCDeviceTypeClause final 227 : public OpenACCClauseWithParams, 228 public llvm::TrailingObjects<OpenACCDeviceTypeClause, 229 DeviceTypeArgument> { 230 // Data stored in trailing objects as IdentifierInfo* /SourceLocation pairs. A 231 // nullptr IdentifierInfo* represents an asterisk. 232 unsigned NumArchs; OpenACCDeviceTypeClause(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<DeviceTypeArgument> Archs,SourceLocation EndLoc)233 OpenACCDeviceTypeClause(OpenACCClauseKind K, SourceLocation BeginLoc, 234 SourceLocation LParenLoc, 235 ArrayRef<DeviceTypeArgument> Archs, 236 SourceLocation EndLoc) 237 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc), 238 NumArchs(Archs.size()) { 239 assert( 240 (K == OpenACCClauseKind::DeviceType || K == OpenACCClauseKind::DType) && 241 "Invalid clause kind for device-type"); 242 243 assert(!llvm::any_of(Archs, [](const DeviceTypeArgument &Arg) { 244 return Arg.second.isInvalid(); 245 }) && "Invalid SourceLocation for an argument"); 246 247 assert( 248 (Archs.size() == 1 || !llvm::any_of(Archs, 249 [](const DeviceTypeArgument &Arg) { 250 return Arg.first == nullptr; 251 })) && 252 "Only a single asterisk version is permitted, and must be the " 253 "only one"); 254 255 std::uninitialized_copy(Archs.begin(), Archs.end(), 256 getTrailingObjects<DeviceTypeArgument>()); 257 } 258 259 public: classof(const OpenACCClause * C)260 static bool classof(const OpenACCClause *C) { 261 return C->getClauseKind() == OpenACCClauseKind::DType || 262 C->getClauseKind() == OpenACCClauseKind::DeviceType; 263 } hasAsterisk()264 bool hasAsterisk() const { 265 return getArchitectures().size() > 0 && 266 getArchitectures()[0].first == nullptr; 267 } 268 getArchitectures()269 ArrayRef<DeviceTypeArgument> getArchitectures() const { 270 return ArrayRef<DeviceTypeArgument>( 271 getTrailingObjects<DeviceTypeArgument>(), NumArchs); 272 } 273 274 static OpenACCDeviceTypeClause * 275 Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, 276 SourceLocation LParenLoc, ArrayRef<DeviceTypeArgument> Archs, 277 SourceLocation EndLoc); 278 }; 279 280 /// A 'default' clause, has the optional 'none' or 'present' argument. 281 class OpenACCDefaultClause : public OpenACCClauseWithParams { 282 friend class ASTReaderStmt; 283 friend class ASTWriterStmt; 284 285 OpenACCDefaultClauseKind DefaultClauseKind; 286 287 protected: OpenACCDefaultClause(OpenACCDefaultClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,SourceLocation EndLoc)288 OpenACCDefaultClause(OpenACCDefaultClauseKind K, SourceLocation BeginLoc, 289 SourceLocation LParenLoc, SourceLocation EndLoc) 290 : OpenACCClauseWithParams(OpenACCClauseKind::Default, BeginLoc, LParenLoc, 291 EndLoc), 292 DefaultClauseKind(K) { 293 assert((DefaultClauseKind == OpenACCDefaultClauseKind::None || 294 DefaultClauseKind == OpenACCDefaultClauseKind::Present) && 295 "Invalid Clause Kind"); 296 } 297 298 public: classof(const OpenACCClause * C)299 static bool classof(const OpenACCClause *C) { 300 return C->getClauseKind() == OpenACCClauseKind::Default; 301 } getDefaultClauseKind()302 OpenACCDefaultClauseKind getDefaultClauseKind() const { 303 return DefaultClauseKind; 304 } 305 306 static OpenACCDefaultClause *Create(const ASTContext &C, 307 OpenACCDefaultClauseKind K, 308 SourceLocation BeginLoc, 309 SourceLocation LParenLoc, 310 SourceLocation EndLoc); 311 }; 312 313 /// Represents one of the handful of classes that has an optional/required 314 /// 'condition' expression as an argument. 315 class OpenACCClauseWithCondition : public OpenACCClauseWithParams { 316 Expr *ConditionExpr = nullptr; 317 318 protected: OpenACCClauseWithCondition(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,Expr * ConditionExpr,SourceLocation EndLoc)319 OpenACCClauseWithCondition(OpenACCClauseKind K, SourceLocation BeginLoc, 320 SourceLocation LParenLoc, Expr *ConditionExpr, 321 SourceLocation EndLoc) 322 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc), 323 ConditionExpr(ConditionExpr) {} 324 325 public: 326 static bool classof(const OpenACCClause *C); 327 hasConditionExpr()328 bool hasConditionExpr() const { return ConditionExpr; } getConditionExpr()329 const Expr *getConditionExpr() const { return ConditionExpr; } getConditionExpr()330 Expr *getConditionExpr() { return ConditionExpr; } 331 children()332 child_range children() { 333 if (ConditionExpr) 334 return child_range(reinterpret_cast<Stmt **>(&ConditionExpr), 335 reinterpret_cast<Stmt **>(&ConditionExpr + 1)); 336 return child_range(child_iterator(), child_iterator()); 337 } 338 children()339 const_child_range children() const { 340 if (ConditionExpr) 341 return const_child_range( 342 reinterpret_cast<Stmt *const *>(&ConditionExpr), 343 reinterpret_cast<Stmt *const *>(&ConditionExpr + 1)); 344 return const_child_range(const_child_iterator(), const_child_iterator()); 345 } 346 }; 347 348 /// An 'if' clause, which has a required condition expression. 349 class OpenACCIfClause : public OpenACCClauseWithCondition { 350 protected: 351 OpenACCIfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 352 Expr *ConditionExpr, SourceLocation EndLoc); 353 354 public: classof(const OpenACCClause * C)355 static bool classof(const OpenACCClause *C) { 356 return C->getClauseKind() == OpenACCClauseKind::If; 357 } 358 static OpenACCIfClause *Create(const ASTContext &C, SourceLocation BeginLoc, 359 SourceLocation LParenLoc, Expr *ConditionExpr, 360 SourceLocation EndLoc); 361 }; 362 363 /// A 'self' clause, which has an optional condition expression. 364 class OpenACCSelfClause : public OpenACCClauseWithCondition { 365 OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 366 Expr *ConditionExpr, SourceLocation EndLoc); 367 368 public: classof(const OpenACCClause * C)369 static bool classof(const OpenACCClause *C) { 370 return C->getClauseKind() == OpenACCClauseKind::Self; 371 } 372 static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc, 373 SourceLocation LParenLoc, 374 Expr *ConditionExpr, SourceLocation EndLoc); 375 }; 376 377 /// Represents a clause that has one or more expressions associated with it. 378 class OpenACCClauseWithExprs : public OpenACCClauseWithParams { 379 MutableArrayRef<Expr *> Exprs; 380 381 protected: OpenACCClauseWithExprs(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,SourceLocation EndLoc)382 OpenACCClauseWithExprs(OpenACCClauseKind K, SourceLocation BeginLoc, 383 SourceLocation LParenLoc, SourceLocation EndLoc) 384 : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {} 385 386 /// Used only for initialization, the leaf class can initialize this to 387 /// trailing storage. setExprs(MutableArrayRef<Expr * > NewExprs)388 void setExprs(MutableArrayRef<Expr *> NewExprs) { 389 assert(Exprs.empty() && "Cannot change Exprs list"); 390 Exprs = NewExprs; 391 } 392 393 /// Gets the entire list of expressions, but leave it to the 394 /// individual clauses to expose this how they'd like. getExprs()395 llvm::ArrayRef<Expr *> getExprs() const { return Exprs; } 396 397 public: 398 static bool classof(const OpenACCClause *C); children()399 child_range children() { 400 return child_range(reinterpret_cast<Stmt **>(Exprs.begin()), 401 reinterpret_cast<Stmt **>(Exprs.end())); 402 } 403 children()404 const_child_range children() const { 405 child_range Children = 406 const_cast<OpenACCClauseWithExprs *>(this)->children(); 407 return const_child_range(Children.begin(), Children.end()); 408 } 409 }; 410 411 // Represents the 'devnum' and expressions lists for the 'wait' clause. 412 class OpenACCWaitClause final 413 : public OpenACCClauseWithExprs, 414 public llvm::TrailingObjects<OpenACCWaitClause, Expr *> { 415 SourceLocation QueuesLoc; OpenACCWaitClause(SourceLocation BeginLoc,SourceLocation LParenLoc,Expr * DevNumExpr,SourceLocation QueuesLoc,ArrayRef<Expr * > QueueIdExprs,SourceLocation EndLoc)416 OpenACCWaitClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 417 Expr *DevNumExpr, SourceLocation QueuesLoc, 418 ArrayRef<Expr *> QueueIdExprs, SourceLocation EndLoc) 419 : OpenACCClauseWithExprs(OpenACCClauseKind::Wait, BeginLoc, LParenLoc, 420 EndLoc), 421 QueuesLoc(QueuesLoc) { 422 // The first element of the trailing storage is always the devnum expr, 423 // whether it is used or not. 424 std::uninitialized_copy(&DevNumExpr, &DevNumExpr + 1, 425 getTrailingObjects<Expr *>()); 426 std::uninitialized_copy(QueueIdExprs.begin(), QueueIdExprs.end(), 427 getTrailingObjects<Expr *>() + 1); 428 setExprs( 429 MutableArrayRef(getTrailingObjects<Expr *>(), QueueIdExprs.size() + 1)); 430 } 431 432 public: classof(const OpenACCClause * C)433 static bool classof(const OpenACCClause *C) { 434 return C->getClauseKind() == OpenACCClauseKind::Wait; 435 } 436 static OpenACCWaitClause *Create(const ASTContext &C, SourceLocation BeginLoc, 437 SourceLocation LParenLoc, Expr *DevNumExpr, 438 SourceLocation QueuesLoc, 439 ArrayRef<Expr *> QueueIdExprs, 440 SourceLocation EndLoc); 441 hasQueuesTag()442 bool hasQueuesTag() const { return !QueuesLoc.isInvalid(); } getQueuesLoc()443 SourceLocation getQueuesLoc() const { return QueuesLoc; } hasDevNumExpr()444 bool hasDevNumExpr() const { return getExprs()[0]; } getDevNumExpr()445 Expr *getDevNumExpr() const { return getExprs()[0]; } getQueueIdExprs()446 llvm::ArrayRef<Expr *> getQueueIdExprs() { 447 return OpenACCClauseWithExprs::getExprs().drop_front(); 448 } getQueueIdExprs()449 llvm::ArrayRef<Expr *> getQueueIdExprs() const { 450 return OpenACCClauseWithExprs::getExprs().drop_front(); 451 } 452 }; 453 454 class OpenACCNumGangsClause final 455 : public OpenACCClauseWithExprs, 456 public llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> { 457 OpenACCNumGangsClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > IntExprs,SourceLocation EndLoc)458 OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 459 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) 460 : OpenACCClauseWithExprs(OpenACCClauseKind::NumGangs, BeginLoc, LParenLoc, 461 EndLoc) { 462 std::uninitialized_copy(IntExprs.begin(), IntExprs.end(), 463 getTrailingObjects<Expr *>()); 464 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size())); 465 } 466 467 public: classof(const OpenACCClause * C)468 static bool classof(const OpenACCClause *C) { 469 return C->getClauseKind() == OpenACCClauseKind::NumGangs; 470 } 471 static OpenACCNumGangsClause * 472 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 473 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc); 474 getIntExprs()475 llvm::ArrayRef<Expr *> getIntExprs() { 476 return OpenACCClauseWithExprs::getExprs(); 477 } 478 getIntExprs()479 llvm::ArrayRef<Expr *> getIntExprs() const { 480 return OpenACCClauseWithExprs::getExprs(); 481 } 482 }; 483 484 /// Represents one of a handful of clauses that have a single integer 485 /// expression. 486 class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs { 487 Expr *IntExpr; 488 489 protected: OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,Expr * IntExpr,SourceLocation EndLoc)490 OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc, 491 SourceLocation LParenLoc, Expr *IntExpr, 492 SourceLocation EndLoc) 493 : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc), 494 IntExpr(IntExpr) { 495 if (IntExpr) 496 setExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1}); 497 } 498 499 public: 500 static bool classof(const OpenACCClause *C); hasIntExpr()501 bool hasIntExpr() const { return !getExprs().empty(); } getIntExpr()502 const Expr *getIntExpr() const { 503 return hasIntExpr() ? getExprs()[0] : nullptr; 504 } 505 getIntExpr()506 Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; }; 507 }; 508 509 class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr { 510 OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 511 Expr *IntExpr, SourceLocation EndLoc); 512 513 public: classof(const OpenACCClause * C)514 static bool classof(const OpenACCClause *C) { 515 return C->getClauseKind() == OpenACCClauseKind::NumWorkers; 516 } 517 static OpenACCNumWorkersClause *Create(const ASTContext &C, 518 SourceLocation BeginLoc, 519 SourceLocation LParenLoc, 520 Expr *IntExpr, SourceLocation EndLoc); 521 }; 522 523 class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr { 524 OpenACCVectorLengthClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 525 Expr *IntExpr, SourceLocation EndLoc); 526 527 public: classof(const OpenACCClause * C)528 static bool classof(const OpenACCClause *C) { 529 return C->getClauseKind() == OpenACCClauseKind::VectorLength; 530 } 531 static OpenACCVectorLengthClause * 532 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 533 Expr *IntExpr, SourceLocation EndLoc); 534 }; 535 536 class OpenACCAsyncClause : public OpenACCClauseWithSingleIntExpr { 537 OpenACCAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 538 Expr *IntExpr, SourceLocation EndLoc); 539 540 public: classof(const OpenACCClause * C)541 static bool classof(const OpenACCClause *C) { 542 return C->getClauseKind() == OpenACCClauseKind::Async; 543 } 544 static OpenACCAsyncClause *Create(const ASTContext &C, 545 SourceLocation BeginLoc, 546 SourceLocation LParenLoc, Expr *IntExpr, 547 SourceLocation EndLoc); 548 }; 549 550 /// Represents a clause with one or more 'var' objects, represented as an expr, 551 /// as its arguments. Var-list is expected to be stored in trailing storage. 552 /// For now, we're just storing the original expression in its entirety, unlike 553 /// OMP which has to do a bunch of work to create a private. 554 class OpenACCClauseWithVarList : public OpenACCClauseWithExprs { 555 protected: OpenACCClauseWithVarList(OpenACCClauseKind K,SourceLocation BeginLoc,SourceLocation LParenLoc,SourceLocation EndLoc)556 OpenACCClauseWithVarList(OpenACCClauseKind K, SourceLocation BeginLoc, 557 SourceLocation LParenLoc, SourceLocation EndLoc) 558 : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {} 559 560 public: 561 static bool classof(const OpenACCClause *C); getVarList()562 ArrayRef<Expr *> getVarList() { return getExprs(); } getVarList()563 ArrayRef<Expr *> getVarList() const { return getExprs(); } 564 }; 565 566 class OpenACCPrivateClause final 567 : public OpenACCClauseWithVarList, 568 public llvm::TrailingObjects<OpenACCPrivateClause, Expr *> { 569 OpenACCPrivateClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)570 OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 571 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 572 : OpenACCClauseWithVarList(OpenACCClauseKind::Private, BeginLoc, 573 LParenLoc, EndLoc) { 574 std::uninitialized_copy(VarList.begin(), VarList.end(), 575 getTrailingObjects<Expr *>()); 576 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 577 } 578 579 public: classof(const OpenACCClause * C)580 static bool classof(const OpenACCClause *C) { 581 return C->getClauseKind() == OpenACCClauseKind::Private; 582 } 583 static OpenACCPrivateClause * 584 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 585 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 586 }; 587 588 class OpenACCFirstPrivateClause final 589 : public OpenACCClauseWithVarList, 590 public llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *> { 591 OpenACCFirstPrivateClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)592 OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 593 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 594 : OpenACCClauseWithVarList(OpenACCClauseKind::FirstPrivate, BeginLoc, 595 LParenLoc, EndLoc) { 596 std::uninitialized_copy(VarList.begin(), VarList.end(), 597 getTrailingObjects<Expr *>()); 598 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 599 } 600 601 public: classof(const OpenACCClause * C)602 static bool classof(const OpenACCClause *C) { 603 return C->getClauseKind() == OpenACCClauseKind::FirstPrivate; 604 } 605 static OpenACCFirstPrivateClause * 606 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 607 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 608 }; 609 610 class OpenACCDevicePtrClause final 611 : public OpenACCClauseWithVarList, 612 public llvm::TrailingObjects<OpenACCDevicePtrClause, Expr *> { 613 OpenACCDevicePtrClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)614 OpenACCDevicePtrClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 615 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 616 : OpenACCClauseWithVarList(OpenACCClauseKind::DevicePtr, BeginLoc, 617 LParenLoc, EndLoc) { 618 std::uninitialized_copy(VarList.begin(), VarList.end(), 619 getTrailingObjects<Expr *>()); 620 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 621 } 622 623 public: classof(const OpenACCClause * C)624 static bool classof(const OpenACCClause *C) { 625 return C->getClauseKind() == OpenACCClauseKind::DevicePtr; 626 } 627 static OpenACCDevicePtrClause * 628 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 629 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 630 }; 631 632 class OpenACCAttachClause final 633 : public OpenACCClauseWithVarList, 634 public llvm::TrailingObjects<OpenACCAttachClause, Expr *> { 635 OpenACCAttachClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)636 OpenACCAttachClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 637 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 638 : OpenACCClauseWithVarList(OpenACCClauseKind::Attach, BeginLoc, LParenLoc, 639 EndLoc) { 640 std::uninitialized_copy(VarList.begin(), VarList.end(), 641 getTrailingObjects<Expr *>()); 642 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 643 } 644 645 public: classof(const OpenACCClause * C)646 static bool classof(const OpenACCClause *C) { 647 return C->getClauseKind() == OpenACCClauseKind::Attach; 648 } 649 static OpenACCAttachClause * 650 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 651 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 652 }; 653 654 class OpenACCNoCreateClause final 655 : public OpenACCClauseWithVarList, 656 public llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> { 657 OpenACCNoCreateClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)658 OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 659 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 660 : OpenACCClauseWithVarList(OpenACCClauseKind::NoCreate, BeginLoc, 661 LParenLoc, EndLoc) { 662 std::uninitialized_copy(VarList.begin(), VarList.end(), 663 getTrailingObjects<Expr *>()); 664 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 665 } 666 667 public: classof(const OpenACCClause * C)668 static bool classof(const OpenACCClause *C) { 669 return C->getClauseKind() == OpenACCClauseKind::NoCreate; 670 } 671 static OpenACCNoCreateClause * 672 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 673 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 674 }; 675 676 class OpenACCPresentClause final 677 : public OpenACCClauseWithVarList, 678 public llvm::TrailingObjects<OpenACCPresentClause, Expr *> { 679 OpenACCPresentClause(SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)680 OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 681 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 682 : OpenACCClauseWithVarList(OpenACCClauseKind::Present, BeginLoc, 683 LParenLoc, EndLoc) { 684 std::uninitialized_copy(VarList.begin(), VarList.end(), 685 getTrailingObjects<Expr *>()); 686 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 687 } 688 689 public: classof(const OpenACCClause * C)690 static bool classof(const OpenACCClause *C) { 691 return C->getClauseKind() == OpenACCClauseKind::Present; 692 } 693 static OpenACCPresentClause * 694 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 695 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 696 }; 697 698 class OpenACCCopyClause final 699 : public OpenACCClauseWithVarList, 700 public llvm::TrailingObjects<OpenACCCopyClause, Expr *> { 701 OpenACCCopyClause(OpenACCClauseKind Spelling,SourceLocation BeginLoc,SourceLocation LParenLoc,ArrayRef<Expr * > VarList,SourceLocation EndLoc)702 OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, 703 SourceLocation LParenLoc, ArrayRef<Expr *> VarList, 704 SourceLocation EndLoc) 705 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc) { 706 assert((Spelling == OpenACCClauseKind::Copy || 707 Spelling == OpenACCClauseKind::PCopy || 708 Spelling == OpenACCClauseKind::PresentOrCopy) && 709 "Invalid clause kind for copy-clause"); 710 std::uninitialized_copy(VarList.begin(), VarList.end(), 711 getTrailingObjects<Expr *>()); 712 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 713 } 714 715 public: classof(const OpenACCClause * C)716 static bool classof(const OpenACCClause *C) { 717 return C->getClauseKind() == OpenACCClauseKind::Copy || 718 C->getClauseKind() == OpenACCClauseKind::PCopy || 719 C->getClauseKind() == OpenACCClauseKind::PresentOrCopy; 720 } 721 static OpenACCCopyClause * 722 Create(const ASTContext &C, OpenACCClauseKind Spelling, 723 SourceLocation BeginLoc, SourceLocation LParenLoc, 724 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 725 }; 726 727 class OpenACCCopyInClause final 728 : public OpenACCClauseWithVarList, 729 public llvm::TrailingObjects<OpenACCCopyInClause, Expr *> { 730 bool IsReadOnly; 731 OpenACCCopyInClause(OpenACCClauseKind Spelling,SourceLocation BeginLoc,SourceLocation LParenLoc,bool IsReadOnly,ArrayRef<Expr * > VarList,SourceLocation EndLoc)732 OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, 733 SourceLocation LParenLoc, bool IsReadOnly, 734 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 735 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), 736 IsReadOnly(IsReadOnly) { 737 assert((Spelling == OpenACCClauseKind::CopyIn || 738 Spelling == OpenACCClauseKind::PCopyIn || 739 Spelling == OpenACCClauseKind::PresentOrCopyIn) && 740 "Invalid clause kind for copyin-clause"); 741 std::uninitialized_copy(VarList.begin(), VarList.end(), 742 getTrailingObjects<Expr *>()); 743 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 744 } 745 746 public: classof(const OpenACCClause * C)747 static bool classof(const OpenACCClause *C) { 748 return C->getClauseKind() == OpenACCClauseKind::CopyIn || 749 C->getClauseKind() == OpenACCClauseKind::PCopyIn || 750 C->getClauseKind() == OpenACCClauseKind::PresentOrCopyIn; 751 } isReadOnly()752 bool isReadOnly() const { return IsReadOnly; } 753 static OpenACCCopyInClause * 754 Create(const ASTContext &C, OpenACCClauseKind Spelling, 755 SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, 756 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 757 }; 758 759 class OpenACCCopyOutClause final 760 : public OpenACCClauseWithVarList, 761 public llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> { 762 bool IsZero; 763 OpenACCCopyOutClause(OpenACCClauseKind Spelling,SourceLocation BeginLoc,SourceLocation LParenLoc,bool IsZero,ArrayRef<Expr * > VarList,SourceLocation EndLoc)764 OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, 765 SourceLocation LParenLoc, bool IsZero, 766 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 767 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), 768 IsZero(IsZero) { 769 assert((Spelling == OpenACCClauseKind::CopyOut || 770 Spelling == OpenACCClauseKind::PCopyOut || 771 Spelling == OpenACCClauseKind::PresentOrCopyOut) && 772 "Invalid clause kind for copyout-clause"); 773 std::uninitialized_copy(VarList.begin(), VarList.end(), 774 getTrailingObjects<Expr *>()); 775 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 776 } 777 778 public: classof(const OpenACCClause * C)779 static bool classof(const OpenACCClause *C) { 780 return C->getClauseKind() == OpenACCClauseKind::CopyOut || 781 C->getClauseKind() == OpenACCClauseKind::PCopyOut || 782 C->getClauseKind() == OpenACCClauseKind::PresentOrCopyOut; 783 } isZero()784 bool isZero() const { return IsZero; } 785 static OpenACCCopyOutClause * 786 Create(const ASTContext &C, OpenACCClauseKind Spelling, 787 SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, 788 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 789 }; 790 791 class OpenACCCreateClause final 792 : public OpenACCClauseWithVarList, 793 public llvm::TrailingObjects<OpenACCCreateClause, Expr *> { 794 bool IsZero; 795 OpenACCCreateClause(OpenACCClauseKind Spelling,SourceLocation BeginLoc,SourceLocation LParenLoc,bool IsZero,ArrayRef<Expr * > VarList,SourceLocation EndLoc)796 OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, 797 SourceLocation LParenLoc, bool IsZero, 798 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 799 : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), 800 IsZero(IsZero) { 801 assert((Spelling == OpenACCClauseKind::Create || 802 Spelling == OpenACCClauseKind::PCreate || 803 Spelling == OpenACCClauseKind::PresentOrCreate) && 804 "Invalid clause kind for create-clause"); 805 std::uninitialized_copy(VarList.begin(), VarList.end(), 806 getTrailingObjects<Expr *>()); 807 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 808 } 809 810 public: classof(const OpenACCClause * C)811 static bool classof(const OpenACCClause *C) { 812 return C->getClauseKind() == OpenACCClauseKind::Create || 813 C->getClauseKind() == OpenACCClauseKind::PCreate || 814 C->getClauseKind() == OpenACCClauseKind::PresentOrCreate; 815 } isZero()816 bool isZero() const { return IsZero; } 817 static OpenACCCreateClause * 818 Create(const ASTContext &C, OpenACCClauseKind Spelling, 819 SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, 820 ArrayRef<Expr *> VarList, SourceLocation EndLoc); 821 }; 822 823 class OpenACCReductionClause final 824 : public OpenACCClauseWithVarList, 825 public llvm::TrailingObjects<OpenACCReductionClause, Expr *> { 826 OpenACCReductionOperator Op; 827 OpenACCReductionClause(SourceLocation BeginLoc,SourceLocation LParenLoc,OpenACCReductionOperator Operator,ArrayRef<Expr * > VarList,SourceLocation EndLoc)828 OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc, 829 OpenACCReductionOperator Operator, 830 ArrayRef<Expr *> VarList, SourceLocation EndLoc) 831 : OpenACCClauseWithVarList(OpenACCClauseKind::Reduction, BeginLoc, 832 LParenLoc, EndLoc), 833 Op(Operator) { 834 std::uninitialized_copy(VarList.begin(), VarList.end(), 835 getTrailingObjects<Expr *>()); 836 setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size())); 837 } 838 839 public: classof(const OpenACCClause * C)840 static bool classof(const OpenACCClause *C) { 841 return C->getClauseKind() == OpenACCClauseKind::Reduction; 842 } 843 844 static OpenACCReductionClause * 845 Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 846 OpenACCReductionOperator Operator, ArrayRef<Expr *> VarList, 847 SourceLocation EndLoc); 848 getReductionOp()849 OpenACCReductionOperator getReductionOp() const { return Op; } 850 }; 851 852 template <class Impl> class OpenACCClauseVisitor { getDerived()853 Impl &getDerived() { return static_cast<Impl &>(*this); } 854 855 public: VisitClauseList(ArrayRef<const OpenACCClause * > List)856 void VisitClauseList(ArrayRef<const OpenACCClause *> List) { 857 for (const OpenACCClause *Clause : List) 858 Visit(Clause); 859 } 860 Visit(const OpenACCClause * C)861 void Visit(const OpenACCClause *C) { 862 if (!C) 863 return; 864 865 switch (C->getClauseKind()) { 866 #define VISIT_CLAUSE(CLAUSE_NAME) \ 867 case OpenACCClauseKind::CLAUSE_NAME: \ 868 Visit##CLAUSE_NAME##Clause(*cast<OpenACC##CLAUSE_NAME##Clause>(C)); \ 869 return; 870 #define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \ 871 case OpenACCClauseKind::ALIAS_NAME: \ 872 Visit##CLAUSE_NAME##Clause(*cast<OpenACC##CLAUSE_NAME##Clause>(C)); \ 873 return; 874 #include "clang/Basic/OpenACCClauses.def" 875 876 default: 877 llvm_unreachable("Clause visitor not yet implemented"); 878 } 879 llvm_unreachable("Invalid Clause kind"); 880 } 881 882 #define VISIT_CLAUSE(CLAUSE_NAME) \ 883 void Visit##CLAUSE_NAME##Clause( \ 884 const OpenACC##CLAUSE_NAME##Clause &Clause) { \ 885 return getDerived().Visit##CLAUSE_NAME##Clause(Clause); \ 886 } 887 888 #include "clang/Basic/OpenACCClauses.def" 889 }; 890 891 class OpenACCClausePrinter final 892 : public OpenACCClauseVisitor<OpenACCClausePrinter> { 893 raw_ostream &OS; 894 const PrintingPolicy &Policy; 895 896 void printExpr(const Expr *E); 897 898 public: VisitClauseList(ArrayRef<const OpenACCClause * > List)899 void VisitClauseList(ArrayRef<const OpenACCClause *> List) { 900 for (const OpenACCClause *Clause : List) { 901 Visit(Clause); 902 903 if (Clause != List.back()) 904 OS << ' '; 905 } 906 } OpenACCClausePrinter(raw_ostream & OS,const PrintingPolicy & Policy)907 OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) 908 : OS(OS), Policy(Policy) {} 909 910 #define VISIT_CLAUSE(CLAUSE_NAME) \ 911 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause); 912 #include "clang/Basic/OpenACCClauses.def" 913 }; 914 915 } // namespace clang 916 917 #endif // LLVM_CLANG_AST_OPENACCCLAUSE_H 918