1 //===----- SemaOpenACC.h - Semantic Analysis for OpenACC constructs -------===// 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 /// \file 9 /// This file declares semantic analysis for OpenACC constructs and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_SEMA_SEMAOPENACC_H 15 #define LLVM_CLANG_SEMA_SEMAOPENACC_H 16 17 #include "clang/AST/DeclGroup.h" 18 #include "clang/AST/StmtOpenACC.h" 19 #include "clang/Basic/LLVM.h" 20 #include "clang/Basic/OpenACCKinds.h" 21 #include "clang/Basic/SourceLocation.h" 22 #include "clang/Sema/Ownership.h" 23 #include "clang/Sema/SemaBase.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/Support/Compiler.h" 26 #include <cassert> 27 #include <optional> 28 #include <utility> 29 #include <variant> 30 31 namespace clang { 32 class IdentifierInfo; 33 class OpenACCClause; 34 class Scope; 35 36 class SemaOpenACC : public SemaBase { 37 public: 38 using DeclGroupPtrTy = OpaquePtr<DeclGroupRef>; 39 40 private: 41 struct ComputeConstructInfo { 42 /// Which type of compute construct we are inside of, which we can use to 43 /// determine whether we should add loops to the above collection. We can 44 /// also use it to diagnose loop construct clauses. 45 OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid; 46 // If we have an active compute construct, stores the list of clauses we've 47 // prepared for it, so that we can diagnose limitations on child constructs. 48 ArrayRef<OpenACCClause *> Clauses; 49 } ActiveComputeConstructInfo; 50 isInComputeConstruct()51 bool isInComputeConstruct() const { 52 return ActiveComputeConstructInfo.Kind != OpenACCDirectiveKind::Invalid; 53 } 54 55 /// Certain clauses care about the same things that aren't specific to the 56 /// individual clause, but can be shared by a few, so store them here. All 57 /// require a 'no intervening constructs' rule, so we know they are all from 58 /// the same 'place'. 59 struct LoopCheckingInfo { 60 /// Records whether we've seen the top level 'for'. We already diagnose 61 /// later that the 'top level' is a for loop, so we use this to suppress the 62 /// 'collapse inner loop not a 'for' loop' diagnostic. 63 LLVM_PREFERRED_TYPE(bool) 64 unsigned TopLevelLoopSeen : 1; 65 66 /// Records whether this 'tier' of the loop has already seen a 'for' loop, 67 /// used to diagnose if there are multiple 'for' loops at any one level. 68 LLVM_PREFERRED_TYPE(bool) 69 unsigned CurLevelHasLoopAlready : 1; 70 71 } LoopInfo{/*TopLevelLoopSeen=*/false, /*CurLevelHasLoopAlready=*/false}; 72 73 /// The 'collapse' clause requires quite a bit of checking while 74 /// parsing/instantiating its body, so this structure/object keeps all of the 75 /// necessary information as we do checking. This should rarely be directly 76 /// modified, and typically should be controlled by the RAII objects. 77 /// 78 /// Collapse has an 'N' count that makes it apply to a number of loops 'below' 79 /// it. 80 struct CollapseCheckingInfo { 81 const OpenACCCollapseClause *ActiveCollapse = nullptr; 82 83 /// This is a value that maintains the current value of the 'N' on the 84 /// current collapse, minus the depth that has already been traversed. When 85 /// there is not an active collapse, or a collapse whose depth we don't know 86 /// (for example, if it is a dependent value), this should be `nullopt`, 87 /// else it should be 'N' minus the current depth traversed. 88 std::optional<llvm::APSInt> CurCollapseCount; 89 90 /// Records whether we've hit a CurCollapseCount of '0' on the way down, 91 /// which allows us to diagnose if the value of 'N' is too large for the 92 /// current number of 'for' loops. 93 bool CollapseDepthSatisfied = true; 94 95 /// Records the kind of the directive that this clause is attached to, which 96 /// allows us to use it in diagnostics. 97 OpenACCDirectiveKind DirectiveKind = OpenACCDirectiveKind::Invalid; 98 } CollapseInfo; 99 100 /// The 'tile' clause requires a bit of additional checking as well, so like 101 /// the `CollapseCheckingInfo`, ensure we maintain information here too. 102 struct TileCheckingInfo { 103 OpenACCTileClause *ActiveTile = nullptr; 104 105 /// This is the number of expressions on a 'tile' clause. This doesn't have 106 /// to be an APSInt because it isn't the result of a constexpr, just by our 107 /// own counting of elements. 108 UnsignedOrNone CurTileCount = std::nullopt; 109 110 /// Records whether we've hit a 'CurTileCount' of '0' on the way down, 111 /// which allows us to diagnose if the number of arguments is too large for 112 /// the current number of 'for' loops. 113 bool TileDepthSatisfied = true; 114 115 /// Records the kind of the directive that this clause is attached to, which 116 /// allows us to use it in diagnostics. 117 OpenACCDirectiveKind DirectiveKind = OpenACCDirectiveKind::Invalid; 118 } TileInfo; 119 120 /// The 'cache' var-list requires some additional work to track variable 121 /// references to make sure they are on the 'other' side of a `loop`. This 122 /// structure is used during parse time to track vardecl use while parsing a 123 /// cache var list. 124 struct CacheParseInfo { 125 bool ParsingCacheVarList = false; 126 bool IsInvalidCacheRef = false; 127 } CacheInfo; 128 129 /// A list of the active reduction clauses, which allows us to check that all 130 /// vars on nested constructs for the same reduction var have the same 131 /// reduction operator. Currently this is enforced against all constructs 132 /// despite the rule being in the 'loop' section. By current reading, this 133 /// should apply to all anyway, but we may need to make this more like the 134 /// 'loop' clause enforcement, where this is 'blocked' by a compute construct. 135 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses; 136 137 // Type to check the 'for' (or range-for) statement for compatibility with the 138 // 'loop' directive. 139 class ForStmtBeginChecker { 140 SemaOpenACC &SemaRef; 141 SourceLocation ForLoc; 142 bool IsInstantiation = false; 143 144 struct RangeForInfo { 145 const CXXForRangeStmt *Uninstantiated = nullptr; 146 const CXXForRangeStmt *CurrentVersion = nullptr; 147 // GCC 7.x requires this constructor, else the construction of variant 148 // doesn't work correctly. RangeForInfoRangeForInfo149 RangeForInfo() : Uninstantiated{nullptr}, CurrentVersion{nullptr} {} RangeForInfoRangeForInfo150 RangeForInfo(const CXXForRangeStmt *Uninst, const CXXForRangeStmt *Cur) 151 : Uninstantiated{Uninst}, CurrentVersion{Cur} {} 152 }; 153 154 struct ForInfo { 155 const Stmt *Init = nullptr; 156 const Stmt *Condition = nullptr; 157 const Stmt *Increment = nullptr; 158 }; 159 160 struct CheckForInfo { 161 ForInfo Uninst; 162 ForInfo Current; 163 }; 164 165 std::variant<RangeForInfo, CheckForInfo> Info; 166 // Prevent us from checking 2x, which can happen with collapse & tile. 167 bool AlreadyChecked = false; 168 169 void checkRangeFor(); 170 171 bool checkForInit(const Stmt *InitStmt, const ValueDecl *&InitVar, 172 bool Diag); 173 bool checkForCond(const Stmt *CondStmt, const ValueDecl *InitVar, 174 bool Diag); 175 bool checkForInc(const Stmt *IncStmt, const ValueDecl *InitVar, bool Diag); 176 177 void checkFor(); 178 179 // void checkRangeFor(); ?? ERICH 180 // const ValueDecl *checkInit(); 181 // void checkCond(const ValueDecl *Init); 182 // void checkInc(const ValueDecl *Init); 183 public: 184 // Checking for non-instantiation version of a Range-for. ForStmtBeginChecker(SemaOpenACC & SemaRef,SourceLocation ForLoc,const CXXForRangeStmt * RangeFor)185 ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc, 186 const CXXForRangeStmt *RangeFor) 187 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(false), 188 Info(RangeForInfo{nullptr, RangeFor}) {} 189 // Checking for an instantiation of the range-for. ForStmtBeginChecker(SemaOpenACC & SemaRef,SourceLocation ForLoc,const CXXForRangeStmt * OldRangeFor,const CXXForRangeStmt * RangeFor)190 ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc, 191 const CXXForRangeStmt *OldRangeFor, 192 const CXXForRangeStmt *RangeFor) 193 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(true), 194 Info(RangeForInfo{OldRangeFor, RangeFor}) {} 195 // Checking for a non-instantiation version of a traditional for. ForStmtBeginChecker(SemaOpenACC & SemaRef,SourceLocation ForLoc,const Stmt * Init,const Stmt * Cond,const Stmt * Inc)196 ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc, 197 const Stmt *Init, const Stmt *Cond, const Stmt *Inc) 198 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(false), 199 Info(CheckForInfo{{}, {Init, Cond, Inc}}) {} 200 // Checking for an instantiation version of a traditional for. ForStmtBeginChecker(SemaOpenACC & SemaRef,SourceLocation ForLoc,const Stmt * OldInit,const Stmt * OldCond,const Stmt * OldInc,const Stmt * Init,const Stmt * Cond,const Stmt * Inc)201 ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc, 202 const Stmt *OldInit, const Stmt *OldCond, 203 const Stmt *OldInc, const Stmt *Init, const Stmt *Cond, 204 const Stmt *Inc) 205 : SemaRef(SemaRef), ForLoc(ForLoc), IsInstantiation(true), 206 Info(CheckForInfo{{OldInit, OldCond, OldInc}, {Init, Cond, Inc}}) {} 207 208 void check(); 209 }; 210 211 /// Helper function for checking the 'for' and 'range for' stmts. 212 void ForStmtBeginHelper(SourceLocation ForLoc, ForStmtBeginChecker &C); 213 214 // The 'declare' construct requires only a single reference among ALL declare 215 // directives in a context. We store existing references to check. Because the 216 // rules prevent referencing the same variable from multiple declaration 217 // contexts, we can just store the declaration and location of the reference. 218 llvm::DenseMap<const clang::DeclaratorDecl *, SourceLocation> 219 DeclareVarReferences; 220 // The 'routine' construct disallows magic-statics in a function referred to 221 // by a 'routine' directive. So record any of these that we see so we can 222 // check them later. 223 llvm::SmallDenseMap<const clang::FunctionDecl *, SourceLocation> 224 MagicStaticLocs; 225 OpenACCRoutineDecl *LastRoutineDecl = nullptr; 226 227 void CheckLastRoutineDeclNameConflict(const NamedDecl *ND); 228 229 bool DiagnoseRequiredClauses(OpenACCDirectiveKind DK, SourceLocation DirLoc, 230 ArrayRef<const OpenACCClause *> Clauses); 231 232 bool DiagnoseAllowedClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 233 SourceLocation ClauseLoc); 234 235 public: 236 // Needed from the visitor, so should be public. 237 bool DiagnoseAllowedOnceClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 238 SourceLocation ClauseLoc, 239 ArrayRef<const OpenACCClause *> Clauses); 240 bool DiagnoseExclusiveClauses(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 241 SourceLocation ClauseLoc, 242 ArrayRef<const OpenACCClause *> Clauses); 243 244 public: getActiveComputeConstructInfo()245 ComputeConstructInfo &getActiveComputeConstructInfo() { 246 return ActiveComputeConstructInfo; 247 } 248 249 /// If there is a current 'active' loop construct with a 'gang' clause on a 250 /// 'kernel' construct, this will have the source location for it, and the 251 /// 'kernel kind'. This permits us to implement the restriction of no further 252 /// 'gang' clauses. 253 struct LoopGangOnKernelTy { 254 SourceLocation Loc; 255 OpenACCDirectiveKind DirKind = OpenACCDirectiveKind::Invalid; 256 } LoopGangClauseOnKernel; 257 258 /// If there is a current 'active' loop construct with a 'worker' clause on it 259 /// (on any sort of construct), this has the source location for it. This 260 /// permits us to implement the restriction of no further 'gang' or 'worker' 261 /// clauses. 262 SourceLocation LoopWorkerClauseLoc; 263 /// If there is a current 'active' loop construct with a 'vector' clause on it 264 /// (on any sort of construct), this has the source location for it. This 265 /// permits us to implement the restriction of no further 'gang', 'vector', or 266 /// 'worker' clauses. 267 SourceLocation LoopVectorClauseLoc; 268 /// If there is a current 'active' loop construct that does NOT have a 'seq' 269 /// clause on it, this has that source location and loop Directive 'kind'. 270 /// This permits us to implement the 'loop' restrictions on the loop variable. 271 /// This can be extended via 'collapse', so we need to keep this around for a 272 /// while. 273 struct LoopWithoutSeqCheckingInfo { 274 OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid; 275 SourceLocation Loc; 276 } LoopWithoutSeqInfo; 277 278 // Redeclaration of the version in OpenACCClause.h. 279 using DeviceTypeArgument = IdentifierLoc; 280 281 /// A type to represent all the data for an OpenACC Clause that has been 282 /// parsed, but not yet created/semantically analyzed. This is effectively a 283 /// discriminated union on the 'Clause Kind', with all of the individual 284 /// clause details stored in a std::variant. 285 class OpenACCParsedClause { 286 OpenACCDirectiveKind DirKind; 287 OpenACCClauseKind ClauseKind; 288 SourceRange ClauseRange; 289 SourceLocation LParenLoc; 290 291 struct DefaultDetails { 292 OpenACCDefaultClauseKind DefaultClauseKind; 293 }; 294 295 struct ConditionDetails { 296 Expr *ConditionExpr; 297 }; 298 299 struct IntExprDetails { 300 SmallVector<Expr *> IntExprs; 301 }; 302 303 struct VarListDetails { 304 SmallVector<Expr *> VarList; 305 OpenACCModifierKind ModifierKind; 306 }; 307 308 struct WaitDetails { 309 Expr *DevNumExpr; 310 SourceLocation QueuesLoc; 311 SmallVector<Expr *> QueueIdExprs; 312 }; 313 314 struct DeviceTypeDetails { 315 SmallVector<DeviceTypeArgument> Archs; 316 }; 317 struct ReductionDetails { 318 OpenACCReductionOperator Op; 319 SmallVector<Expr *> VarList; 320 }; 321 322 struct CollapseDetails { 323 bool IsForce; 324 Expr *LoopCount; 325 }; 326 327 struct GangDetails { 328 SmallVector<OpenACCGangKind> GangKinds; 329 SmallVector<Expr *> IntExprs; 330 }; 331 struct BindDetails { 332 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *> 333 Argument; 334 }; 335 336 std::variant<std::monostate, DefaultDetails, ConditionDetails, 337 IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails, 338 ReductionDetails, CollapseDetails, GangDetails, BindDetails> 339 Details = std::monostate{}; 340 341 public: OpenACCParsedClause(OpenACCDirectiveKind DirKind,OpenACCClauseKind ClauseKind,SourceLocation BeginLoc)342 OpenACCParsedClause(OpenACCDirectiveKind DirKind, 343 OpenACCClauseKind ClauseKind, SourceLocation BeginLoc) 344 : DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {} 345 getDirectiveKind()346 OpenACCDirectiveKind getDirectiveKind() const { return DirKind; } 347 getClauseKind()348 OpenACCClauseKind getClauseKind() const { return ClauseKind; } 349 getBeginLoc()350 SourceLocation getBeginLoc() const { return ClauseRange.getBegin(); } 351 getLParenLoc()352 SourceLocation getLParenLoc() const { return LParenLoc; } 353 getEndLoc()354 SourceLocation getEndLoc() const { return ClauseRange.getEnd(); } 355 getDefaultClauseKind()356 OpenACCDefaultClauseKind getDefaultClauseKind() const { 357 assert(ClauseKind == OpenACCClauseKind::Default && 358 "Parsed clause is not a default clause"); 359 return std::get<DefaultDetails>(Details).DefaultClauseKind; 360 } 361 getConditionExpr()362 const Expr *getConditionExpr() const { 363 return const_cast<OpenACCParsedClause *>(this)->getConditionExpr(); 364 } 365 getConditionExpr()366 Expr *getConditionExpr() { 367 assert((ClauseKind == OpenACCClauseKind::If || 368 (ClauseKind == OpenACCClauseKind::Self && 369 DirKind != OpenACCDirectiveKind::Update)) && 370 "Parsed clause kind does not have a condition expr"); 371 372 // 'self' has an optional ConditionExpr, so be tolerant of that. This will 373 // assert in variant otherwise. 374 if (ClauseKind == OpenACCClauseKind::Self && 375 std::holds_alternative<std::monostate>(Details)) 376 return nullptr; 377 378 return std::get<ConditionDetails>(Details).ConditionExpr; 379 } 380 getNumIntExprs()381 unsigned getNumIntExprs() const { 382 assert((ClauseKind == OpenACCClauseKind::NumGangs || 383 ClauseKind == OpenACCClauseKind::NumWorkers || 384 ClauseKind == OpenACCClauseKind::Async || 385 ClauseKind == OpenACCClauseKind::DeviceNum || 386 ClauseKind == OpenACCClauseKind::DefaultAsync || 387 ClauseKind == OpenACCClauseKind::Tile || 388 ClauseKind == OpenACCClauseKind::Worker || 389 ClauseKind == OpenACCClauseKind::Vector || 390 ClauseKind == OpenACCClauseKind::VectorLength) && 391 "Parsed clause kind does not have a int exprs"); 392 393 // 'async', 'worker', 'vector', and 'wait' have an optional IntExpr, so be 394 // tolerant of that. 395 if ((ClauseKind == OpenACCClauseKind::Async || 396 ClauseKind == OpenACCClauseKind::Worker || 397 ClauseKind == OpenACCClauseKind::Vector || 398 ClauseKind == OpenACCClauseKind::Wait) && 399 std::holds_alternative<std::monostate>(Details)) 400 return 0; 401 return std::get<IntExprDetails>(Details).IntExprs.size(); 402 } 403 getQueuesLoc()404 SourceLocation getQueuesLoc() const { 405 assert(ClauseKind == OpenACCClauseKind::Wait && 406 "Parsed clause kind does not have a queues location"); 407 408 if (std::holds_alternative<std::monostate>(Details)) 409 return SourceLocation{}; 410 411 return std::get<WaitDetails>(Details).QueuesLoc; 412 } 413 getDevNumExpr()414 Expr *getDevNumExpr() const { 415 assert(ClauseKind == OpenACCClauseKind::Wait && 416 "Parsed clause kind does not have a device number expr"); 417 418 if (std::holds_alternative<std::monostate>(Details)) 419 return nullptr; 420 421 return std::get<WaitDetails>(Details).DevNumExpr; 422 } 423 getQueueIdExprs()424 ArrayRef<Expr *> getQueueIdExprs() const { 425 assert(ClauseKind == OpenACCClauseKind::Wait && 426 "Parsed clause kind does not have a queue id expr list"); 427 428 if (std::holds_alternative<std::monostate>(Details)) 429 return ArrayRef<Expr *>(); 430 431 return std::get<WaitDetails>(Details).QueueIdExprs; 432 } 433 getIntExprs()434 ArrayRef<Expr *> getIntExprs() { 435 assert((ClauseKind == OpenACCClauseKind::NumGangs || 436 ClauseKind == OpenACCClauseKind::NumWorkers || 437 ClauseKind == OpenACCClauseKind::Async || 438 ClauseKind == OpenACCClauseKind::DeviceNum || 439 ClauseKind == OpenACCClauseKind::DefaultAsync || 440 ClauseKind == OpenACCClauseKind::Tile || 441 ClauseKind == OpenACCClauseKind::Gang || 442 ClauseKind == OpenACCClauseKind::Worker || 443 ClauseKind == OpenACCClauseKind::Vector || 444 ClauseKind == OpenACCClauseKind::VectorLength) && 445 "Parsed clause kind does not have a int exprs"); 446 447 if (ClauseKind == OpenACCClauseKind::Gang) { 448 // There might not be any gang int exprs, as this is an optional 449 // argument. 450 if (std::holds_alternative<std::monostate>(Details)) 451 return {}; 452 return std::get<GangDetails>(Details).IntExprs; 453 } 454 455 return std::get<IntExprDetails>(Details).IntExprs; 456 } 457 getIntExprs()458 ArrayRef<Expr *> getIntExprs() const { 459 return const_cast<OpenACCParsedClause *>(this)->getIntExprs(); 460 } 461 getReductionOp()462 OpenACCReductionOperator getReductionOp() const { 463 return std::get<ReductionDetails>(Details).Op; 464 } 465 getGangKinds()466 ArrayRef<OpenACCGangKind> getGangKinds() const { 467 assert(ClauseKind == OpenACCClauseKind::Gang && 468 "Parsed clause kind does not have gang kind"); 469 // The args on gang are optional, so this might not actually hold 470 // anything. 471 if (std::holds_alternative<std::monostate>(Details)) 472 return {}; 473 return std::get<GangDetails>(Details).GangKinds; 474 } 475 getVarList()476 ArrayRef<Expr *> getVarList() { 477 assert((ClauseKind == OpenACCClauseKind::Private || 478 ClauseKind == OpenACCClauseKind::NoCreate || 479 ClauseKind == OpenACCClauseKind::Present || 480 ClauseKind == OpenACCClauseKind::Copy || 481 ClauseKind == OpenACCClauseKind::PCopy || 482 ClauseKind == OpenACCClauseKind::PresentOrCopy || 483 ClauseKind == OpenACCClauseKind::CopyIn || 484 ClauseKind == OpenACCClauseKind::PCopyIn || 485 ClauseKind == OpenACCClauseKind::PresentOrCopyIn || 486 ClauseKind == OpenACCClauseKind::CopyOut || 487 ClauseKind == OpenACCClauseKind::PCopyOut || 488 ClauseKind == OpenACCClauseKind::PresentOrCopyOut || 489 ClauseKind == OpenACCClauseKind::Create || 490 ClauseKind == OpenACCClauseKind::PCreate || 491 ClauseKind == OpenACCClauseKind::PresentOrCreate || 492 ClauseKind == OpenACCClauseKind::Attach || 493 ClauseKind == OpenACCClauseKind::Delete || 494 ClauseKind == OpenACCClauseKind::UseDevice || 495 ClauseKind == OpenACCClauseKind::Detach || 496 ClauseKind == OpenACCClauseKind::DevicePtr || 497 ClauseKind == OpenACCClauseKind::Reduction || 498 ClauseKind == OpenACCClauseKind::Host || 499 ClauseKind == OpenACCClauseKind::Device || 500 ClauseKind == OpenACCClauseKind::DeviceResident || 501 ClauseKind == OpenACCClauseKind::Link || 502 (ClauseKind == OpenACCClauseKind::Self && 503 DirKind == OpenACCDirectiveKind::Update) || 504 ClauseKind == OpenACCClauseKind::FirstPrivate) && 505 "Parsed clause kind does not have a var-list"); 506 507 if (ClauseKind == OpenACCClauseKind::Reduction) 508 return std::get<ReductionDetails>(Details).VarList; 509 510 return std::get<VarListDetails>(Details).VarList; 511 } 512 getVarList()513 ArrayRef<Expr *> getVarList() const { 514 return const_cast<OpenACCParsedClause *>(this)->getVarList(); 515 } 516 getModifierList()517 OpenACCModifierKind getModifierList() const { 518 return std::get<VarListDetails>(Details).ModifierKind; 519 } 520 isForce()521 bool isForce() const { 522 assert(ClauseKind == OpenACCClauseKind::Collapse && 523 "Only 'collapse' has a force tag"); 524 return std::get<CollapseDetails>(Details).IsForce; 525 } 526 getLoopCount()527 Expr *getLoopCount() const { 528 assert(ClauseKind == OpenACCClauseKind::Collapse && 529 "Only 'collapse' has a loop count"); 530 return std::get<CollapseDetails>(Details).LoopCount; 531 } 532 getDeviceTypeArchitectures()533 ArrayRef<DeviceTypeArgument> getDeviceTypeArchitectures() const { 534 assert((ClauseKind == OpenACCClauseKind::DeviceType || 535 ClauseKind == OpenACCClauseKind::DType) && 536 "Only 'device_type'/'dtype' has a device-type-arg list"); 537 return std::get<DeviceTypeDetails>(Details).Archs; 538 } 539 540 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *> getBindDetails()541 getBindDetails() const { 542 assert(ClauseKind == OpenACCClauseKind::Bind && 543 "Only 'bind' has bind details"); 544 return std::get<BindDetails>(Details).Argument; 545 } 546 setLParenLoc(SourceLocation EndLoc)547 void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; } setEndLoc(SourceLocation EndLoc)548 void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); } 549 setDefaultDetails(OpenACCDefaultClauseKind DefKind)550 void setDefaultDetails(OpenACCDefaultClauseKind DefKind) { 551 assert(ClauseKind == OpenACCClauseKind::Default && 552 "Parsed clause is not a default clause"); 553 Details = DefaultDetails{DefKind}; 554 } 555 setConditionDetails(Expr * ConditionExpr)556 void setConditionDetails(Expr *ConditionExpr) { 557 assert((ClauseKind == OpenACCClauseKind::If || 558 (ClauseKind == OpenACCClauseKind::Self && 559 DirKind != OpenACCDirectiveKind::Update)) && 560 "Parsed clause kind does not have a condition expr"); 561 // In C++ we can count on this being a 'bool', but in C this gets left as 562 // some sort of scalar that codegen will have to take care of converting. 563 assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() || 564 ConditionExpr->getType()->isScalarType()) && 565 "Condition expression type not scalar/dependent"); 566 567 Details = ConditionDetails{ConditionExpr}; 568 } 569 setIntExprDetails(ArrayRef<Expr * > IntExprs)570 void setIntExprDetails(ArrayRef<Expr *> IntExprs) { 571 assert((ClauseKind == OpenACCClauseKind::NumGangs || 572 ClauseKind == OpenACCClauseKind::NumWorkers || 573 ClauseKind == OpenACCClauseKind::Async || 574 ClauseKind == OpenACCClauseKind::DeviceNum || 575 ClauseKind == OpenACCClauseKind::DefaultAsync || 576 ClauseKind == OpenACCClauseKind::Tile || 577 ClauseKind == OpenACCClauseKind::Worker || 578 ClauseKind == OpenACCClauseKind::Vector || 579 ClauseKind == OpenACCClauseKind::VectorLength) && 580 "Parsed clause kind does not have a int exprs"); 581 Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}}; 582 } setIntExprDetails(llvm::SmallVector<Expr * > && IntExprs)583 void setIntExprDetails(llvm::SmallVector<Expr *> &&IntExprs) { 584 assert((ClauseKind == OpenACCClauseKind::NumGangs || 585 ClauseKind == OpenACCClauseKind::NumWorkers || 586 ClauseKind == OpenACCClauseKind::Async || 587 ClauseKind == OpenACCClauseKind::DeviceNum || 588 ClauseKind == OpenACCClauseKind::DefaultAsync || 589 ClauseKind == OpenACCClauseKind::Tile || 590 ClauseKind == OpenACCClauseKind::Worker || 591 ClauseKind == OpenACCClauseKind::Vector || 592 ClauseKind == OpenACCClauseKind::VectorLength) && 593 "Parsed clause kind does not have a int exprs"); 594 Details = IntExprDetails{std::move(IntExprs)}; 595 } 596 setGangDetails(ArrayRef<OpenACCGangKind> GKs,ArrayRef<Expr * > IntExprs)597 void setGangDetails(ArrayRef<OpenACCGangKind> GKs, 598 ArrayRef<Expr *> IntExprs) { 599 assert(ClauseKind == OpenACCClauseKind::Gang && 600 "Parsed Clause kind does not have gang details"); 601 assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?"); 602 603 Details = GangDetails{{GKs.begin(), GKs.end()}, 604 {IntExprs.begin(), IntExprs.end()}}; 605 } 606 setGangDetails(llvm::SmallVector<OpenACCGangKind> && GKs,llvm::SmallVector<Expr * > && IntExprs)607 void setGangDetails(llvm::SmallVector<OpenACCGangKind> &&GKs, 608 llvm::SmallVector<Expr *> &&IntExprs) { 609 assert(ClauseKind == OpenACCClauseKind::Gang && 610 "Parsed Clause kind does not have gang details"); 611 assert(GKs.size() == IntExprs.size() && "Mismatched kind/size?"); 612 613 Details = GangDetails{std::move(GKs), std::move(IntExprs)}; 614 } 615 setVarListDetails(ArrayRef<Expr * > VarList,OpenACCModifierKind ModKind)616 void setVarListDetails(ArrayRef<Expr *> VarList, 617 OpenACCModifierKind ModKind) { 618 assert((ClauseKind == OpenACCClauseKind::Private || 619 ClauseKind == OpenACCClauseKind::NoCreate || 620 ClauseKind == OpenACCClauseKind::Present || 621 ClauseKind == OpenACCClauseKind::Copy || 622 ClauseKind == OpenACCClauseKind::PCopy || 623 ClauseKind == OpenACCClauseKind::PresentOrCopy || 624 ClauseKind == OpenACCClauseKind::CopyIn || 625 ClauseKind == OpenACCClauseKind::PCopyIn || 626 ClauseKind == OpenACCClauseKind::PresentOrCopyIn || 627 ClauseKind == OpenACCClauseKind::CopyOut || 628 ClauseKind == OpenACCClauseKind::PCopyOut || 629 ClauseKind == OpenACCClauseKind::PresentOrCopyOut || 630 ClauseKind == OpenACCClauseKind::Create || 631 ClauseKind == OpenACCClauseKind::PCreate || 632 ClauseKind == OpenACCClauseKind::PresentOrCreate || 633 ClauseKind == OpenACCClauseKind::Attach || 634 ClauseKind == OpenACCClauseKind::Delete || 635 ClauseKind == OpenACCClauseKind::UseDevice || 636 ClauseKind == OpenACCClauseKind::Detach || 637 ClauseKind == OpenACCClauseKind::DevicePtr || 638 ClauseKind == OpenACCClauseKind::Host || 639 ClauseKind == OpenACCClauseKind::Device || 640 ClauseKind == OpenACCClauseKind::DeviceResident || 641 ClauseKind == OpenACCClauseKind::Link || 642 (ClauseKind == OpenACCClauseKind::Self && 643 DirKind == OpenACCDirectiveKind::Update) || 644 ClauseKind == OpenACCClauseKind::FirstPrivate) && 645 "Parsed clause kind does not have a var-list"); 646 assert((ModKind == OpenACCModifierKind::Invalid || 647 ClauseKind == OpenACCClauseKind::Copy || 648 ClauseKind == OpenACCClauseKind::PCopy || 649 ClauseKind == OpenACCClauseKind::PresentOrCopy || 650 ClauseKind == OpenACCClauseKind::CopyIn || 651 ClauseKind == OpenACCClauseKind::PCopyIn || 652 ClauseKind == OpenACCClauseKind::PresentOrCopyIn || 653 ClauseKind == OpenACCClauseKind::CopyOut || 654 ClauseKind == OpenACCClauseKind::PCopyOut || 655 ClauseKind == OpenACCClauseKind::PresentOrCopyOut || 656 ClauseKind == OpenACCClauseKind::Create || 657 ClauseKind == OpenACCClauseKind::PCreate || 658 ClauseKind == OpenACCClauseKind::PresentOrCreate) && 659 "Modifier Kind only valid on copy, copyin, copyout, create"); 660 Details = VarListDetails{{VarList.begin(), VarList.end()}, ModKind}; 661 } 662 setVarListDetails(llvm::SmallVector<Expr * > && VarList,OpenACCModifierKind ModKind)663 void setVarListDetails(llvm::SmallVector<Expr *> &&VarList, 664 OpenACCModifierKind ModKind) { 665 assert((ClauseKind == OpenACCClauseKind::Private || 666 ClauseKind == OpenACCClauseKind::NoCreate || 667 ClauseKind == OpenACCClauseKind::Present || 668 ClauseKind == OpenACCClauseKind::Copy || 669 ClauseKind == OpenACCClauseKind::PCopy || 670 ClauseKind == OpenACCClauseKind::PresentOrCopy || 671 ClauseKind == OpenACCClauseKind::CopyIn || 672 ClauseKind == OpenACCClauseKind::PCopyIn || 673 ClauseKind == OpenACCClauseKind::PresentOrCopyIn || 674 ClauseKind == OpenACCClauseKind::CopyOut || 675 ClauseKind == OpenACCClauseKind::PCopyOut || 676 ClauseKind == OpenACCClauseKind::PresentOrCopyOut || 677 ClauseKind == OpenACCClauseKind::Create || 678 ClauseKind == OpenACCClauseKind::PCreate || 679 ClauseKind == OpenACCClauseKind::PresentOrCreate || 680 ClauseKind == OpenACCClauseKind::Attach || 681 ClauseKind == OpenACCClauseKind::Delete || 682 ClauseKind == OpenACCClauseKind::UseDevice || 683 ClauseKind == OpenACCClauseKind::Detach || 684 ClauseKind == OpenACCClauseKind::DevicePtr || 685 ClauseKind == OpenACCClauseKind::Host || 686 ClauseKind == OpenACCClauseKind::Device || 687 ClauseKind == OpenACCClauseKind::DeviceResident || 688 ClauseKind == OpenACCClauseKind::Link || 689 (ClauseKind == OpenACCClauseKind::Self && 690 DirKind == OpenACCDirectiveKind::Update) || 691 ClauseKind == OpenACCClauseKind::FirstPrivate) && 692 "Parsed clause kind does not have a var-list"); 693 assert((ModKind == OpenACCModifierKind::Invalid || 694 ClauseKind == OpenACCClauseKind::Copy || 695 ClauseKind == OpenACCClauseKind::PCopy || 696 ClauseKind == OpenACCClauseKind::PresentOrCopy || 697 ClauseKind == OpenACCClauseKind::CopyIn || 698 ClauseKind == OpenACCClauseKind::PCopyIn || 699 ClauseKind == OpenACCClauseKind::PresentOrCopyIn || 700 ClauseKind == OpenACCClauseKind::CopyOut || 701 ClauseKind == OpenACCClauseKind::PCopyOut || 702 ClauseKind == OpenACCClauseKind::PresentOrCopyOut || 703 ClauseKind == OpenACCClauseKind::Create || 704 ClauseKind == OpenACCClauseKind::PCreate || 705 ClauseKind == OpenACCClauseKind::PresentOrCreate) && 706 "Modifier Kind only valid on copy, copyin, copyout, create"); 707 Details = VarListDetails{std::move(VarList), ModKind}; 708 } 709 setReductionDetails(OpenACCReductionOperator Op,llvm::SmallVector<Expr * > && VarList)710 void setReductionDetails(OpenACCReductionOperator Op, 711 llvm::SmallVector<Expr *> &&VarList) { 712 assert(ClauseKind == OpenACCClauseKind::Reduction && 713 "reduction details only valid on reduction"); 714 Details = ReductionDetails{Op, std::move(VarList)}; 715 } 716 setWaitDetails(Expr * DevNum,SourceLocation QueuesLoc,llvm::SmallVector<Expr * > && IntExprs)717 void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, 718 llvm::SmallVector<Expr *> &&IntExprs) { 719 assert(ClauseKind == OpenACCClauseKind::Wait && 720 "Parsed clause kind does not have a wait-details"); 721 Details = WaitDetails{DevNum, QueuesLoc, std::move(IntExprs)}; 722 } 723 setDeviceTypeDetails(llvm::SmallVector<DeviceTypeArgument> && Archs)724 void setDeviceTypeDetails(llvm::SmallVector<DeviceTypeArgument> &&Archs) { 725 assert((ClauseKind == OpenACCClauseKind::DeviceType || 726 ClauseKind == OpenACCClauseKind::DType) && 727 "Only 'device_type'/'dtype' has a device-type-arg list"); 728 Details = DeviceTypeDetails{std::move(Archs)}; 729 } 730 setCollapseDetails(bool IsForce,Expr * LoopCount)731 void setCollapseDetails(bool IsForce, Expr *LoopCount) { 732 assert(ClauseKind == OpenACCClauseKind::Collapse && 733 "Only 'collapse' has collapse details"); 734 Details = CollapseDetails{IsForce, LoopCount}; 735 } 736 setBindDetails(std::variant<std::monostate,clang::StringLiteral *,IdentifierInfo * > Arg)737 void setBindDetails( 738 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *> 739 Arg) { 740 assert(ClauseKind == OpenACCClauseKind::Bind && 741 "Only 'bind' has bind details"); 742 Details = BindDetails{Arg}; 743 } 744 }; 745 746 SemaOpenACC(Sema &S); 747 748 // Called when we encounter a 'while' statement, before looking at its 'body'. 749 void ActOnWhileStmt(SourceLocation WhileLoc); 750 // Called when we encounter a 'do' statement, before looking at its 'body'. 751 void ActOnDoStmt(SourceLocation DoLoc); 752 // Called when we encounter a 'for' statement, before looking at its 'body', 753 // for the 'range-for'. 'ActOnForStmtEnd' is used after the body. 754 void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, 755 const Stmt *RangeFor); 756 void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *RangeFor); 757 // Called when we encounter a 'for' statement, before looking at its 'body'. 758 // 'ActOnForStmtEnd' is used after the body. 759 void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, 760 const Stmt *Second, const Stmt *Third); 761 void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst, 762 const Stmt *First, const Stmt *OldSecond, 763 const Stmt *Second, const Stmt *OldThird, 764 const Stmt *Third); 765 // Called when we encounter a 'for' statement, after we've consumed/checked 766 // the body. This is necessary for a number of checks on the contents of the 767 // 'for' statement. 768 void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body); 769 770 /// Called after parsing an OpenACC Clause so that it can be checked. 771 OpenACCClause *ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses, 772 OpenACCParsedClause &Clause); 773 774 /// Called after the construct has been parsed, but clauses haven't been 775 /// parsed. This allows us to diagnose not-implemented, as well as set up any 776 /// state required for parsing the clauses. 777 void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc); 778 779 /// Called after the directive, including its clauses, have been parsed and 780 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES 781 /// happen before any associated declarations or statements have been parsed. 782 /// This function is only called when we are parsing a 'statement' context. 783 bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, 784 ArrayRef<const OpenACCClause *> Clauses); 785 786 /// Called after the directive, including its clauses, have been parsed and 787 /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES 788 /// happen before any associated declarations or statements have been parsed. 789 /// This function is only called when we are parsing a 'Decl' context. 790 bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, 791 ArrayRef<const OpenACCClause *> Clauses); 792 /// Called when we encounter an associated statement for our construct, this 793 /// should check legality of the statement as it appertains to this Construct. 794 StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, 795 OpenACCDirectiveKind K, 796 OpenACCAtomicKind AtKind, 797 ArrayRef<const OpenACCClause *> Clauses, 798 StmtResult AssocStmt); 799 ActOnAssociatedStmt(SourceLocation DirectiveLoc,OpenACCDirectiveKind K,ArrayRef<const OpenACCClause * > Clauses,StmtResult AssocStmt)800 StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, 801 OpenACCDirectiveKind K, 802 ArrayRef<const OpenACCClause *> Clauses, 803 StmtResult AssocStmt) { 804 return ActOnAssociatedStmt(DirectiveLoc, K, OpenACCAtomicKind::None, 805 Clauses, AssocStmt); 806 } 807 /// Called to check the form of the `atomic` construct which has some fairly 808 /// sizable restrictions. 809 StmtResult CheckAtomicAssociatedStmt(SourceLocation AtomicDirLoc, 810 OpenACCAtomicKind AtKind, 811 StmtResult AssocStmt); 812 813 /// Called after the directive has been completely parsed, including the 814 /// declaration group or associated statement. 815 /// DirLoc: Location of the actual directive keyword. 816 /// LParenLoc: Location of the left paren, if it exists (not on all 817 /// constructs). 818 /// MiscLoc: First misc location, if necessary (not all constructs). 819 /// Exprs: List of expressions on the construct itself, if necessary (not all 820 /// constructs). 821 /// FuncRef: used only for Routine, this is the function being referenced. 822 /// AK: The atomic kind of the directive, if necessary (atomic only) 823 /// RParenLoc: Location of the right paren, if it exists (not on all 824 /// constructs). 825 /// EndLoc: The last source location of the driective. 826 /// Clauses: The list of clauses for the directive, if present. 827 /// AssocStmt: The associated statement for this construct, if necessary. 828 StmtResult ActOnEndStmtDirective( 829 OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, 830 SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs, 831 OpenACCAtomicKind AK, SourceLocation RParenLoc, SourceLocation EndLoc, 832 ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt); 833 834 /// Called after the directive has been completely parsed, including the 835 /// declaration group or associated statement. 836 DeclGroupRef 837 ActOnEndDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, 838 SourceLocation DirLoc, SourceLocation LParenLoc, 839 SourceLocation RParenLoc, SourceLocation EndLoc, 840 ArrayRef<OpenACCClause *> Clauses); 841 842 // Helper functions for ActOnEndRoutine*Directive, which does all the checking 843 // given the proper list of declarations. 844 void CheckRoutineDecl(SourceLocation DirLoc, 845 ArrayRef<const OpenACCClause *> Clauses, 846 Decl *NextParsedDecl); 847 OpenACCRoutineDecl *CheckRoutineDecl(SourceLocation StartLoc, 848 SourceLocation DirLoc, 849 SourceLocation LParenLoc, Expr *FuncRef, 850 SourceLocation RParenLoc, 851 ArrayRef<const OpenACCClause *> Clauses, 852 SourceLocation EndLoc); 853 OpenACCRoutineDeclAttr * 854 mergeRoutineDeclAttr(const OpenACCRoutineDeclAttr &Old); 855 DeclGroupRef 856 ActOnEndRoutineDeclDirective(SourceLocation StartLoc, SourceLocation DirLoc, 857 SourceLocation LParenLoc, Expr *ReferencedFunc, 858 SourceLocation RParenLoc, 859 ArrayRef<const OpenACCClause *> Clauses, 860 SourceLocation EndLoc, DeclGroupPtrTy NextDecl); 861 StmtResult 862 ActOnEndRoutineStmtDirective(SourceLocation StartLoc, SourceLocation DirLoc, 863 SourceLocation LParenLoc, Expr *ReferencedFunc, 864 SourceLocation RParenLoc, 865 ArrayRef<const OpenACCClause *> Clauses, 866 SourceLocation EndLoc, Stmt *NextStmt); 867 868 /// Called when encountering an 'int-expr' for OpenACC, and manages 869 /// conversions and diagnostics to 'int'. 870 ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 871 SourceLocation Loc, Expr *IntExpr); 872 873 /// Called right before a 'var' is parsed, so we can set the state for parsing 874 /// a 'cache' var. 875 void ActOnStartParseVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK); 876 /// Called only if the parse of a 'var' was invalid, else 'ActOnVar' should be 877 /// called. 878 void ActOnInvalidParseVar(); 879 /// Called when encountering a 'var' for OpenACC, ensures it is actually a 880 /// declaration reference to a variable of the correct type. 881 ExprResult ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 882 Expr *VarExpr); 883 /// Helper function called by ActonVar that is used to check a 'cache' var. 884 ExprResult ActOnCacheVar(Expr *VarExpr); 885 /// Function called when a variable declarator is created, which lets us 886 /// implement the 'routine' 'function static variables' restriction. 887 void ActOnVariableDeclarator(VarDecl *VD); 888 /// Called when a function decl is created, which lets us implement the 889 /// 'routine' 'doesn't match next thing' warning. 890 void ActOnFunctionDeclarator(FunctionDecl *FD); 891 /// Called when a variable is initialized, so we can implement the 'routine 892 /// 'doesn't match the next thing' warning for lambda init. 893 void ActOnVariableInit(VarDecl *VD, QualType InitType); 894 895 // Called after 'ActOnVar' specifically for a 'link' clause, which has to do 896 // some minor additional checks. 897 llvm::SmallVector<Expr *> CheckLinkClauseVarList(ArrayRef<Expr *> VarExpr); 898 899 // Checking for the arguments specific to the declare-clause that need to be 900 // checked during both phases of template translation. 901 bool CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause, 902 OpenACCModifierKind Mods); 903 904 ExprResult ActOnRoutineName(Expr *RoutineName); 905 906 /// Called while semantically analyzing the reduction clause, ensuring the var 907 /// is the correct kind of reference. 908 ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind, 909 OpenACCReductionOperator ReductionOp, 910 Expr *VarExpr); 911 912 /// Called to check the 'var' type is a variable of pointer type, necessary 913 /// for 'deviceptr' and 'attach' clauses. Returns true on success. 914 bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr); 915 916 /// Checks and creates an Array Section used in an OpenACC construct/clause. 917 ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, 918 Expr *LowerBound, 919 SourceLocation ColonLocFirst, Expr *Length, 920 SourceLocation RBLoc); 921 /// Checks the loop depth value for a collapse clause. 922 ExprResult CheckCollapseLoopCount(Expr *LoopCount); 923 /// Checks a single size expr for a tile clause. 924 ExprResult CheckTileSizeExpr(Expr *SizeExpr); 925 926 // Check a single expression on a gang clause. 927 ExprResult CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses, 928 OpenACCDirectiveKind DK, OpenACCGangKind GK, 929 Expr *E); 930 931 // Called when a declaration is referenced, so that we can make sure certain 932 // clauses don't do the 'wrong' thing/have incorrect references. 933 void CheckDeclReference(SourceLocation Loc, Expr *E, Decl *D); 934 935 // Does the checking for a 'gang' clause that needs to be done in dependent 936 // and not dependent cases. 937 OpenACCClause * 938 CheckGangClause(OpenACCDirectiveKind DirKind, 939 ArrayRef<const OpenACCClause *> ExistingClauses, 940 SourceLocation BeginLoc, SourceLocation LParenLoc, 941 ArrayRef<OpenACCGangKind> GangKinds, 942 ArrayRef<Expr *> IntExprs, SourceLocation EndLoc); 943 // Does the checking for a 'reduction ' clause that needs to be done in 944 // dependent and not dependent cases. 945 OpenACCClause * 946 CheckReductionClause(ArrayRef<const OpenACCClause *> ExistingClauses, 947 OpenACCDirectiveKind DirectiveKind, 948 SourceLocation BeginLoc, SourceLocation LParenLoc, 949 OpenACCReductionOperator ReductionOp, 950 ArrayRef<Expr *> Vars, SourceLocation EndLoc); 951 952 ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc); 953 ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc); 954 955 /// Helper type to restore the state of various 'loop' constructs when we run 956 /// into a loop (for, etc) inside the construct. 957 class LoopInConstructRAII { 958 SemaOpenACC &SemaRef; 959 LoopCheckingInfo OldLoopInfo; 960 CollapseCheckingInfo OldCollapseInfo; 961 TileCheckingInfo OldTileInfo; 962 bool PreserveDepth; 963 964 public: 965 LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth = true) SemaRef(SemaRef)966 : SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo), 967 OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo), 968 PreserveDepth(PreserveDepth) {} ~LoopInConstructRAII()969 ~LoopInConstructRAII() { 970 // The associated-statement level of this should NOT preserve this, as it 971 // is a new construct, but other loop uses need to preserve the depth so 972 // it makes it to the 'top level' for diagnostics. 973 bool CollapseDepthSatisified = 974 PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied 975 : OldCollapseInfo.CollapseDepthSatisfied; 976 bool TileDepthSatisfied = PreserveDepth 977 ? SemaRef.TileInfo.TileDepthSatisfied 978 : OldTileInfo.TileDepthSatisfied; 979 bool CurLevelHasLoopAlready = 980 PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready 981 : OldLoopInfo.CurLevelHasLoopAlready; 982 983 SemaRef.LoopInfo = OldLoopInfo; 984 SemaRef.CollapseInfo = OldCollapseInfo; 985 SemaRef.TileInfo = OldTileInfo; 986 987 SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified; 988 SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied; 989 SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready; 990 } 991 }; 992 993 /// Helper type for the registration/assignment of constructs that need to 994 /// 'know' about their parent constructs and hold a reference to them, such as 995 /// Loop needing its parent construct. 996 class AssociatedStmtRAII { 997 SemaOpenACC &SemaRef; 998 ComputeConstructInfo OldActiveComputeConstructInfo; 999 OpenACCDirectiveKind DirKind; 1000 LoopGangOnKernelTy OldLoopGangClauseOnKernel; 1001 SourceLocation OldLoopWorkerClauseLoc; 1002 SourceLocation OldLoopVectorClauseLoc; 1003 LoopWithoutSeqCheckingInfo OldLoopWithoutSeqInfo; 1004 llvm::SmallVector<OpenACCReductionClause *> ActiveReductionClauses; 1005 LoopInConstructRAII LoopRAII; 1006 1007 public: 1008 AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind, SourceLocation, 1009 ArrayRef<const OpenACCClause *>, 1010 ArrayRef<OpenACCClause *>); 1011 void SetCollapseInfoBeforeAssociatedStmt( 1012 ArrayRef<const OpenACCClause *> UnInstClauses, 1013 ArrayRef<OpenACCClause *> Clauses); 1014 void SetTileInfoBeforeAssociatedStmt( 1015 ArrayRef<const OpenACCClause *> UnInstClauses, 1016 ArrayRef<OpenACCClause *> Clauses); 1017 ~AssociatedStmtRAII(); 1018 }; 1019 }; 1020 1021 } // namespace clang 1022 1023 #endif // LLVM_CLANG_SEMA_SEMAOPENACC_H 1024