1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP 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 implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 const Decl *PossiblyLoopCounter = nullptr; 143 bool NowaitRegion = false; 144 bool CancelRegion = false; 145 bool LoopStart = false; 146 SourceLocation InnerTeamsRegionLoc; 147 /// Reference to the taskgroup task_reduction reference expression. 148 Expr *TaskgroupReductionRef = nullptr; 149 llvm::DenseSet<QualType> MappedClassesQualTypes; 150 /// List of globals marked as declare target link in this target region 151 /// (isOpenMPTargetExecutionDirective(Directive) == true). 152 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 153 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 154 Scope *CurScope, SourceLocation Loc) 155 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 156 ConstructLoc(Loc) {} 157 SharingMapTy() = default; 158 }; 159 160 using StackTy = SmallVector<SharingMapTy, 4>; 161 162 /// Stack of used declaration and their data-sharing attributes. 163 DeclSAMapTy Threadprivates; 164 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 165 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 166 /// true, if check for DSA must be from parent directive, false, if 167 /// from current directive. 168 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 169 Sema &SemaRef; 170 bool ForceCapturing = false; 171 /// true if all the vaiables in the target executable directives must be 172 /// captured by reference. 173 bool ForceCaptureByReferenceInTargetExecutable = false; 174 CriticalsWithHintsTy Criticals; 175 176 using iterator = StackTy::const_reverse_iterator; 177 178 DSAVarData getDSA(iterator &Iter, ValueDecl *D) const; 179 180 /// Checks if the variable is a local for OpenMP region. 181 bool isOpenMPLocal(VarDecl *D, iterator Iter) const; 182 183 bool isStackEmpty() const { 184 return Stack.empty() || 185 Stack.back().second != CurrentNonCapturingFunctionScope || 186 Stack.back().first.empty(); 187 } 188 189 /// Vector of previously declared requires directives 190 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 191 192 public: 193 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 194 195 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 196 OpenMPClauseKind getClauseParsingMode() const { 197 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 198 return ClauseKindMode; 199 } 200 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 201 202 bool isForceVarCapturing() const { return ForceCapturing; } 203 void setForceVarCapturing(bool V) { ForceCapturing = V; } 204 205 void setForceCaptureByReferenceInTargetExecutable(bool V) { 206 ForceCaptureByReferenceInTargetExecutable = V; 207 } 208 bool isForceCaptureByReferenceInTargetExecutable() const { 209 return ForceCaptureByReferenceInTargetExecutable; 210 } 211 212 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 213 Scope *CurScope, SourceLocation Loc) { 214 if (Stack.empty() || 215 Stack.back().second != CurrentNonCapturingFunctionScope) 216 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 217 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 218 Stack.back().first.back().DefaultAttrLoc = Loc; 219 } 220 221 void pop() { 222 assert(!Stack.back().first.empty() && 223 "Data-sharing attributes stack is empty!"); 224 Stack.back().first.pop_back(); 225 } 226 227 /// Marks that we're started loop parsing. 228 void loopInit() { 229 assert(isOpenMPLoopDirective(getCurrentDirective()) && 230 "Expected loop-based directive."); 231 Stack.back().first.back().LoopStart = true; 232 } 233 /// Start capturing of the variables in the loop context. 234 void loopStart() { 235 assert(isOpenMPLoopDirective(getCurrentDirective()) && 236 "Expected loop-based directive."); 237 Stack.back().first.back().LoopStart = false; 238 } 239 /// true, if variables are captured, false otherwise. 240 bool isLoopStarted() const { 241 assert(isOpenMPLoopDirective(getCurrentDirective()) && 242 "Expected loop-based directive."); 243 return !Stack.back().first.back().LoopStart; 244 } 245 /// Marks (or clears) declaration as possibly loop counter. 246 void resetPossibleLoopCounter(const Decl *D = nullptr) { 247 Stack.back().first.back().PossiblyLoopCounter = 248 D ? D->getCanonicalDecl() : D; 249 } 250 /// Gets the possible loop counter decl. 251 const Decl *getPossiblyLoopCunter() const { 252 return Stack.back().first.back().PossiblyLoopCounter; 253 } 254 /// Start new OpenMP region stack in new non-capturing function. 255 void pushFunction() { 256 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 257 assert(!isa<CapturingScopeInfo>(CurFnScope)); 258 CurrentNonCapturingFunctionScope = CurFnScope; 259 } 260 /// Pop region stack for non-capturing function. 261 void popFunction(const FunctionScopeInfo *OldFSI) { 262 if (!Stack.empty() && Stack.back().second == OldFSI) { 263 assert(Stack.back().first.empty()); 264 Stack.pop_back(); 265 } 266 CurrentNonCapturingFunctionScope = nullptr; 267 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 268 if (!isa<CapturingScopeInfo>(FSI)) { 269 CurrentNonCapturingFunctionScope = FSI; 270 break; 271 } 272 } 273 } 274 275 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 276 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 277 } 278 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 279 getCriticalWithHint(const DeclarationNameInfo &Name) const { 280 auto I = Criticals.find(Name.getAsString()); 281 if (I != Criticals.end()) 282 return I->second; 283 return std::make_pair(nullptr, llvm::APSInt()); 284 } 285 /// If 'aligned' declaration for given variable \a D was not seen yet, 286 /// add it and return NULL; otherwise return previous occurrence's expression 287 /// for diagnostics. 288 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 289 290 /// Register specified variable as loop control variable. 291 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 292 /// Check if the specified variable is a loop control variable for 293 /// current region. 294 /// \return The index of the loop control variable in the list of associated 295 /// for-loops (from outer to inner). 296 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 297 /// Check if the specified variable is a loop control variable for 298 /// parent region. 299 /// \return The index of the loop control variable in the list of associated 300 /// for-loops (from outer to inner). 301 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 302 /// Get the loop control variable for the I-th loop (or nullptr) in 303 /// parent directive. 304 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 305 306 /// Adds explicit data sharing attribute to the specified declaration. 307 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 308 DeclRefExpr *PrivateCopy = nullptr); 309 310 /// Adds additional information for the reduction items with the reduction id 311 /// represented as an operator. 312 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 313 BinaryOperatorKind BOK); 314 /// Adds additional information for the reduction items with the reduction id 315 /// represented as reduction identifier. 316 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 317 const Expr *ReductionRef); 318 /// Returns the location and reduction operation from the innermost parent 319 /// region for the given \p D. 320 const DSAVarData 321 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 322 BinaryOperatorKind &BOK, 323 Expr *&TaskgroupDescriptor) const; 324 /// Returns the location and reduction operation from the innermost parent 325 /// region for the given \p D. 326 const DSAVarData 327 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 328 const Expr *&ReductionRef, 329 Expr *&TaskgroupDescriptor) const; 330 /// Return reduction reference expression for the current taskgroup. 331 Expr *getTaskgroupReductionRef() const { 332 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 333 "taskgroup reference expression requested for non taskgroup " 334 "directive."); 335 return Stack.back().first.back().TaskgroupReductionRef; 336 } 337 /// Checks if the given \p VD declaration is actually a taskgroup reduction 338 /// descriptor variable at the \p Level of OpenMP regions. 339 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 340 return Stack.back().first[Level].TaskgroupReductionRef && 341 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 342 ->getDecl() == VD; 343 } 344 345 /// Returns data sharing attributes from top of the stack for the 346 /// specified declaration. 347 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 348 /// Returns data-sharing attributes for the specified declaration. 349 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 350 /// Checks if the specified variables has data-sharing attributes which 351 /// match specified \a CPred predicate in any directive which matches \a DPred 352 /// predicate. 353 const DSAVarData 354 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 355 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 356 bool FromParent) const; 357 /// Checks if the specified variables has data-sharing attributes which 358 /// match specified \a CPred predicate in any innermost directive which 359 /// matches \a DPred predicate. 360 const DSAVarData 361 hasInnermostDSA(ValueDecl *D, 362 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 363 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 364 bool FromParent) const; 365 /// Checks if the specified variables has explicit data-sharing 366 /// attributes which match specified \a CPred predicate at the specified 367 /// OpenMP region. 368 bool hasExplicitDSA(const ValueDecl *D, 369 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 370 unsigned Level, bool NotLastprivate = false) const; 371 372 /// Returns true if the directive at level \Level matches in the 373 /// specified \a DPred predicate. 374 bool hasExplicitDirective( 375 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 376 unsigned Level) const; 377 378 /// Finds a directive which matches specified \a DPred predicate. 379 bool hasDirective( 380 const llvm::function_ref<bool( 381 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 382 DPred, 383 bool FromParent) const; 384 385 /// Returns currently analyzed directive. 386 OpenMPDirectiveKind getCurrentDirective() const { 387 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 388 } 389 /// Returns directive kind at specified level. 390 OpenMPDirectiveKind getDirective(unsigned Level) const { 391 assert(!isStackEmpty() && "No directive at specified level."); 392 return Stack.back().first[Level].Directive; 393 } 394 /// Returns parent directive. 395 OpenMPDirectiveKind getParentDirective() const { 396 if (isStackEmpty() || Stack.back().first.size() == 1) 397 return OMPD_unknown; 398 return std::next(Stack.back().first.rbegin())->Directive; 399 } 400 401 /// Add requires decl to internal vector 402 void addRequiresDecl(OMPRequiresDecl *RD) { 403 RequiresDecls.push_back(RD); 404 } 405 406 /// Checks for a duplicate clause amongst previously declared requires 407 /// directives 408 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 409 bool IsDuplicate = false; 410 for (OMPClause *CNew : ClauseList) { 411 for (const OMPRequiresDecl *D : RequiresDecls) { 412 for (const OMPClause *CPrev : D->clauselists()) { 413 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 414 SemaRef.Diag(CNew->getBeginLoc(), 415 diag::err_omp_requires_clause_redeclaration) 416 << getOpenMPClauseName(CNew->getClauseKind()); 417 SemaRef.Diag(CPrev->getBeginLoc(), 418 diag::note_omp_requires_previous_clause) 419 << getOpenMPClauseName(CPrev->getClauseKind()); 420 IsDuplicate = true; 421 } 422 } 423 } 424 } 425 return IsDuplicate; 426 } 427 428 /// Set default data sharing attribute to none. 429 void setDefaultDSANone(SourceLocation Loc) { 430 assert(!isStackEmpty()); 431 Stack.back().first.back().DefaultAttr = DSA_none; 432 Stack.back().first.back().DefaultAttrLoc = Loc; 433 } 434 /// Set default data sharing attribute to shared. 435 void setDefaultDSAShared(SourceLocation Loc) { 436 assert(!isStackEmpty()); 437 Stack.back().first.back().DefaultAttr = DSA_shared; 438 Stack.back().first.back().DefaultAttrLoc = Loc; 439 } 440 /// Set default data mapping attribute to 'tofrom:scalar'. 441 void setDefaultDMAToFromScalar(SourceLocation Loc) { 442 assert(!isStackEmpty()); 443 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 444 Stack.back().first.back().DefaultMapAttrLoc = Loc; 445 } 446 447 DefaultDataSharingAttributes getDefaultDSA() const { 448 return isStackEmpty() ? DSA_unspecified 449 : Stack.back().first.back().DefaultAttr; 450 } 451 SourceLocation getDefaultDSALocation() const { 452 return isStackEmpty() ? SourceLocation() 453 : Stack.back().first.back().DefaultAttrLoc; 454 } 455 DefaultMapAttributes getDefaultDMA() const { 456 return isStackEmpty() ? DMA_unspecified 457 : Stack.back().first.back().DefaultMapAttr; 458 } 459 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 460 return Stack.back().first[Level].DefaultMapAttr; 461 } 462 SourceLocation getDefaultDMALocation() const { 463 return isStackEmpty() ? SourceLocation() 464 : Stack.back().first.back().DefaultMapAttrLoc; 465 } 466 467 /// Checks if the specified variable is a threadprivate. 468 bool isThreadPrivate(VarDecl *D) { 469 const DSAVarData DVar = getTopDSA(D, false); 470 return isOpenMPThreadPrivate(DVar.CKind); 471 } 472 473 /// Marks current region as ordered (it has an 'ordered' clause). 474 void setOrderedRegion(bool IsOrdered, const Expr *Param, 475 OMPOrderedClause *Clause) { 476 assert(!isStackEmpty()); 477 if (IsOrdered) 478 Stack.back().first.back().OrderedRegion.emplace(Param, Clause); 479 else 480 Stack.back().first.back().OrderedRegion.reset(); 481 } 482 /// Returns true, if region is ordered (has associated 'ordered' clause), 483 /// false - otherwise. 484 bool isOrderedRegion() const { 485 if (isStackEmpty()) 486 return false; 487 return Stack.back().first.rbegin()->OrderedRegion.hasValue(); 488 } 489 /// Returns optional parameter for the ordered region. 490 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 491 if (isStackEmpty() || 492 !Stack.back().first.rbegin()->OrderedRegion.hasValue()) 493 return std::make_pair(nullptr, nullptr); 494 return Stack.back().first.rbegin()->OrderedRegion.getValue(); 495 } 496 /// Returns true, if parent region is ordered (has associated 497 /// 'ordered' clause), false - otherwise. 498 bool isParentOrderedRegion() const { 499 if (isStackEmpty() || Stack.back().first.size() == 1) 500 return false; 501 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); 502 } 503 /// Returns optional parameter for the ordered region. 504 std::pair<const Expr *, OMPOrderedClause *> 505 getParentOrderedRegionParam() const { 506 if (isStackEmpty() || Stack.back().first.size() == 1 || 507 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) 508 return std::make_pair(nullptr, nullptr); 509 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); 510 } 511 /// Marks current region as nowait (it has a 'nowait' clause). 512 void setNowaitRegion(bool IsNowait = true) { 513 assert(!isStackEmpty()); 514 Stack.back().first.back().NowaitRegion = IsNowait; 515 } 516 /// Returns true, if parent region is nowait (has associated 517 /// 'nowait' clause), false - otherwise. 518 bool isParentNowaitRegion() const { 519 if (isStackEmpty() || Stack.back().first.size() == 1) 520 return false; 521 return std::next(Stack.back().first.rbegin())->NowaitRegion; 522 } 523 /// Marks parent region as cancel region. 524 void setParentCancelRegion(bool Cancel = true) { 525 if (!isStackEmpty() && Stack.back().first.size() > 1) { 526 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 527 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 528 } 529 } 530 /// Return true if current region has inner cancel construct. 531 bool isCancelRegion() const { 532 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 533 } 534 535 /// Set collapse value for the region. 536 void setAssociatedLoops(unsigned Val) { 537 assert(!isStackEmpty()); 538 Stack.back().first.back().AssociatedLoops = Val; 539 } 540 /// Return collapse value for region. 541 unsigned getAssociatedLoops() const { 542 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 543 } 544 545 /// Marks current target region as one with closely nested teams 546 /// region. 547 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 548 if (!isStackEmpty() && Stack.back().first.size() > 1) { 549 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 550 TeamsRegionLoc; 551 } 552 } 553 /// Returns true, if current region has closely nested teams region. 554 bool hasInnerTeamsRegion() const { 555 return getInnerTeamsRegionLoc().isValid(); 556 } 557 /// Returns location of the nested teams region (if any). 558 SourceLocation getInnerTeamsRegionLoc() const { 559 return isStackEmpty() ? SourceLocation() 560 : Stack.back().first.back().InnerTeamsRegionLoc; 561 } 562 563 Scope *getCurScope() const { 564 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 565 } 566 SourceLocation getConstructLoc() const { 567 return isStackEmpty() ? SourceLocation() 568 : Stack.back().first.back().ConstructLoc; 569 } 570 571 /// Do the check specified in \a Check to all component lists and return true 572 /// if any issue is found. 573 bool checkMappableExprComponentListsForDecl( 574 const ValueDecl *VD, bool CurrentRegionOnly, 575 const llvm::function_ref< 576 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 577 OpenMPClauseKind)> 578 Check) const { 579 if (isStackEmpty()) 580 return false; 581 auto SI = Stack.back().first.rbegin(); 582 auto SE = Stack.back().first.rend(); 583 584 if (SI == SE) 585 return false; 586 587 if (CurrentRegionOnly) 588 SE = std::next(SI); 589 else 590 std::advance(SI, 1); 591 592 for (; SI != SE; ++SI) { 593 auto MI = SI->MappedExprComponents.find(VD); 594 if (MI != SI->MappedExprComponents.end()) 595 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 596 MI->second.Components) 597 if (Check(L, MI->second.Kind)) 598 return true; 599 } 600 return false; 601 } 602 603 /// Do the check specified in \a Check to all component lists at a given level 604 /// and return true if any issue is found. 605 bool checkMappableExprComponentListsForDeclAtLevel( 606 const ValueDecl *VD, unsigned Level, 607 const llvm::function_ref< 608 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 609 OpenMPClauseKind)> 610 Check) const { 611 if (isStackEmpty()) 612 return false; 613 614 auto StartI = Stack.back().first.begin(); 615 auto EndI = Stack.back().first.end(); 616 if (std::distance(StartI, EndI) <= (int)Level) 617 return false; 618 std::advance(StartI, Level); 619 620 auto MI = StartI->MappedExprComponents.find(VD); 621 if (MI != StartI->MappedExprComponents.end()) 622 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 623 MI->second.Components) 624 if (Check(L, MI->second.Kind)) 625 return true; 626 return false; 627 } 628 629 /// Create a new mappable expression component list associated with a given 630 /// declaration and initialize it with the provided list of components. 631 void addMappableExpressionComponents( 632 const ValueDecl *VD, 633 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 634 OpenMPClauseKind WhereFoundClauseKind) { 635 assert(!isStackEmpty() && 636 "Not expecting to retrieve components from a empty stack!"); 637 MappedExprComponentTy &MEC = 638 Stack.back().first.back().MappedExprComponents[VD]; 639 // Create new entry and append the new components there. 640 MEC.Components.resize(MEC.Components.size() + 1); 641 MEC.Components.back().append(Components.begin(), Components.end()); 642 MEC.Kind = WhereFoundClauseKind; 643 } 644 645 unsigned getNestingLevel() const { 646 assert(!isStackEmpty()); 647 return Stack.back().first.size() - 1; 648 } 649 void addDoacrossDependClause(OMPDependClause *C, 650 const OperatorOffsetTy &OpsOffs) { 651 assert(!isStackEmpty() && Stack.back().first.size() > 1); 652 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 653 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 654 StackElem.DoacrossDepends.try_emplace(C, OpsOffs); 655 } 656 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 657 getDoacrossDependClauses() const { 658 assert(!isStackEmpty()); 659 const SharingMapTy &StackElem = Stack.back().first.back(); 660 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 661 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 662 return llvm::make_range(Ref.begin(), Ref.end()); 663 } 664 return llvm::make_range(StackElem.DoacrossDepends.end(), 665 StackElem.DoacrossDepends.end()); 666 } 667 668 // Store types of classes which have been explicitly mapped 669 void addMappedClassesQualTypes(QualType QT) { 670 SharingMapTy &StackElem = Stack.back().first.back(); 671 StackElem.MappedClassesQualTypes.insert(QT); 672 } 673 674 // Return set of mapped classes types 675 bool isClassPreviouslyMapped(QualType QT) const { 676 const SharingMapTy &StackElem = Stack.back().first.back(); 677 return StackElem.MappedClassesQualTypes.count(QT) != 0; 678 } 679 680 /// Adds global declare target to the parent target region. 681 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 682 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 683 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 684 "Expected declare target link global."); 685 if (isStackEmpty()) 686 return; 687 auto It = Stack.back().first.rbegin(); 688 while (It != Stack.back().first.rend() && 689 !isOpenMPTargetExecutionDirective(It->Directive)) 690 ++It; 691 if (It != Stack.back().first.rend()) { 692 assert(isOpenMPTargetExecutionDirective(It->Directive) && 693 "Expected target executable directive."); 694 It->DeclareTargetLinkVarDecls.push_back(E); 695 } 696 } 697 698 /// Returns the list of globals with declare target link if current directive 699 /// is target. 700 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 701 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 702 "Expected target executable directive."); 703 return Stack.back().first.back().DeclareTargetLinkVarDecls; 704 } 705 }; 706 707 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 708 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 709 } 710 711 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 712 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown; 713 } 714 715 } // namespace 716 717 static const Expr *getExprAsWritten(const Expr *E) { 718 if (const auto *FE = dyn_cast<FullExpr>(E)) 719 E = FE->getSubExpr(); 720 721 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 722 E = MTE->GetTemporaryExpr(); 723 724 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 725 E = Binder->getSubExpr(); 726 727 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 728 E = ICE->getSubExprAsWritten(); 729 return E->IgnoreParens(); 730 } 731 732 static Expr *getExprAsWritten(Expr *E) { 733 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 734 } 735 736 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 737 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 738 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 739 D = ME->getMemberDecl(); 740 const auto *VD = dyn_cast<VarDecl>(D); 741 const auto *FD = dyn_cast<FieldDecl>(D); 742 if (VD != nullptr) { 743 VD = VD->getCanonicalDecl(); 744 D = VD; 745 } else { 746 assert(FD); 747 FD = FD->getCanonicalDecl(); 748 D = FD; 749 } 750 return D; 751 } 752 753 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 754 return const_cast<ValueDecl *>( 755 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 756 } 757 758 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 759 ValueDecl *D) const { 760 D = getCanonicalDecl(D); 761 auto *VD = dyn_cast<VarDecl>(D); 762 const auto *FD = dyn_cast<FieldDecl>(D); 763 DSAVarData DVar; 764 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 765 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 766 // in a region but not in construct] 767 // File-scope or namespace-scope variables referenced in called routines 768 // in the region are shared unless they appear in a threadprivate 769 // directive. 770 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 771 DVar.CKind = OMPC_shared; 772 773 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 774 // in a region but not in construct] 775 // Variables with static storage duration that are declared in called 776 // routines in the region are shared. 777 if (VD && VD->hasGlobalStorage()) 778 DVar.CKind = OMPC_shared; 779 780 // Non-static data members are shared by default. 781 if (FD) 782 DVar.CKind = OMPC_shared; 783 784 return DVar; 785 } 786 787 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 788 // in a Construct, C/C++, predetermined, p.1] 789 // Variables with automatic storage duration that are declared in a scope 790 // inside the construct are private. 791 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 792 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 793 DVar.CKind = OMPC_private; 794 return DVar; 795 } 796 797 DVar.DKind = Iter->Directive; 798 // Explicitly specified attributes and local variables with predetermined 799 // attributes. 800 if (Iter->SharingMap.count(D)) { 801 const DSAInfo &Data = Iter->SharingMap.lookup(D); 802 DVar.RefExpr = Data.RefExpr.getPointer(); 803 DVar.PrivateCopy = Data.PrivateCopy; 804 DVar.CKind = Data.Attributes; 805 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 806 return DVar; 807 } 808 809 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 810 // in a Construct, C/C++, implicitly determined, p.1] 811 // In a parallel or task construct, the data-sharing attributes of these 812 // variables are determined by the default clause, if present. 813 switch (Iter->DefaultAttr) { 814 case DSA_shared: 815 DVar.CKind = OMPC_shared; 816 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 817 return DVar; 818 case DSA_none: 819 return DVar; 820 case DSA_unspecified: 821 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 822 // in a Construct, implicitly determined, p.2] 823 // In a parallel construct, if no default clause is present, these 824 // variables are shared. 825 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 826 if (isOpenMPParallelDirective(DVar.DKind) || 827 isOpenMPTeamsDirective(DVar.DKind)) { 828 DVar.CKind = OMPC_shared; 829 return DVar; 830 } 831 832 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 833 // in a Construct, implicitly determined, p.4] 834 // In a task construct, if no default clause is present, a variable that in 835 // the enclosing context is determined to be shared by all implicit tasks 836 // bound to the current team is shared. 837 if (isOpenMPTaskingDirective(DVar.DKind)) { 838 DSAVarData DVarTemp; 839 iterator I = Iter, E = Stack.back().first.rend(); 840 do { 841 ++I; 842 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 843 // Referenced in a Construct, implicitly determined, p.6] 844 // In a task construct, if no default clause is present, a variable 845 // whose data-sharing attribute is not determined by the rules above is 846 // firstprivate. 847 DVarTemp = getDSA(I, D); 848 if (DVarTemp.CKind != OMPC_shared) { 849 DVar.RefExpr = nullptr; 850 DVar.CKind = OMPC_firstprivate; 851 return DVar; 852 } 853 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 854 DVar.CKind = 855 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 856 return DVar; 857 } 858 } 859 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 860 // in a Construct, implicitly determined, p.3] 861 // For constructs other than task, if no default clause is present, these 862 // variables inherit their data-sharing attributes from the enclosing 863 // context. 864 return getDSA(++Iter, D); 865 } 866 867 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 868 const Expr *NewDE) { 869 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 870 D = getCanonicalDecl(D); 871 SharingMapTy &StackElem = Stack.back().first.back(); 872 auto It = StackElem.AlignedMap.find(D); 873 if (It == StackElem.AlignedMap.end()) { 874 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 875 StackElem.AlignedMap[D] = NewDE; 876 return nullptr; 877 } 878 assert(It->second && "Unexpected nullptr expr in the aligned map"); 879 return It->second; 880 } 881 882 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 883 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 884 D = getCanonicalDecl(D); 885 SharingMapTy &StackElem = Stack.back().first.back(); 886 StackElem.LCVMap.try_emplace( 887 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 888 } 889 890 const DSAStackTy::LCDeclInfo 891 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 892 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 893 D = getCanonicalDecl(D); 894 const SharingMapTy &StackElem = Stack.back().first.back(); 895 auto It = StackElem.LCVMap.find(D); 896 if (It != StackElem.LCVMap.end()) 897 return It->second; 898 return {0, nullptr}; 899 } 900 901 const DSAStackTy::LCDeclInfo 902 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 903 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 904 "Data-sharing attributes stack is empty"); 905 D = getCanonicalDecl(D); 906 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 907 auto It = StackElem.LCVMap.find(D); 908 if (It != StackElem.LCVMap.end()) 909 return It->second; 910 return {0, nullptr}; 911 } 912 913 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 914 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 915 "Data-sharing attributes stack is empty"); 916 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 917 if (StackElem.LCVMap.size() < I) 918 return nullptr; 919 for (const auto &Pair : StackElem.LCVMap) 920 if (Pair.second.first == I) 921 return Pair.first; 922 return nullptr; 923 } 924 925 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 926 DeclRefExpr *PrivateCopy) { 927 D = getCanonicalDecl(D); 928 if (A == OMPC_threadprivate) { 929 DSAInfo &Data = Threadprivates[D]; 930 Data.Attributes = A; 931 Data.RefExpr.setPointer(E); 932 Data.PrivateCopy = nullptr; 933 } else { 934 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 935 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 936 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 937 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 938 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 939 (isLoopControlVariable(D).first && A == OMPC_private)); 940 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 941 Data.RefExpr.setInt(/*IntVal=*/true); 942 return; 943 } 944 const bool IsLastprivate = 945 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 946 Data.Attributes = A; 947 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 948 Data.PrivateCopy = PrivateCopy; 949 if (PrivateCopy) { 950 DSAInfo &Data = 951 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 952 Data.Attributes = A; 953 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 954 Data.PrivateCopy = nullptr; 955 } 956 } 957 } 958 959 /// Build a variable declaration for OpenMP loop iteration variable. 960 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 961 StringRef Name, const AttrVec *Attrs = nullptr, 962 DeclRefExpr *OrigRef = nullptr) { 963 DeclContext *DC = SemaRef.CurContext; 964 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 965 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 966 auto *Decl = 967 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 968 if (Attrs) { 969 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 970 I != E; ++I) 971 Decl->addAttr(*I); 972 } 973 Decl->setImplicit(); 974 if (OrigRef) { 975 Decl->addAttr( 976 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 977 } 978 return Decl; 979 } 980 981 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 982 SourceLocation Loc, 983 bool RefersToCapture = false) { 984 D->setReferenced(); 985 D->markUsed(S.Context); 986 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 987 SourceLocation(), D, RefersToCapture, Loc, Ty, 988 VK_LValue); 989 } 990 991 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 992 BinaryOperatorKind BOK) { 993 D = getCanonicalDecl(D); 994 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 995 assert( 996 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 997 "Additional reduction info may be specified only for reduction items."); 998 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 999 assert(ReductionData.ReductionRange.isInvalid() && 1000 Stack.back().first.back().Directive == OMPD_taskgroup && 1001 "Additional reduction info may be specified only once for reduction " 1002 "items."); 1003 ReductionData.set(BOK, SR); 1004 Expr *&TaskgroupReductionRef = 1005 Stack.back().first.back().TaskgroupReductionRef; 1006 if (!TaskgroupReductionRef) { 1007 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1008 SemaRef.Context.VoidPtrTy, ".task_red."); 1009 TaskgroupReductionRef = 1010 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1011 } 1012 } 1013 1014 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1015 const Expr *ReductionRef) { 1016 D = getCanonicalDecl(D); 1017 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1018 assert( 1019 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1020 "Additional reduction info may be specified only for reduction items."); 1021 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1022 assert(ReductionData.ReductionRange.isInvalid() && 1023 Stack.back().first.back().Directive == OMPD_taskgroup && 1024 "Additional reduction info may be specified only once for reduction " 1025 "items."); 1026 ReductionData.set(ReductionRef, SR); 1027 Expr *&TaskgroupReductionRef = 1028 Stack.back().first.back().TaskgroupReductionRef; 1029 if (!TaskgroupReductionRef) { 1030 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1031 SemaRef.Context.VoidPtrTy, ".task_red."); 1032 TaskgroupReductionRef = 1033 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1034 } 1035 } 1036 1037 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1038 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1039 Expr *&TaskgroupDescriptor) const { 1040 D = getCanonicalDecl(D); 1041 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1042 if (Stack.back().first.empty()) 1043 return DSAVarData(); 1044 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1045 E = Stack.back().first.rend(); 1046 I != E; std::advance(I, 1)) { 1047 const DSAInfo &Data = I->SharingMap.lookup(D); 1048 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1049 continue; 1050 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1051 if (!ReductionData.ReductionOp || 1052 ReductionData.ReductionOp.is<const Expr *>()) 1053 return DSAVarData(); 1054 SR = ReductionData.ReductionRange; 1055 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1056 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1057 "expression for the descriptor is not " 1058 "set."); 1059 TaskgroupDescriptor = I->TaskgroupReductionRef; 1060 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1061 Data.PrivateCopy, I->DefaultAttrLoc); 1062 } 1063 return DSAVarData(); 1064 } 1065 1066 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1067 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1068 Expr *&TaskgroupDescriptor) const { 1069 D = getCanonicalDecl(D); 1070 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1071 if (Stack.back().first.empty()) 1072 return DSAVarData(); 1073 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1074 E = Stack.back().first.rend(); 1075 I != E; std::advance(I, 1)) { 1076 const DSAInfo &Data = I->SharingMap.lookup(D); 1077 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1078 continue; 1079 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1080 if (!ReductionData.ReductionOp || 1081 !ReductionData.ReductionOp.is<const Expr *>()) 1082 return DSAVarData(); 1083 SR = ReductionData.ReductionRange; 1084 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1085 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1086 "expression for the descriptor is not " 1087 "set."); 1088 TaskgroupDescriptor = I->TaskgroupReductionRef; 1089 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1090 Data.PrivateCopy, I->DefaultAttrLoc); 1091 } 1092 return DSAVarData(); 1093 } 1094 1095 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 1096 D = D->getCanonicalDecl(); 1097 if (!isStackEmpty()) { 1098 iterator I = Iter, E = Stack.back().first.rend(); 1099 Scope *TopScope = nullptr; 1100 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) && 1101 !isOpenMPTargetExecutionDirective(I->Directive)) 1102 ++I; 1103 if (I == E) 1104 return false; 1105 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1106 Scope *CurScope = getCurScope(); 1107 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 1108 CurScope = CurScope->getParent(); 1109 return CurScope != TopScope; 1110 } 1111 return false; 1112 } 1113 1114 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1115 bool AcceptIfMutable = true, 1116 bool *IsClassType = nullptr) { 1117 ASTContext &Context = SemaRef.getASTContext(); 1118 Type = Type.getNonReferenceType().getCanonicalType(); 1119 bool IsConstant = Type.isConstant(Context); 1120 Type = Context.getBaseElementType(Type); 1121 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1122 ? Type->getAsCXXRecordDecl() 1123 : nullptr; 1124 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1125 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1126 RD = CTD->getTemplatedDecl(); 1127 if (IsClassType) 1128 *IsClassType = RD; 1129 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1130 RD->hasDefinition() && RD->hasMutableFields()); 1131 } 1132 1133 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1134 QualType Type, OpenMPClauseKind CKind, 1135 SourceLocation ELoc, 1136 bool AcceptIfMutable = true, 1137 bool ListItemNotVar = false) { 1138 ASTContext &Context = SemaRef.getASTContext(); 1139 bool IsClassType; 1140 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1141 unsigned Diag = ListItemNotVar 1142 ? diag::err_omp_const_list_item 1143 : IsClassType ? diag::err_omp_const_not_mutable_variable 1144 : diag::err_omp_const_variable; 1145 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1146 if (!ListItemNotVar && D) { 1147 const VarDecl *VD = dyn_cast<VarDecl>(D); 1148 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1149 VarDecl::DeclarationOnly; 1150 SemaRef.Diag(D->getLocation(), 1151 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1152 << D; 1153 } 1154 return true; 1155 } 1156 return false; 1157 } 1158 1159 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1160 bool FromParent) { 1161 D = getCanonicalDecl(D); 1162 DSAVarData DVar; 1163 1164 auto *VD = dyn_cast<VarDecl>(D); 1165 auto TI = Threadprivates.find(D); 1166 if (TI != Threadprivates.end()) { 1167 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1168 DVar.CKind = OMPC_threadprivate; 1169 return DVar; 1170 } 1171 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1172 DVar.RefExpr = buildDeclRefExpr( 1173 SemaRef, VD, D->getType().getNonReferenceType(), 1174 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1175 DVar.CKind = OMPC_threadprivate; 1176 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1177 return DVar; 1178 } 1179 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1180 // in a Construct, C/C++, predetermined, p.1] 1181 // Variables appearing in threadprivate directives are threadprivate. 1182 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1183 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1184 SemaRef.getLangOpts().OpenMPUseTLS && 1185 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1186 (VD && VD->getStorageClass() == SC_Register && 1187 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1188 DVar.RefExpr = buildDeclRefExpr( 1189 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1190 DVar.CKind = OMPC_threadprivate; 1191 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1192 return DVar; 1193 } 1194 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1195 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1196 !isLoopControlVariable(D).first) { 1197 iterator IterTarget = 1198 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1199 [](const SharingMapTy &Data) { 1200 return isOpenMPTargetExecutionDirective(Data.Directive); 1201 }); 1202 if (IterTarget != Stack.back().first.rend()) { 1203 iterator ParentIterTarget = std::next(IterTarget, 1); 1204 for (iterator Iter = Stack.back().first.rbegin(); 1205 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1206 if (isOpenMPLocal(VD, Iter)) { 1207 DVar.RefExpr = 1208 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1209 D->getLocation()); 1210 DVar.CKind = OMPC_threadprivate; 1211 return DVar; 1212 } 1213 } 1214 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1215 auto DSAIter = IterTarget->SharingMap.find(D); 1216 if (DSAIter != IterTarget->SharingMap.end() && 1217 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1218 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1219 DVar.CKind = OMPC_threadprivate; 1220 return DVar; 1221 } 1222 iterator End = Stack.back().first.rend(); 1223 if (!SemaRef.isOpenMPCapturedByRef( 1224 D, std::distance(ParentIterTarget, End))) { 1225 DVar.RefExpr = 1226 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1227 IterTarget->ConstructLoc); 1228 DVar.CKind = OMPC_threadprivate; 1229 return DVar; 1230 } 1231 } 1232 } 1233 } 1234 1235 if (isStackEmpty()) 1236 // Not in OpenMP execution region and top scope was already checked. 1237 return DVar; 1238 1239 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1240 // in a Construct, C/C++, predetermined, p.4] 1241 // Static data members are shared. 1242 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1243 // in a Construct, C/C++, predetermined, p.7] 1244 // Variables with static storage duration that are declared in a scope 1245 // inside the construct are shared. 1246 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1247 if (VD && VD->isStaticDataMember()) { 1248 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1249 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1250 return DVar; 1251 1252 DVar.CKind = OMPC_shared; 1253 return DVar; 1254 } 1255 1256 // The predetermined shared attribute for const-qualified types having no 1257 // mutable members was removed after OpenMP 3.1. 1258 if (SemaRef.LangOpts.OpenMP <= 31) { 1259 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1260 // in a Construct, C/C++, predetermined, p.6] 1261 // Variables with const qualified type having no mutable member are 1262 // shared. 1263 if (isConstNotMutableType(SemaRef, D->getType())) { 1264 // Variables with const-qualified type having no mutable member may be 1265 // listed in a firstprivate clause, even if they are static data members. 1266 DSAVarData DVarTemp = hasInnermostDSA( 1267 D, 1268 [](OpenMPClauseKind C) { 1269 return C == OMPC_firstprivate || C == OMPC_shared; 1270 }, 1271 MatchesAlways, FromParent); 1272 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1273 return DVarTemp; 1274 1275 DVar.CKind = OMPC_shared; 1276 return DVar; 1277 } 1278 } 1279 1280 // Explicitly specified attributes and local variables with predetermined 1281 // attributes. 1282 iterator I = Stack.back().first.rbegin(); 1283 iterator EndI = Stack.back().first.rend(); 1284 if (FromParent && I != EndI) 1285 std::advance(I, 1); 1286 auto It = I->SharingMap.find(D); 1287 if (It != I->SharingMap.end()) { 1288 const DSAInfo &Data = It->getSecond(); 1289 DVar.RefExpr = Data.RefExpr.getPointer(); 1290 DVar.PrivateCopy = Data.PrivateCopy; 1291 DVar.CKind = Data.Attributes; 1292 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1293 DVar.DKind = I->Directive; 1294 } 1295 1296 return DVar; 1297 } 1298 1299 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1300 bool FromParent) const { 1301 if (isStackEmpty()) { 1302 iterator I; 1303 return getDSA(I, D); 1304 } 1305 D = getCanonicalDecl(D); 1306 iterator StartI = Stack.back().first.rbegin(); 1307 iterator EndI = Stack.back().first.rend(); 1308 if (FromParent && StartI != EndI) 1309 std::advance(StartI, 1); 1310 return getDSA(StartI, D); 1311 } 1312 1313 const DSAStackTy::DSAVarData 1314 DSAStackTy::hasDSA(ValueDecl *D, 1315 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1316 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1317 bool FromParent) const { 1318 if (isStackEmpty()) 1319 return {}; 1320 D = getCanonicalDecl(D); 1321 iterator I = Stack.back().first.rbegin(); 1322 iterator EndI = Stack.back().first.rend(); 1323 if (FromParent && I != EndI) 1324 std::advance(I, 1); 1325 for (; I != EndI; std::advance(I, 1)) { 1326 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive)) 1327 continue; 1328 iterator NewI = I; 1329 DSAVarData DVar = getDSA(NewI, D); 1330 if (I == NewI && CPred(DVar.CKind)) 1331 return DVar; 1332 } 1333 return {}; 1334 } 1335 1336 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1337 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1338 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1339 bool FromParent) const { 1340 if (isStackEmpty()) 1341 return {}; 1342 D = getCanonicalDecl(D); 1343 iterator StartI = Stack.back().first.rbegin(); 1344 iterator EndI = Stack.back().first.rend(); 1345 if (FromParent && StartI != EndI) 1346 std::advance(StartI, 1); 1347 if (StartI == EndI || !DPred(StartI->Directive)) 1348 return {}; 1349 iterator NewI = StartI; 1350 DSAVarData DVar = getDSA(NewI, D); 1351 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1352 } 1353 1354 bool DSAStackTy::hasExplicitDSA( 1355 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1356 unsigned Level, bool NotLastprivate) const { 1357 if (isStackEmpty()) 1358 return false; 1359 D = getCanonicalDecl(D); 1360 auto StartI = Stack.back().first.begin(); 1361 auto EndI = Stack.back().first.end(); 1362 if (std::distance(StartI, EndI) <= (int)Level) 1363 return false; 1364 std::advance(StartI, Level); 1365 auto I = StartI->SharingMap.find(D); 1366 if ((I != StartI->SharingMap.end()) && 1367 I->getSecond().RefExpr.getPointer() && 1368 CPred(I->getSecond().Attributes) && 1369 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1370 return true; 1371 // Check predetermined rules for the loop control variables. 1372 auto LI = StartI->LCVMap.find(D); 1373 if (LI != StartI->LCVMap.end()) 1374 return CPred(OMPC_private); 1375 return false; 1376 } 1377 1378 bool DSAStackTy::hasExplicitDirective( 1379 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1380 unsigned Level) const { 1381 if (isStackEmpty()) 1382 return false; 1383 auto StartI = Stack.back().first.begin(); 1384 auto EndI = Stack.back().first.end(); 1385 if (std::distance(StartI, EndI) <= (int)Level) 1386 return false; 1387 std::advance(StartI, Level); 1388 return DPred(StartI->Directive); 1389 } 1390 1391 bool DSAStackTy::hasDirective( 1392 const llvm::function_ref<bool(OpenMPDirectiveKind, 1393 const DeclarationNameInfo &, SourceLocation)> 1394 DPred, 1395 bool FromParent) const { 1396 // We look only in the enclosing region. 1397 if (isStackEmpty()) 1398 return false; 1399 auto StartI = std::next(Stack.back().first.rbegin()); 1400 auto EndI = Stack.back().first.rend(); 1401 if (FromParent && StartI != EndI) 1402 StartI = std::next(StartI); 1403 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1404 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1405 return true; 1406 } 1407 return false; 1408 } 1409 1410 void Sema::InitDataSharingAttributesStack() { 1411 VarDataSharingAttributesStack = new DSAStackTy(*this); 1412 } 1413 1414 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1415 1416 void Sema::pushOpenMPFunctionRegion() { 1417 DSAStack->pushFunction(); 1418 } 1419 1420 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1421 DSAStack->popFunction(OldFSI); 1422 } 1423 1424 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1425 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1426 "Expected OpenMP device compilation."); 1427 return !S.isInOpenMPTargetExecutionDirective() && 1428 !S.isInOpenMPDeclareTargetContext(); 1429 } 1430 1431 /// Do we know that we will eventually codegen the given function? 1432 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1433 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1434 "Expected OpenMP device compilation."); 1435 // Templates are emitted when they're instantiated. 1436 if (FD->isDependentContext()) 1437 return false; 1438 1439 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1440 FD->getCanonicalDecl())) 1441 return true; 1442 1443 // Otherwise, the function is known-emitted if it's in our set of 1444 // known-emitted functions. 1445 return S.DeviceKnownEmittedFns.count(FD) > 0; 1446 } 1447 1448 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1449 unsigned DiagID) { 1450 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1451 "Expected OpenMP device compilation."); 1452 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1453 !isKnownEmitted(*this, getCurFunctionDecl())) 1454 ? DeviceDiagBuilder::K_Deferred 1455 : DeviceDiagBuilder::K_Immediate, 1456 Loc, DiagID, getCurFunctionDecl(), *this); 1457 } 1458 1459 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1460 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1461 "Expected OpenMP device compilation."); 1462 assert(Callee && "Callee may not be null."); 1463 FunctionDecl *Caller = getCurFunctionDecl(); 1464 1465 // If the caller is known-emitted, mark the callee as known-emitted. 1466 // Otherwise, mark the call in our call graph so we can traverse it later. 1467 if (!isOpenMPDeviceDelayedContext(*this) || 1468 (Caller && isKnownEmitted(*this, Caller))) 1469 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1470 else if (Caller) 1471 DeviceCallGraph[Caller].insert({Callee, Loc}); 1472 } 1473 1474 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1475 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1476 "OpenMP device compilation mode is expected."); 1477 QualType Ty = E->getType(); 1478 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1479 (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) || 1480 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1481 !Context.getTargetInfo().hasInt128Type())) 1482 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1483 << Ty << E->getSourceRange(); 1484 } 1485 1486 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1487 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1488 1489 ASTContext &Ctx = getASTContext(); 1490 bool IsByRef = true; 1491 1492 // Find the directive that is associated with the provided scope. 1493 D = cast<ValueDecl>(D->getCanonicalDecl()); 1494 QualType Ty = D->getType(); 1495 1496 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1497 // This table summarizes how a given variable should be passed to the device 1498 // given its type and the clauses where it appears. This table is based on 1499 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1500 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1501 // 1502 // ========================================================================= 1503 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1504 // | |(tofrom:scalar)| | pvt | | | | 1505 // ========================================================================= 1506 // | scl | | | | - | | bycopy| 1507 // | scl | | - | x | - | - | bycopy| 1508 // | scl | | x | - | - | - | null | 1509 // | scl | x | | | - | | byref | 1510 // | scl | x | - | x | - | - | bycopy| 1511 // | scl | x | x | - | - | - | null | 1512 // | scl | | - | - | - | x | byref | 1513 // | scl | x | - | - | - | x | byref | 1514 // 1515 // | agg | n.a. | | | - | | byref | 1516 // | agg | n.a. | - | x | - | - | byref | 1517 // | agg | n.a. | x | - | - | - | null | 1518 // | agg | n.a. | - | - | - | x | byref | 1519 // | agg | n.a. | - | - | - | x[] | byref | 1520 // 1521 // | ptr | n.a. | | | - | | bycopy| 1522 // | ptr | n.a. | - | x | - | - | bycopy| 1523 // | ptr | n.a. | x | - | - | - | null | 1524 // | ptr | n.a. | - | - | - | x | byref | 1525 // | ptr | n.a. | - | - | - | x[] | bycopy| 1526 // | ptr | n.a. | - | - | x | | bycopy| 1527 // | ptr | n.a. | - | - | x | x | bycopy| 1528 // | ptr | n.a. | - | - | x | x[] | bycopy| 1529 // ========================================================================= 1530 // Legend: 1531 // scl - scalar 1532 // ptr - pointer 1533 // agg - aggregate 1534 // x - applies 1535 // - - invalid in this combination 1536 // [] - mapped with an array section 1537 // byref - should be mapped by reference 1538 // byval - should be mapped by value 1539 // null - initialize a local variable to null on the device 1540 // 1541 // Observations: 1542 // - All scalar declarations that show up in a map clause have to be passed 1543 // by reference, because they may have been mapped in the enclosing data 1544 // environment. 1545 // - If the scalar value does not fit the size of uintptr, it has to be 1546 // passed by reference, regardless the result in the table above. 1547 // - For pointers mapped by value that have either an implicit map or an 1548 // array section, the runtime library may pass the NULL value to the 1549 // device instead of the value passed to it by the compiler. 1550 1551 if (Ty->isReferenceType()) 1552 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1553 1554 // Locate map clauses and see if the variable being captured is referred to 1555 // in any of those clauses. Here we only care about variables, not fields, 1556 // because fields are part of aggregates. 1557 bool IsVariableUsedInMapClause = false; 1558 bool IsVariableAssociatedWithSection = false; 1559 1560 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1561 D, Level, 1562 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1563 OMPClauseMappableExprCommon::MappableExprComponentListRef 1564 MapExprComponents, 1565 OpenMPClauseKind WhereFoundClauseKind) { 1566 // Only the map clause information influences how a variable is 1567 // captured. E.g. is_device_ptr does not require changing the default 1568 // behavior. 1569 if (WhereFoundClauseKind != OMPC_map) 1570 return false; 1571 1572 auto EI = MapExprComponents.rbegin(); 1573 auto EE = MapExprComponents.rend(); 1574 1575 assert(EI != EE && "Invalid map expression!"); 1576 1577 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1578 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1579 1580 ++EI; 1581 if (EI == EE) 1582 return false; 1583 1584 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1585 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1586 isa<MemberExpr>(EI->getAssociatedExpression())) { 1587 IsVariableAssociatedWithSection = true; 1588 // There is nothing more we need to know about this variable. 1589 return true; 1590 } 1591 1592 // Keep looking for more map info. 1593 return false; 1594 }); 1595 1596 if (IsVariableUsedInMapClause) { 1597 // If variable is identified in a map clause it is always captured by 1598 // reference except if it is a pointer that is dereferenced somehow. 1599 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1600 } else { 1601 // By default, all the data that has a scalar type is mapped by copy 1602 // (except for reduction variables). 1603 IsByRef = 1604 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1605 !Ty->isAnyPointerType()) || 1606 !Ty->isScalarType() || 1607 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1608 DSAStack->hasExplicitDSA( 1609 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1610 } 1611 } 1612 1613 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1614 IsByRef = 1615 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1616 !Ty->isAnyPointerType()) || 1617 !DSAStack->hasExplicitDSA( 1618 D, 1619 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1620 Level, /*NotLastprivate=*/true)) && 1621 // If the variable is artificial and must be captured by value - try to 1622 // capture by value. 1623 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1624 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1625 } 1626 1627 // When passing data by copy, we need to make sure it fits the uintptr size 1628 // and alignment, because the runtime library only deals with uintptr types. 1629 // If it does not fit the uintptr size, we need to pass the data by reference 1630 // instead. 1631 if (!IsByRef && 1632 (Ctx.getTypeSizeInChars(Ty) > 1633 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1634 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1635 IsByRef = true; 1636 } 1637 1638 return IsByRef; 1639 } 1640 1641 unsigned Sema::getOpenMPNestingLevel() const { 1642 assert(getLangOpts().OpenMP); 1643 return DSAStack->getNestingLevel(); 1644 } 1645 1646 bool Sema::isInOpenMPTargetExecutionDirective() const { 1647 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1648 !DSAStack->isClauseParsingMode()) || 1649 DSAStack->hasDirective( 1650 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1651 SourceLocation) -> bool { 1652 return isOpenMPTargetExecutionDirective(K); 1653 }, 1654 false); 1655 } 1656 1657 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { 1658 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1659 D = getCanonicalDecl(D); 1660 1661 // If we are attempting to capture a global variable in a directive with 1662 // 'target' we return true so that this global is also mapped to the device. 1663 // 1664 auto *VD = dyn_cast<VarDecl>(D); 1665 if (VD && !VD->hasLocalStorage()) { 1666 if (isInOpenMPDeclareTargetContext() && 1667 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1668 // Try to mark variable as declare target if it is used in capturing 1669 // regions. 1670 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1671 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1672 return nullptr; 1673 } else if (isInOpenMPTargetExecutionDirective()) { 1674 // If the declaration is enclosed in a 'declare target' directive, 1675 // then it should not be captured. 1676 // 1677 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1678 return nullptr; 1679 return VD; 1680 } 1681 } 1682 // Capture variables captured by reference in lambdas for target-based 1683 // directives. 1684 if (VD && !DSAStack->isClauseParsingMode()) { 1685 if (const auto *RD = VD->getType() 1686 .getCanonicalType() 1687 .getNonReferenceType() 1688 ->getAsCXXRecordDecl()) { 1689 bool SavedForceCaptureByReferenceInTargetExecutable = 1690 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1691 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1692 if (RD->isLambda()) { 1693 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1694 FieldDecl *ThisCapture; 1695 RD->getCaptureFields(Captures, ThisCapture); 1696 for (const LambdaCapture &LC : RD->captures()) { 1697 if (LC.getCaptureKind() == LCK_ByRef) { 1698 VarDecl *VD = LC.getCapturedVar(); 1699 DeclContext *VDC = VD->getDeclContext(); 1700 if (!VDC->Encloses(CurContext)) 1701 continue; 1702 DSAStackTy::DSAVarData DVarPrivate = 1703 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1704 // Do not capture already captured variables. 1705 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1706 DVarPrivate.CKind == OMPC_unknown && 1707 !DSAStack->checkMappableExprComponentListsForDecl( 1708 D, /*CurrentRegionOnly=*/true, 1709 [](OMPClauseMappableExprCommon:: 1710 MappableExprComponentListRef, 1711 OpenMPClauseKind) { return true; })) 1712 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1713 } else if (LC.getCaptureKind() == LCK_This) { 1714 QualType ThisTy = getCurrentThisType(); 1715 if (!ThisTy.isNull() && 1716 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1717 CheckCXXThisCapture(LC.getLocation()); 1718 } 1719 } 1720 } 1721 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1722 SavedForceCaptureByReferenceInTargetExecutable); 1723 } 1724 } 1725 1726 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1727 (!DSAStack->isClauseParsingMode() || 1728 DSAStack->getParentDirective() != OMPD_unknown)) { 1729 auto &&Info = DSAStack->isLoopControlVariable(D); 1730 if (Info.first || 1731 (VD && VD->hasLocalStorage() && 1732 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1733 (VD && DSAStack->isForceVarCapturing())) 1734 return VD ? VD : Info.second; 1735 DSAStackTy::DSAVarData DVarPrivate = 1736 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1737 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1738 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1739 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1740 [](OpenMPDirectiveKind) { return true; }, 1741 DSAStack->isClauseParsingMode()); 1742 if (DVarPrivate.CKind != OMPC_unknown) 1743 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1744 } 1745 return nullptr; 1746 } 1747 1748 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1749 unsigned Level) const { 1750 SmallVector<OpenMPDirectiveKind, 4> Regions; 1751 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1752 FunctionScopesIndex -= Regions.size(); 1753 } 1754 1755 void Sema::startOpenMPLoop() { 1756 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1757 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1758 DSAStack->loopInit(); 1759 } 1760 1761 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1762 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1763 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1764 if (DSAStack->getAssociatedLoops() > 0 && 1765 !DSAStack->isLoopStarted()) { 1766 DSAStack->resetPossibleLoopCounter(D); 1767 DSAStack->loopStart(); 1768 return true; 1769 } 1770 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1771 DSAStack->isLoopControlVariable(D).first) && 1772 !DSAStack->hasExplicitDSA( 1773 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1774 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1775 return true; 1776 } 1777 return DSAStack->hasExplicitDSA( 1778 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1779 (DSAStack->isClauseParsingMode() && 1780 DSAStack->getClauseParsingMode() == OMPC_private) || 1781 // Consider taskgroup reduction descriptor variable a private to avoid 1782 // possible capture in the region. 1783 (DSAStack->hasExplicitDirective( 1784 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1785 Level) && 1786 DSAStack->isTaskgroupReductionRef(D, Level)); 1787 } 1788 1789 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1790 unsigned Level) { 1791 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1792 D = getCanonicalDecl(D); 1793 OpenMPClauseKind OMPC = OMPC_unknown; 1794 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1795 const unsigned NewLevel = I - 1; 1796 if (DSAStack->hasExplicitDSA(D, 1797 [&OMPC](const OpenMPClauseKind K) { 1798 if (isOpenMPPrivate(K)) { 1799 OMPC = K; 1800 return true; 1801 } 1802 return false; 1803 }, 1804 NewLevel)) 1805 break; 1806 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1807 D, NewLevel, 1808 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1809 OpenMPClauseKind) { return true; })) { 1810 OMPC = OMPC_map; 1811 break; 1812 } 1813 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1814 NewLevel)) { 1815 OMPC = OMPC_map; 1816 if (D->getType()->isScalarType() && 1817 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1818 DefaultMapAttributes::DMA_tofrom_scalar) 1819 OMPC = OMPC_firstprivate; 1820 break; 1821 } 1822 } 1823 if (OMPC != OMPC_unknown) 1824 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1825 } 1826 1827 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1828 unsigned Level) const { 1829 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1830 // Return true if the current level is no longer enclosed in a target region. 1831 1832 const auto *VD = dyn_cast<VarDecl>(D); 1833 return VD && !VD->hasLocalStorage() && 1834 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1835 Level); 1836 } 1837 1838 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1839 1840 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1841 const DeclarationNameInfo &DirName, 1842 Scope *CurScope, SourceLocation Loc) { 1843 DSAStack->push(DKind, DirName, CurScope, Loc); 1844 PushExpressionEvaluationContext( 1845 ExpressionEvaluationContext::PotentiallyEvaluated); 1846 } 1847 1848 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1849 DSAStack->setClauseParsingMode(K); 1850 } 1851 1852 void Sema::EndOpenMPClause() { 1853 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1854 } 1855 1856 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1857 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1858 // A variable of class type (or array thereof) that appears in a lastprivate 1859 // clause requires an accessible, unambiguous default constructor for the 1860 // class type, unless the list item is also specified in a firstprivate 1861 // clause. 1862 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1863 for (OMPClause *C : D->clauses()) { 1864 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1865 SmallVector<Expr *, 8> PrivateCopies; 1866 for (Expr *DE : Clause->varlists()) { 1867 if (DE->isValueDependent() || DE->isTypeDependent()) { 1868 PrivateCopies.push_back(nullptr); 1869 continue; 1870 } 1871 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1872 auto *VD = cast<VarDecl>(DRE->getDecl()); 1873 QualType Type = VD->getType().getNonReferenceType(); 1874 const DSAStackTy::DSAVarData DVar = 1875 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1876 if (DVar.CKind == OMPC_lastprivate) { 1877 // Generate helper private variable and initialize it with the 1878 // default value. The address of the original variable is replaced 1879 // by the address of the new private variable in CodeGen. This new 1880 // variable is not added to IdResolver, so the code in the OpenMP 1881 // region uses original variable for proper diagnostics. 1882 VarDecl *VDPrivate = buildVarDecl( 1883 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1884 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1885 ActOnUninitializedDecl(VDPrivate); 1886 if (VDPrivate->isInvalidDecl()) 1887 continue; 1888 PrivateCopies.push_back(buildDeclRefExpr( 1889 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1890 } else { 1891 // The variable is also a firstprivate, so initialization sequence 1892 // for private copy is generated already. 1893 PrivateCopies.push_back(nullptr); 1894 } 1895 } 1896 // Set initializers to private copies if no errors were found. 1897 if (PrivateCopies.size() == Clause->varlist_size()) 1898 Clause->setPrivateCopies(PrivateCopies); 1899 } 1900 } 1901 } 1902 1903 DSAStack->pop(); 1904 DiscardCleanupsInEvaluationContext(); 1905 PopExpressionEvaluationContext(); 1906 } 1907 1908 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1909 Expr *NumIterations, Sema &SemaRef, 1910 Scope *S, DSAStackTy *Stack); 1911 1912 namespace { 1913 1914 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1915 private: 1916 Sema &SemaRef; 1917 1918 public: 1919 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1920 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1921 NamedDecl *ND = Candidate.getCorrectionDecl(); 1922 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1923 return VD->hasGlobalStorage() && 1924 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1925 SemaRef.getCurScope()); 1926 } 1927 return false; 1928 } 1929 }; 1930 1931 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 1932 private: 1933 Sema &SemaRef; 1934 1935 public: 1936 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1937 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1938 NamedDecl *ND = Candidate.getCorrectionDecl(); 1939 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 1940 isa<FunctionDecl>(ND))) { 1941 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1942 SemaRef.getCurScope()); 1943 } 1944 return false; 1945 } 1946 }; 1947 1948 } // namespace 1949 1950 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1951 CXXScopeSpec &ScopeSpec, 1952 const DeclarationNameInfo &Id, 1953 OpenMPDirectiveKind Kind) { 1954 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1955 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1956 1957 if (Lookup.isAmbiguous()) 1958 return ExprError(); 1959 1960 VarDecl *VD; 1961 if (!Lookup.isSingleResult()) { 1962 if (TypoCorrection Corrected = CorrectTypo( 1963 Id, LookupOrdinaryName, CurScope, nullptr, 1964 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1965 diagnoseTypo(Corrected, 1966 PDiag(Lookup.empty() 1967 ? diag::err_undeclared_var_use_suggest 1968 : diag::err_omp_expected_var_arg_suggest) 1969 << Id.getName()); 1970 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1971 } else { 1972 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1973 : diag::err_omp_expected_var_arg) 1974 << Id.getName(); 1975 return ExprError(); 1976 } 1977 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1978 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1979 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1980 return ExprError(); 1981 } 1982 Lookup.suppressDiagnostics(); 1983 1984 // OpenMP [2.9.2, Syntax, C/C++] 1985 // Variables must be file-scope, namespace-scope, or static block-scope. 1986 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 1987 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1988 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 1989 bool IsDecl = 1990 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1991 Diag(VD->getLocation(), 1992 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1993 << VD; 1994 return ExprError(); 1995 } 1996 1997 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1998 NamedDecl *ND = CanonicalVD; 1999 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2000 // A threadprivate directive for file-scope variables must appear outside 2001 // any definition or declaration. 2002 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2003 !getCurLexicalContext()->isTranslationUnit()) { 2004 Diag(Id.getLoc(), diag::err_omp_var_scope) 2005 << getOpenMPDirectiveName(Kind) << VD; 2006 bool IsDecl = 2007 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2008 Diag(VD->getLocation(), 2009 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2010 << VD; 2011 return ExprError(); 2012 } 2013 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2014 // A threadprivate directive for static class member variables must appear 2015 // in the class definition, in the same scope in which the member 2016 // variables are declared. 2017 if (CanonicalVD->isStaticDataMember() && 2018 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2019 Diag(Id.getLoc(), diag::err_omp_var_scope) 2020 << getOpenMPDirectiveName(Kind) << VD; 2021 bool IsDecl = 2022 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2023 Diag(VD->getLocation(), 2024 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2025 << VD; 2026 return ExprError(); 2027 } 2028 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2029 // A threadprivate directive for namespace-scope variables must appear 2030 // outside any definition or declaration other than the namespace 2031 // definition itself. 2032 if (CanonicalVD->getDeclContext()->isNamespace() && 2033 (!getCurLexicalContext()->isFileContext() || 2034 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2035 Diag(Id.getLoc(), diag::err_omp_var_scope) 2036 << getOpenMPDirectiveName(Kind) << VD; 2037 bool IsDecl = 2038 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2039 Diag(VD->getLocation(), 2040 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2041 << VD; 2042 return ExprError(); 2043 } 2044 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2045 // A threadprivate directive for static block-scope variables must appear 2046 // in the scope of the variable and not in a nested scope. 2047 if (CanonicalVD->isLocalVarDecl() && CurScope && 2048 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2049 Diag(Id.getLoc(), diag::err_omp_var_scope) 2050 << getOpenMPDirectiveName(Kind) << VD; 2051 bool IsDecl = 2052 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2053 Diag(VD->getLocation(), 2054 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2055 << VD; 2056 return ExprError(); 2057 } 2058 2059 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2060 // A threadprivate directive must lexically precede all references to any 2061 // of the variables in its list. 2062 if (Kind == OMPD_threadprivate && VD->isUsed() && 2063 !DSAStack->isThreadPrivate(VD)) { 2064 Diag(Id.getLoc(), diag::err_omp_var_used) 2065 << getOpenMPDirectiveName(Kind) << VD; 2066 return ExprError(); 2067 } 2068 2069 QualType ExprType = VD->getType().getNonReferenceType(); 2070 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2071 SourceLocation(), VD, 2072 /*RefersToEnclosingVariableOrCapture=*/false, 2073 Id.getLoc(), ExprType, VK_LValue); 2074 } 2075 2076 Sema::DeclGroupPtrTy 2077 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2078 ArrayRef<Expr *> VarList) { 2079 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2080 CurContext->addDecl(D); 2081 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2082 } 2083 return nullptr; 2084 } 2085 2086 namespace { 2087 class LocalVarRefChecker final 2088 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2089 Sema &SemaRef; 2090 2091 public: 2092 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2093 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2094 if (VD->hasLocalStorage()) { 2095 SemaRef.Diag(E->getBeginLoc(), 2096 diag::err_omp_local_var_in_threadprivate_init) 2097 << E->getSourceRange(); 2098 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2099 << VD << VD->getSourceRange(); 2100 return true; 2101 } 2102 } 2103 return false; 2104 } 2105 bool VisitStmt(const Stmt *S) { 2106 for (const Stmt *Child : S->children()) { 2107 if (Child && Visit(Child)) 2108 return true; 2109 } 2110 return false; 2111 } 2112 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2113 }; 2114 } // namespace 2115 2116 OMPThreadPrivateDecl * 2117 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2118 SmallVector<Expr *, 8> Vars; 2119 for (Expr *RefExpr : VarList) { 2120 auto *DE = cast<DeclRefExpr>(RefExpr); 2121 auto *VD = cast<VarDecl>(DE->getDecl()); 2122 SourceLocation ILoc = DE->getExprLoc(); 2123 2124 // Mark variable as used. 2125 VD->setReferenced(); 2126 VD->markUsed(Context); 2127 2128 QualType QType = VD->getType(); 2129 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2130 // It will be analyzed later. 2131 Vars.push_back(DE); 2132 continue; 2133 } 2134 2135 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2136 // A threadprivate variable must not have an incomplete type. 2137 if (RequireCompleteType(ILoc, VD->getType(), 2138 diag::err_omp_threadprivate_incomplete_type)) { 2139 continue; 2140 } 2141 2142 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2143 // A threadprivate variable must not have a reference type. 2144 if (VD->getType()->isReferenceType()) { 2145 Diag(ILoc, diag::err_omp_ref_type_arg) 2146 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2147 bool IsDecl = 2148 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2149 Diag(VD->getLocation(), 2150 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2151 << VD; 2152 continue; 2153 } 2154 2155 // Check if this is a TLS variable. If TLS is not being supported, produce 2156 // the corresponding diagnostic. 2157 if ((VD->getTLSKind() != VarDecl::TLS_None && 2158 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2159 getLangOpts().OpenMPUseTLS && 2160 getASTContext().getTargetInfo().isTLSSupported())) || 2161 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2162 !VD->isLocalVarDecl())) { 2163 Diag(ILoc, diag::err_omp_var_thread_local) 2164 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2165 bool IsDecl = 2166 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2167 Diag(VD->getLocation(), 2168 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2169 << VD; 2170 continue; 2171 } 2172 2173 // Check if initial value of threadprivate variable reference variable with 2174 // local storage (it is not supported by runtime). 2175 if (const Expr *Init = VD->getAnyInitializer()) { 2176 LocalVarRefChecker Checker(*this); 2177 if (Checker.Visit(Init)) 2178 continue; 2179 } 2180 2181 Vars.push_back(RefExpr); 2182 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2183 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2184 Context, SourceRange(Loc, Loc))); 2185 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2186 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2187 } 2188 OMPThreadPrivateDecl *D = nullptr; 2189 if (!Vars.empty()) { 2190 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2191 Vars); 2192 D->setAccess(AS_public); 2193 } 2194 return D; 2195 } 2196 2197 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2198 SourceLocation Loc, ArrayRef<Expr *> VarList, 2199 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2200 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2201 Expr *Allocator = nullptr; 2202 if (!Clauses.empty()) 2203 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2204 SmallVector<Expr *, 8> Vars; 2205 for (Expr *RefExpr : VarList) { 2206 auto *DE = cast<DeclRefExpr>(RefExpr); 2207 auto *VD = cast<VarDecl>(DE->getDecl()); 2208 2209 // Check if this is a TLS variable or global register. 2210 if (VD->getTLSKind() != VarDecl::TLS_None || 2211 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2212 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2213 !VD->isLocalVarDecl())) 2214 continue; 2215 // Do not apply for parameters. 2216 if (isa<ParmVarDecl>(VD)) 2217 continue; 2218 2219 Vars.push_back(RefExpr); 2220 Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator, 2221 DE->getSourceRange()); 2222 VD->addAttr(A); 2223 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2224 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2225 } 2226 if (Vars.empty()) 2227 return nullptr; 2228 if (!Owner) 2229 Owner = getCurLexicalContext(); 2230 OMPAllocateDecl *D = 2231 OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2232 D->setAccess(AS_public); 2233 Owner->addDecl(D); 2234 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2235 } 2236 2237 Sema::DeclGroupPtrTy 2238 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2239 ArrayRef<OMPClause *> ClauseList) { 2240 OMPRequiresDecl *D = nullptr; 2241 if (!CurContext->isFileContext()) { 2242 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2243 } else { 2244 D = CheckOMPRequiresDecl(Loc, ClauseList); 2245 if (D) { 2246 CurContext->addDecl(D); 2247 DSAStack->addRequiresDecl(D); 2248 } 2249 } 2250 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2251 } 2252 2253 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2254 ArrayRef<OMPClause *> ClauseList) { 2255 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2256 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2257 ClauseList); 2258 return nullptr; 2259 } 2260 2261 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2262 const ValueDecl *D, 2263 const DSAStackTy::DSAVarData &DVar, 2264 bool IsLoopIterVar = false) { 2265 if (DVar.RefExpr) { 2266 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2267 << getOpenMPClauseName(DVar.CKind); 2268 return; 2269 } 2270 enum { 2271 PDSA_StaticMemberShared, 2272 PDSA_StaticLocalVarShared, 2273 PDSA_LoopIterVarPrivate, 2274 PDSA_LoopIterVarLinear, 2275 PDSA_LoopIterVarLastprivate, 2276 PDSA_ConstVarShared, 2277 PDSA_GlobalVarShared, 2278 PDSA_TaskVarFirstprivate, 2279 PDSA_LocalVarPrivate, 2280 PDSA_Implicit 2281 } Reason = PDSA_Implicit; 2282 bool ReportHint = false; 2283 auto ReportLoc = D->getLocation(); 2284 auto *VD = dyn_cast<VarDecl>(D); 2285 if (IsLoopIterVar) { 2286 if (DVar.CKind == OMPC_private) 2287 Reason = PDSA_LoopIterVarPrivate; 2288 else if (DVar.CKind == OMPC_lastprivate) 2289 Reason = PDSA_LoopIterVarLastprivate; 2290 else 2291 Reason = PDSA_LoopIterVarLinear; 2292 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2293 DVar.CKind == OMPC_firstprivate) { 2294 Reason = PDSA_TaskVarFirstprivate; 2295 ReportLoc = DVar.ImplicitDSALoc; 2296 } else if (VD && VD->isStaticLocal()) 2297 Reason = PDSA_StaticLocalVarShared; 2298 else if (VD && VD->isStaticDataMember()) 2299 Reason = PDSA_StaticMemberShared; 2300 else if (VD && VD->isFileVarDecl()) 2301 Reason = PDSA_GlobalVarShared; 2302 else if (D->getType().isConstant(SemaRef.getASTContext())) 2303 Reason = PDSA_ConstVarShared; 2304 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2305 ReportHint = true; 2306 Reason = PDSA_LocalVarPrivate; 2307 } 2308 if (Reason != PDSA_Implicit) { 2309 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2310 << Reason << ReportHint 2311 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2312 } else if (DVar.ImplicitDSALoc.isValid()) { 2313 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2314 << getOpenMPClauseName(DVar.CKind); 2315 } 2316 } 2317 2318 namespace { 2319 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2320 DSAStackTy *Stack; 2321 Sema &SemaRef; 2322 bool ErrorFound = false; 2323 CapturedStmt *CS = nullptr; 2324 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2325 llvm::SmallVector<Expr *, 4> ImplicitMap; 2326 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2327 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2328 2329 void VisitSubCaptures(OMPExecutableDirective *S) { 2330 // Check implicitly captured variables. 2331 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2332 return; 2333 for (const CapturedStmt::Capture &Cap : 2334 S->getInnermostCapturedStmt()->captures()) { 2335 if (!Cap.capturesVariable()) 2336 continue; 2337 VarDecl *VD = Cap.getCapturedVar(); 2338 // Do not try to map the variable if it or its sub-component was mapped 2339 // already. 2340 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2341 Stack->checkMappableExprComponentListsForDecl( 2342 VD, /*CurrentRegionOnly=*/true, 2343 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2344 OpenMPClauseKind) { return true; })) 2345 continue; 2346 DeclRefExpr *DRE = buildDeclRefExpr( 2347 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2348 Cap.getLocation(), /*RefersToCapture=*/true); 2349 Visit(DRE); 2350 } 2351 } 2352 2353 public: 2354 void VisitDeclRefExpr(DeclRefExpr *E) { 2355 if (E->isTypeDependent() || E->isValueDependent() || 2356 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2357 return; 2358 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2359 VD = VD->getCanonicalDecl(); 2360 // Skip internally declared variables. 2361 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 2362 return; 2363 2364 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2365 // Check if the variable has explicit DSA set and stop analysis if it so. 2366 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2367 return; 2368 2369 // Skip internally declared static variables. 2370 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2371 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2372 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && 2373 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2374 return; 2375 2376 SourceLocation ELoc = E->getExprLoc(); 2377 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2378 // The default(none) clause requires that each variable that is referenced 2379 // in the construct, and does not have a predetermined data-sharing 2380 // attribute, must have its data-sharing attribute explicitly determined 2381 // by being listed in a data-sharing attribute clause. 2382 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2383 isImplicitOrExplicitTaskingRegion(DKind) && 2384 VarsWithInheritedDSA.count(VD) == 0) { 2385 VarsWithInheritedDSA[VD] = E; 2386 return; 2387 } 2388 2389 if (isOpenMPTargetExecutionDirective(DKind) && 2390 !Stack->isLoopControlVariable(VD).first) { 2391 if (!Stack->checkMappableExprComponentListsForDecl( 2392 VD, /*CurrentRegionOnly=*/true, 2393 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2394 StackComponents, 2395 OpenMPClauseKind) { 2396 // Variable is used if it has been marked as an array, array 2397 // section or the variable iself. 2398 return StackComponents.size() == 1 || 2399 std::all_of( 2400 std::next(StackComponents.rbegin()), 2401 StackComponents.rend(), 2402 [](const OMPClauseMappableExprCommon:: 2403 MappableComponent &MC) { 2404 return MC.getAssociatedDeclaration() == 2405 nullptr && 2406 (isa<OMPArraySectionExpr>( 2407 MC.getAssociatedExpression()) || 2408 isa<ArraySubscriptExpr>( 2409 MC.getAssociatedExpression())); 2410 }); 2411 })) { 2412 bool IsFirstprivate = false; 2413 // By default lambdas are captured as firstprivates. 2414 if (const auto *RD = 2415 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2416 IsFirstprivate = RD->isLambda(); 2417 IsFirstprivate = 2418 IsFirstprivate || 2419 (VD->getType().getNonReferenceType()->isScalarType() && 2420 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2421 if (IsFirstprivate) 2422 ImplicitFirstprivate.emplace_back(E); 2423 else 2424 ImplicitMap.emplace_back(E); 2425 return; 2426 } 2427 } 2428 2429 // OpenMP [2.9.3.6, Restrictions, p.2] 2430 // A list item that appears in a reduction clause of the innermost 2431 // enclosing worksharing or parallel construct may not be accessed in an 2432 // explicit task. 2433 DVar = Stack->hasInnermostDSA( 2434 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2435 [](OpenMPDirectiveKind K) { 2436 return isOpenMPParallelDirective(K) || 2437 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2438 }, 2439 /*FromParent=*/true); 2440 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2441 ErrorFound = true; 2442 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2443 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2444 return; 2445 } 2446 2447 // Define implicit data-sharing attributes for task. 2448 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2449 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2450 !Stack->isLoopControlVariable(VD).first) { 2451 ImplicitFirstprivate.push_back(E); 2452 return; 2453 } 2454 2455 // Store implicitly used globals with declare target link for parent 2456 // target. 2457 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2458 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2459 Stack->addToParentTargetRegionLinkGlobals(E); 2460 return; 2461 } 2462 } 2463 } 2464 void VisitMemberExpr(MemberExpr *E) { 2465 if (E->isTypeDependent() || E->isValueDependent() || 2466 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2467 return; 2468 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2469 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2470 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2471 if (!FD) 2472 return; 2473 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2474 // Check if the variable has explicit DSA set and stop analysis if it 2475 // so. 2476 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2477 return; 2478 2479 if (isOpenMPTargetExecutionDirective(DKind) && 2480 !Stack->isLoopControlVariable(FD).first && 2481 !Stack->checkMappableExprComponentListsForDecl( 2482 FD, /*CurrentRegionOnly=*/true, 2483 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2484 StackComponents, 2485 OpenMPClauseKind) { 2486 return isa<CXXThisExpr>( 2487 cast<MemberExpr>( 2488 StackComponents.back().getAssociatedExpression()) 2489 ->getBase() 2490 ->IgnoreParens()); 2491 })) { 2492 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2493 // A bit-field cannot appear in a map clause. 2494 // 2495 if (FD->isBitField()) 2496 return; 2497 2498 // Check to see if the member expression is referencing a class that 2499 // has already been explicitly mapped 2500 if (Stack->isClassPreviouslyMapped(TE->getType())) 2501 return; 2502 2503 ImplicitMap.emplace_back(E); 2504 return; 2505 } 2506 2507 SourceLocation ELoc = E->getExprLoc(); 2508 // OpenMP [2.9.3.6, Restrictions, p.2] 2509 // A list item that appears in a reduction clause of the innermost 2510 // enclosing worksharing or parallel construct may not be accessed in 2511 // an explicit task. 2512 DVar = Stack->hasInnermostDSA( 2513 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2514 [](OpenMPDirectiveKind K) { 2515 return isOpenMPParallelDirective(K) || 2516 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2517 }, 2518 /*FromParent=*/true); 2519 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2520 ErrorFound = true; 2521 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2522 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2523 return; 2524 } 2525 2526 // Define implicit data-sharing attributes for task. 2527 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2528 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2529 !Stack->isLoopControlVariable(FD).first) { 2530 // Check if there is a captured expression for the current field in the 2531 // region. Do not mark it as firstprivate unless there is no captured 2532 // expression. 2533 // TODO: try to make it firstprivate. 2534 if (DVar.CKind != OMPC_unknown) 2535 ImplicitFirstprivate.push_back(E); 2536 } 2537 return; 2538 } 2539 if (isOpenMPTargetExecutionDirective(DKind)) { 2540 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2541 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2542 /*NoDiagnose=*/true)) 2543 return; 2544 const auto *VD = cast<ValueDecl>( 2545 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2546 if (!Stack->checkMappableExprComponentListsForDecl( 2547 VD, /*CurrentRegionOnly=*/true, 2548 [&CurComponents]( 2549 OMPClauseMappableExprCommon::MappableExprComponentListRef 2550 StackComponents, 2551 OpenMPClauseKind) { 2552 auto CCI = CurComponents.rbegin(); 2553 auto CCE = CurComponents.rend(); 2554 for (const auto &SC : llvm::reverse(StackComponents)) { 2555 // Do both expressions have the same kind? 2556 if (CCI->getAssociatedExpression()->getStmtClass() != 2557 SC.getAssociatedExpression()->getStmtClass()) 2558 if (!(isa<OMPArraySectionExpr>( 2559 SC.getAssociatedExpression()) && 2560 isa<ArraySubscriptExpr>( 2561 CCI->getAssociatedExpression()))) 2562 return false; 2563 2564 const Decl *CCD = CCI->getAssociatedDeclaration(); 2565 const Decl *SCD = SC.getAssociatedDeclaration(); 2566 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2567 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2568 if (SCD != CCD) 2569 return false; 2570 std::advance(CCI, 1); 2571 if (CCI == CCE) 2572 break; 2573 } 2574 return true; 2575 })) { 2576 Visit(E->getBase()); 2577 } 2578 } else { 2579 Visit(E->getBase()); 2580 } 2581 } 2582 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2583 for (OMPClause *C : S->clauses()) { 2584 // Skip analysis of arguments of implicitly defined firstprivate clause 2585 // for task|target directives. 2586 // Skip analysis of arguments of implicitly defined map clause for target 2587 // directives. 2588 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2589 C->isImplicit())) { 2590 for (Stmt *CC : C->children()) { 2591 if (CC) 2592 Visit(CC); 2593 } 2594 } 2595 } 2596 // Check implicitly captured variables. 2597 VisitSubCaptures(S); 2598 } 2599 void VisitStmt(Stmt *S) { 2600 for (Stmt *C : S->children()) { 2601 if (C) { 2602 // Check implicitly captured variables in the task-based directives to 2603 // check if they must be firstprivatized. 2604 Visit(C); 2605 } 2606 } 2607 } 2608 2609 bool isErrorFound() const { return ErrorFound; } 2610 ArrayRef<Expr *> getImplicitFirstprivate() const { 2611 return ImplicitFirstprivate; 2612 } 2613 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2614 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2615 return VarsWithInheritedDSA; 2616 } 2617 2618 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2619 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2620 // Process declare target link variables for the target directives. 2621 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2622 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2623 Visit(E); 2624 } 2625 } 2626 }; 2627 } // namespace 2628 2629 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2630 switch (DKind) { 2631 case OMPD_parallel: 2632 case OMPD_parallel_for: 2633 case OMPD_parallel_for_simd: 2634 case OMPD_parallel_sections: 2635 case OMPD_teams: 2636 case OMPD_teams_distribute: 2637 case OMPD_teams_distribute_simd: { 2638 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2639 QualType KmpInt32PtrTy = 2640 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2641 Sema::CapturedParamNameType Params[] = { 2642 std::make_pair(".global_tid.", KmpInt32PtrTy), 2643 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2644 std::make_pair(StringRef(), QualType()) // __context with shared vars 2645 }; 2646 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2647 Params); 2648 break; 2649 } 2650 case OMPD_target_teams: 2651 case OMPD_target_parallel: 2652 case OMPD_target_parallel_for: 2653 case OMPD_target_parallel_for_simd: 2654 case OMPD_target_teams_distribute: 2655 case OMPD_target_teams_distribute_simd: { 2656 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2657 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2658 QualType KmpInt32PtrTy = 2659 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2660 QualType Args[] = {VoidPtrTy}; 2661 FunctionProtoType::ExtProtoInfo EPI; 2662 EPI.Variadic = true; 2663 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2664 Sema::CapturedParamNameType Params[] = { 2665 std::make_pair(".global_tid.", KmpInt32Ty), 2666 std::make_pair(".part_id.", KmpInt32PtrTy), 2667 std::make_pair(".privates.", VoidPtrTy), 2668 std::make_pair( 2669 ".copy_fn.", 2670 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2671 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2672 std::make_pair(StringRef(), QualType()) // __context with shared vars 2673 }; 2674 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2675 Params); 2676 // Mark this captured region as inlined, because we don't use outlined 2677 // function directly. 2678 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2679 AlwaysInlineAttr::CreateImplicit( 2680 Context, AlwaysInlineAttr::Keyword_forceinline)); 2681 Sema::CapturedParamNameType ParamsTarget[] = { 2682 std::make_pair(StringRef(), QualType()) // __context with shared vars 2683 }; 2684 // Start a captured region for 'target' with no implicit parameters. 2685 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2686 ParamsTarget); 2687 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2688 std::make_pair(".global_tid.", KmpInt32PtrTy), 2689 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2690 std::make_pair(StringRef(), QualType()) // __context with shared vars 2691 }; 2692 // Start a captured region for 'teams' or 'parallel'. Both regions have 2693 // the same implicit parameters. 2694 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2695 ParamsTeamsOrParallel); 2696 break; 2697 } 2698 case OMPD_target: 2699 case OMPD_target_simd: { 2700 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2701 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2702 QualType KmpInt32PtrTy = 2703 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2704 QualType Args[] = {VoidPtrTy}; 2705 FunctionProtoType::ExtProtoInfo EPI; 2706 EPI.Variadic = true; 2707 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2708 Sema::CapturedParamNameType Params[] = { 2709 std::make_pair(".global_tid.", KmpInt32Ty), 2710 std::make_pair(".part_id.", KmpInt32PtrTy), 2711 std::make_pair(".privates.", VoidPtrTy), 2712 std::make_pair( 2713 ".copy_fn.", 2714 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2715 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2716 std::make_pair(StringRef(), QualType()) // __context with shared vars 2717 }; 2718 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2719 Params); 2720 // Mark this captured region as inlined, because we don't use outlined 2721 // function directly. 2722 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2723 AlwaysInlineAttr::CreateImplicit( 2724 Context, AlwaysInlineAttr::Keyword_forceinline)); 2725 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2726 std::make_pair(StringRef(), QualType())); 2727 break; 2728 } 2729 case OMPD_simd: 2730 case OMPD_for: 2731 case OMPD_for_simd: 2732 case OMPD_sections: 2733 case OMPD_section: 2734 case OMPD_single: 2735 case OMPD_master: 2736 case OMPD_critical: 2737 case OMPD_taskgroup: 2738 case OMPD_distribute: 2739 case OMPD_distribute_simd: 2740 case OMPD_ordered: 2741 case OMPD_atomic: 2742 case OMPD_target_data: { 2743 Sema::CapturedParamNameType Params[] = { 2744 std::make_pair(StringRef(), QualType()) // __context with shared vars 2745 }; 2746 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2747 Params); 2748 break; 2749 } 2750 case OMPD_task: { 2751 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2752 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2753 QualType KmpInt32PtrTy = 2754 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2755 QualType Args[] = {VoidPtrTy}; 2756 FunctionProtoType::ExtProtoInfo EPI; 2757 EPI.Variadic = true; 2758 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2759 Sema::CapturedParamNameType Params[] = { 2760 std::make_pair(".global_tid.", KmpInt32Ty), 2761 std::make_pair(".part_id.", KmpInt32PtrTy), 2762 std::make_pair(".privates.", VoidPtrTy), 2763 std::make_pair( 2764 ".copy_fn.", 2765 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2766 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2767 std::make_pair(StringRef(), QualType()) // __context with shared vars 2768 }; 2769 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2770 Params); 2771 // Mark this captured region as inlined, because we don't use outlined 2772 // function directly. 2773 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2774 AlwaysInlineAttr::CreateImplicit( 2775 Context, AlwaysInlineAttr::Keyword_forceinline)); 2776 break; 2777 } 2778 case OMPD_taskloop: 2779 case OMPD_taskloop_simd: { 2780 QualType KmpInt32Ty = 2781 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 2782 .withConst(); 2783 QualType KmpUInt64Ty = 2784 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 2785 .withConst(); 2786 QualType KmpInt64Ty = 2787 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 2788 .withConst(); 2789 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2790 QualType KmpInt32PtrTy = 2791 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2792 QualType Args[] = {VoidPtrTy}; 2793 FunctionProtoType::ExtProtoInfo EPI; 2794 EPI.Variadic = true; 2795 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2796 Sema::CapturedParamNameType Params[] = { 2797 std::make_pair(".global_tid.", KmpInt32Ty), 2798 std::make_pair(".part_id.", KmpInt32PtrTy), 2799 std::make_pair(".privates.", VoidPtrTy), 2800 std::make_pair( 2801 ".copy_fn.", 2802 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2803 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2804 std::make_pair(".lb.", KmpUInt64Ty), 2805 std::make_pair(".ub.", KmpUInt64Ty), 2806 std::make_pair(".st.", KmpInt64Ty), 2807 std::make_pair(".liter.", KmpInt32Ty), 2808 std::make_pair(".reductions.", VoidPtrTy), 2809 std::make_pair(StringRef(), QualType()) // __context with shared vars 2810 }; 2811 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2812 Params); 2813 // Mark this captured region as inlined, because we don't use outlined 2814 // function directly. 2815 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2816 AlwaysInlineAttr::CreateImplicit( 2817 Context, AlwaysInlineAttr::Keyword_forceinline)); 2818 break; 2819 } 2820 case OMPD_distribute_parallel_for_simd: 2821 case OMPD_distribute_parallel_for: { 2822 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2823 QualType KmpInt32PtrTy = 2824 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2825 Sema::CapturedParamNameType Params[] = { 2826 std::make_pair(".global_tid.", KmpInt32PtrTy), 2827 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2828 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2829 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2830 std::make_pair(StringRef(), QualType()) // __context with shared vars 2831 }; 2832 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2833 Params); 2834 break; 2835 } 2836 case OMPD_target_teams_distribute_parallel_for: 2837 case OMPD_target_teams_distribute_parallel_for_simd: { 2838 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2839 QualType KmpInt32PtrTy = 2840 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2841 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2842 2843 QualType Args[] = {VoidPtrTy}; 2844 FunctionProtoType::ExtProtoInfo EPI; 2845 EPI.Variadic = true; 2846 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2847 Sema::CapturedParamNameType Params[] = { 2848 std::make_pair(".global_tid.", KmpInt32Ty), 2849 std::make_pair(".part_id.", KmpInt32PtrTy), 2850 std::make_pair(".privates.", VoidPtrTy), 2851 std::make_pair( 2852 ".copy_fn.", 2853 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2854 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2855 std::make_pair(StringRef(), QualType()) // __context with shared vars 2856 }; 2857 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2858 Params); 2859 // Mark this captured region as inlined, because we don't use outlined 2860 // function directly. 2861 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2862 AlwaysInlineAttr::CreateImplicit( 2863 Context, AlwaysInlineAttr::Keyword_forceinline)); 2864 Sema::CapturedParamNameType ParamsTarget[] = { 2865 std::make_pair(StringRef(), QualType()) // __context with shared vars 2866 }; 2867 // Start a captured region for 'target' with no implicit parameters. 2868 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2869 ParamsTarget); 2870 2871 Sema::CapturedParamNameType ParamsTeams[] = { 2872 std::make_pair(".global_tid.", KmpInt32PtrTy), 2873 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2874 std::make_pair(StringRef(), QualType()) // __context with shared vars 2875 }; 2876 // Start a captured region for 'target' with no implicit parameters. 2877 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2878 ParamsTeams); 2879 2880 Sema::CapturedParamNameType ParamsParallel[] = { 2881 std::make_pair(".global_tid.", KmpInt32PtrTy), 2882 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2883 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2884 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2885 std::make_pair(StringRef(), QualType()) // __context with shared vars 2886 }; 2887 // Start a captured region for 'teams' or 'parallel'. Both regions have 2888 // the same implicit parameters. 2889 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2890 ParamsParallel); 2891 break; 2892 } 2893 2894 case OMPD_teams_distribute_parallel_for: 2895 case OMPD_teams_distribute_parallel_for_simd: { 2896 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2897 QualType KmpInt32PtrTy = 2898 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2899 2900 Sema::CapturedParamNameType ParamsTeams[] = { 2901 std::make_pair(".global_tid.", KmpInt32PtrTy), 2902 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2903 std::make_pair(StringRef(), QualType()) // __context with shared vars 2904 }; 2905 // Start a captured region for 'target' with no implicit parameters. 2906 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2907 ParamsTeams); 2908 2909 Sema::CapturedParamNameType ParamsParallel[] = { 2910 std::make_pair(".global_tid.", KmpInt32PtrTy), 2911 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2912 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2913 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2914 std::make_pair(StringRef(), QualType()) // __context with shared vars 2915 }; 2916 // Start a captured region for 'teams' or 'parallel'. Both regions have 2917 // the same implicit parameters. 2918 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2919 ParamsParallel); 2920 break; 2921 } 2922 case OMPD_target_update: 2923 case OMPD_target_enter_data: 2924 case OMPD_target_exit_data: { 2925 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2926 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2927 QualType KmpInt32PtrTy = 2928 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2929 QualType Args[] = {VoidPtrTy}; 2930 FunctionProtoType::ExtProtoInfo EPI; 2931 EPI.Variadic = true; 2932 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2933 Sema::CapturedParamNameType Params[] = { 2934 std::make_pair(".global_tid.", KmpInt32Ty), 2935 std::make_pair(".part_id.", KmpInt32PtrTy), 2936 std::make_pair(".privates.", VoidPtrTy), 2937 std::make_pair( 2938 ".copy_fn.", 2939 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2940 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2941 std::make_pair(StringRef(), QualType()) // __context with shared vars 2942 }; 2943 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2944 Params); 2945 // Mark this captured region as inlined, because we don't use outlined 2946 // function directly. 2947 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2948 AlwaysInlineAttr::CreateImplicit( 2949 Context, AlwaysInlineAttr::Keyword_forceinline)); 2950 break; 2951 } 2952 case OMPD_threadprivate: 2953 case OMPD_allocate: 2954 case OMPD_taskyield: 2955 case OMPD_barrier: 2956 case OMPD_taskwait: 2957 case OMPD_cancellation_point: 2958 case OMPD_cancel: 2959 case OMPD_flush: 2960 case OMPD_declare_reduction: 2961 case OMPD_declare_mapper: 2962 case OMPD_declare_simd: 2963 case OMPD_declare_target: 2964 case OMPD_end_declare_target: 2965 case OMPD_requires: 2966 llvm_unreachable("OpenMP Directive is not allowed"); 2967 case OMPD_unknown: 2968 llvm_unreachable("Unknown OpenMP directive"); 2969 } 2970 } 2971 2972 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 2973 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2974 getOpenMPCaptureRegions(CaptureRegions, DKind); 2975 return CaptureRegions.size(); 2976 } 2977 2978 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2979 Expr *CaptureExpr, bool WithInit, 2980 bool AsExpression) { 2981 assert(CaptureExpr); 2982 ASTContext &C = S.getASTContext(); 2983 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 2984 QualType Ty = Init->getType(); 2985 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 2986 if (S.getLangOpts().CPlusPlus) { 2987 Ty = C.getLValueReferenceType(Ty); 2988 } else { 2989 Ty = C.getPointerType(Ty); 2990 ExprResult Res = 2991 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 2992 if (!Res.isUsable()) 2993 return nullptr; 2994 Init = Res.get(); 2995 } 2996 WithInit = true; 2997 } 2998 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 2999 CaptureExpr->getBeginLoc()); 3000 if (!WithInit) 3001 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3002 S.CurContext->addHiddenDecl(CED); 3003 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3004 return CED; 3005 } 3006 3007 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3008 bool WithInit) { 3009 OMPCapturedExprDecl *CD; 3010 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3011 CD = cast<OMPCapturedExprDecl>(VD); 3012 else 3013 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3014 /*AsExpression=*/false); 3015 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3016 CaptureExpr->getExprLoc()); 3017 } 3018 3019 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3020 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3021 if (!Ref) { 3022 OMPCapturedExprDecl *CD = buildCaptureDecl( 3023 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3024 /*WithInit=*/true, /*AsExpression=*/true); 3025 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3026 CaptureExpr->getExprLoc()); 3027 } 3028 ExprResult Res = Ref; 3029 if (!S.getLangOpts().CPlusPlus && 3030 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3031 Ref->getType()->isPointerType()) { 3032 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3033 if (!Res.isUsable()) 3034 return ExprError(); 3035 } 3036 return S.DefaultLvalueConversion(Res.get()); 3037 } 3038 3039 namespace { 3040 // OpenMP directives parsed in this section are represented as a 3041 // CapturedStatement with an associated statement. If a syntax error 3042 // is detected during the parsing of the associated statement, the 3043 // compiler must abort processing and close the CapturedStatement. 3044 // 3045 // Combined directives such as 'target parallel' have more than one 3046 // nested CapturedStatements. This RAII ensures that we unwind out 3047 // of all the nested CapturedStatements when an error is found. 3048 class CaptureRegionUnwinderRAII { 3049 private: 3050 Sema &S; 3051 bool &ErrorFound; 3052 OpenMPDirectiveKind DKind = OMPD_unknown; 3053 3054 public: 3055 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3056 OpenMPDirectiveKind DKind) 3057 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3058 ~CaptureRegionUnwinderRAII() { 3059 if (ErrorFound) { 3060 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3061 while (--ThisCaptureLevel >= 0) 3062 S.ActOnCapturedRegionError(); 3063 } 3064 } 3065 }; 3066 } // namespace 3067 3068 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3069 ArrayRef<OMPClause *> Clauses) { 3070 bool ErrorFound = false; 3071 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3072 *this, ErrorFound, DSAStack->getCurrentDirective()); 3073 if (!S.isUsable()) { 3074 ErrorFound = true; 3075 return StmtError(); 3076 } 3077 3078 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3079 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3080 OMPOrderedClause *OC = nullptr; 3081 OMPScheduleClause *SC = nullptr; 3082 SmallVector<const OMPLinearClause *, 4> LCs; 3083 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3084 // This is required for proper codegen. 3085 for (OMPClause *Clause : Clauses) { 3086 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3087 Clause->getClauseKind() == OMPC_in_reduction) { 3088 // Capture taskgroup task_reduction descriptors inside the tasking regions 3089 // with the corresponding in_reduction items. 3090 auto *IRC = cast<OMPInReductionClause>(Clause); 3091 for (Expr *E : IRC->taskgroup_descriptors()) 3092 if (E) 3093 MarkDeclarationsReferencedInExpr(E); 3094 } 3095 if (isOpenMPPrivate(Clause->getClauseKind()) || 3096 Clause->getClauseKind() == OMPC_copyprivate || 3097 (getLangOpts().OpenMPUseTLS && 3098 getASTContext().getTargetInfo().isTLSSupported() && 3099 Clause->getClauseKind() == OMPC_copyin)) { 3100 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3101 // Mark all variables in private list clauses as used in inner region. 3102 for (Stmt *VarRef : Clause->children()) { 3103 if (auto *E = cast_or_null<Expr>(VarRef)) { 3104 MarkDeclarationsReferencedInExpr(E); 3105 } 3106 } 3107 DSAStack->setForceVarCapturing(/*V=*/false); 3108 } else if (CaptureRegions.size() > 1 || 3109 CaptureRegions.back() != OMPD_unknown) { 3110 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3111 PICs.push_back(C); 3112 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3113 if (Expr *E = C->getPostUpdateExpr()) 3114 MarkDeclarationsReferencedInExpr(E); 3115 } 3116 } 3117 if (Clause->getClauseKind() == OMPC_schedule) 3118 SC = cast<OMPScheduleClause>(Clause); 3119 else if (Clause->getClauseKind() == OMPC_ordered) 3120 OC = cast<OMPOrderedClause>(Clause); 3121 else if (Clause->getClauseKind() == OMPC_linear) 3122 LCs.push_back(cast<OMPLinearClause>(Clause)); 3123 } 3124 // OpenMP, 2.7.1 Loop Construct, Restrictions 3125 // The nonmonotonic modifier cannot be specified if an ordered clause is 3126 // specified. 3127 if (SC && 3128 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3129 SC->getSecondScheduleModifier() == 3130 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3131 OC) { 3132 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3133 ? SC->getFirstScheduleModifierLoc() 3134 : SC->getSecondScheduleModifierLoc(), 3135 diag::err_omp_schedule_nonmonotonic_ordered) 3136 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3137 ErrorFound = true; 3138 } 3139 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3140 for (const OMPLinearClause *C : LCs) { 3141 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3142 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3143 } 3144 ErrorFound = true; 3145 } 3146 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3147 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3148 OC->getNumForLoops()) { 3149 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3150 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3151 ErrorFound = true; 3152 } 3153 if (ErrorFound) { 3154 return StmtError(); 3155 } 3156 StmtResult SR = S; 3157 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3158 // Mark all variables in private list clauses as used in inner region. 3159 // Required for proper codegen of combined directives. 3160 // TODO: add processing for other clauses. 3161 if (ThisCaptureRegion != OMPD_unknown) { 3162 for (const clang::OMPClauseWithPreInit *C : PICs) { 3163 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3164 // Find the particular capture region for the clause if the 3165 // directive is a combined one with multiple capture regions. 3166 // If the directive is not a combined one, the capture region 3167 // associated with the clause is OMPD_unknown and is generated 3168 // only once. 3169 if (CaptureRegion == ThisCaptureRegion || 3170 CaptureRegion == OMPD_unknown) { 3171 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3172 for (Decl *D : DS->decls()) 3173 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3174 } 3175 } 3176 } 3177 } 3178 SR = ActOnCapturedRegionEnd(SR.get()); 3179 } 3180 return SR; 3181 } 3182 3183 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3184 OpenMPDirectiveKind CancelRegion, 3185 SourceLocation StartLoc) { 3186 // CancelRegion is only needed for cancel and cancellation_point. 3187 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3188 return false; 3189 3190 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3191 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3192 return false; 3193 3194 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3195 << getOpenMPDirectiveName(CancelRegion); 3196 return true; 3197 } 3198 3199 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3200 OpenMPDirectiveKind CurrentRegion, 3201 const DeclarationNameInfo &CurrentName, 3202 OpenMPDirectiveKind CancelRegion, 3203 SourceLocation StartLoc) { 3204 if (Stack->getCurScope()) { 3205 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3206 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3207 bool NestingProhibited = false; 3208 bool CloseNesting = true; 3209 bool OrphanSeen = false; 3210 enum { 3211 NoRecommend, 3212 ShouldBeInParallelRegion, 3213 ShouldBeInOrderedRegion, 3214 ShouldBeInTargetRegion, 3215 ShouldBeInTeamsRegion 3216 } Recommend = NoRecommend; 3217 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3218 // OpenMP [2.16, Nesting of Regions] 3219 // OpenMP constructs may not be nested inside a simd region. 3220 // OpenMP [2.8.1,simd Construct, Restrictions] 3221 // An ordered construct with the simd clause is the only OpenMP 3222 // construct that can appear in the simd region. 3223 // Allowing a SIMD construct nested in another SIMD construct is an 3224 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3225 // message. 3226 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3227 ? diag::err_omp_prohibited_region_simd 3228 : diag::warn_omp_nesting_simd); 3229 return CurrentRegion != OMPD_simd; 3230 } 3231 if (ParentRegion == OMPD_atomic) { 3232 // OpenMP [2.16, Nesting of Regions] 3233 // OpenMP constructs may not be nested inside an atomic region. 3234 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3235 return true; 3236 } 3237 if (CurrentRegion == OMPD_section) { 3238 // OpenMP [2.7.2, sections Construct, Restrictions] 3239 // Orphaned section directives are prohibited. That is, the section 3240 // directives must appear within the sections construct and must not be 3241 // encountered elsewhere in the sections region. 3242 if (ParentRegion != OMPD_sections && 3243 ParentRegion != OMPD_parallel_sections) { 3244 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3245 << (ParentRegion != OMPD_unknown) 3246 << getOpenMPDirectiveName(ParentRegion); 3247 return true; 3248 } 3249 return false; 3250 } 3251 // Allow some constructs (except teams and cancellation constructs) to be 3252 // orphaned (they could be used in functions, called from OpenMP regions 3253 // with the required preconditions). 3254 if (ParentRegion == OMPD_unknown && 3255 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3256 CurrentRegion != OMPD_cancellation_point && 3257 CurrentRegion != OMPD_cancel) 3258 return false; 3259 if (CurrentRegion == OMPD_cancellation_point || 3260 CurrentRegion == OMPD_cancel) { 3261 // OpenMP [2.16, Nesting of Regions] 3262 // A cancellation point construct for which construct-type-clause is 3263 // taskgroup must be nested inside a task construct. A cancellation 3264 // point construct for which construct-type-clause is not taskgroup must 3265 // be closely nested inside an OpenMP construct that matches the type 3266 // specified in construct-type-clause. 3267 // A cancel construct for which construct-type-clause is taskgroup must be 3268 // nested inside a task construct. A cancel construct for which 3269 // construct-type-clause is not taskgroup must be closely nested inside an 3270 // OpenMP construct that matches the type specified in 3271 // construct-type-clause. 3272 NestingProhibited = 3273 !((CancelRegion == OMPD_parallel && 3274 (ParentRegion == OMPD_parallel || 3275 ParentRegion == OMPD_target_parallel)) || 3276 (CancelRegion == OMPD_for && 3277 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3278 ParentRegion == OMPD_target_parallel_for || 3279 ParentRegion == OMPD_distribute_parallel_for || 3280 ParentRegion == OMPD_teams_distribute_parallel_for || 3281 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3282 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3283 (CancelRegion == OMPD_sections && 3284 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3285 ParentRegion == OMPD_parallel_sections))); 3286 OrphanSeen = ParentRegion == OMPD_unknown; 3287 } else if (CurrentRegion == OMPD_master) { 3288 // OpenMP [2.16, Nesting of Regions] 3289 // A master region may not be closely nested inside a worksharing, 3290 // atomic, or explicit task region. 3291 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3292 isOpenMPTaskingDirective(ParentRegion); 3293 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3294 // OpenMP [2.16, Nesting of Regions] 3295 // A critical region may not be nested (closely or otherwise) inside a 3296 // critical region with the same name. Note that this restriction is not 3297 // sufficient to prevent deadlock. 3298 SourceLocation PreviousCriticalLoc; 3299 bool DeadLock = Stack->hasDirective( 3300 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3301 const DeclarationNameInfo &DNI, 3302 SourceLocation Loc) { 3303 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3304 PreviousCriticalLoc = Loc; 3305 return true; 3306 } 3307 return false; 3308 }, 3309 false /* skip top directive */); 3310 if (DeadLock) { 3311 SemaRef.Diag(StartLoc, 3312 diag::err_omp_prohibited_region_critical_same_name) 3313 << CurrentName.getName(); 3314 if (PreviousCriticalLoc.isValid()) 3315 SemaRef.Diag(PreviousCriticalLoc, 3316 diag::note_omp_previous_critical_region); 3317 return true; 3318 } 3319 } else if (CurrentRegion == OMPD_barrier) { 3320 // OpenMP [2.16, Nesting of Regions] 3321 // A barrier region may not be closely nested inside a worksharing, 3322 // explicit task, critical, ordered, atomic, or master region. 3323 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3324 isOpenMPTaskingDirective(ParentRegion) || 3325 ParentRegion == OMPD_master || 3326 ParentRegion == OMPD_critical || 3327 ParentRegion == OMPD_ordered; 3328 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3329 !isOpenMPParallelDirective(CurrentRegion) && 3330 !isOpenMPTeamsDirective(CurrentRegion)) { 3331 // OpenMP [2.16, Nesting of Regions] 3332 // A worksharing region may not be closely nested inside a worksharing, 3333 // explicit task, critical, ordered, atomic, or master region. 3334 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3335 isOpenMPTaskingDirective(ParentRegion) || 3336 ParentRegion == OMPD_master || 3337 ParentRegion == OMPD_critical || 3338 ParentRegion == OMPD_ordered; 3339 Recommend = ShouldBeInParallelRegion; 3340 } else if (CurrentRegion == OMPD_ordered) { 3341 // OpenMP [2.16, Nesting of Regions] 3342 // An ordered region may not be closely nested inside a critical, 3343 // atomic, or explicit task region. 3344 // An ordered region must be closely nested inside a loop region (or 3345 // parallel loop region) with an ordered clause. 3346 // OpenMP [2.8.1,simd Construct, Restrictions] 3347 // An ordered construct with the simd clause is the only OpenMP construct 3348 // that can appear in the simd region. 3349 NestingProhibited = ParentRegion == OMPD_critical || 3350 isOpenMPTaskingDirective(ParentRegion) || 3351 !(isOpenMPSimdDirective(ParentRegion) || 3352 Stack->isParentOrderedRegion()); 3353 Recommend = ShouldBeInOrderedRegion; 3354 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3355 // OpenMP [2.16, Nesting of Regions] 3356 // If specified, a teams construct must be contained within a target 3357 // construct. 3358 NestingProhibited = ParentRegion != OMPD_target; 3359 OrphanSeen = ParentRegion == OMPD_unknown; 3360 Recommend = ShouldBeInTargetRegion; 3361 } 3362 if (!NestingProhibited && 3363 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3364 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3365 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3366 // OpenMP [2.16, Nesting of Regions] 3367 // distribute, parallel, parallel sections, parallel workshare, and the 3368 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3369 // constructs that can be closely nested in the teams region. 3370 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3371 !isOpenMPDistributeDirective(CurrentRegion); 3372 Recommend = ShouldBeInParallelRegion; 3373 } 3374 if (!NestingProhibited && 3375 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3376 // OpenMP 4.5 [2.17 Nesting of Regions] 3377 // The region associated with the distribute construct must be strictly 3378 // nested inside a teams region 3379 NestingProhibited = 3380 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3381 Recommend = ShouldBeInTeamsRegion; 3382 } 3383 if (!NestingProhibited && 3384 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3385 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3386 // OpenMP 4.5 [2.17 Nesting of Regions] 3387 // If a target, target update, target data, target enter data, or 3388 // target exit data construct is encountered during execution of a 3389 // target region, the behavior is unspecified. 3390 NestingProhibited = Stack->hasDirective( 3391 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3392 SourceLocation) { 3393 if (isOpenMPTargetExecutionDirective(K)) { 3394 OffendingRegion = K; 3395 return true; 3396 } 3397 return false; 3398 }, 3399 false /* don't skip top directive */); 3400 CloseNesting = false; 3401 } 3402 if (NestingProhibited) { 3403 if (OrphanSeen) { 3404 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3405 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3406 } else { 3407 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3408 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3409 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3410 } 3411 return true; 3412 } 3413 } 3414 return false; 3415 } 3416 3417 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3418 ArrayRef<OMPClause *> Clauses, 3419 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3420 bool ErrorFound = false; 3421 unsigned NamedModifiersNumber = 0; 3422 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3423 OMPD_unknown + 1); 3424 SmallVector<SourceLocation, 4> NameModifierLoc; 3425 for (const OMPClause *C : Clauses) { 3426 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3427 // At most one if clause without a directive-name-modifier can appear on 3428 // the directive. 3429 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3430 if (FoundNameModifiers[CurNM]) { 3431 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3432 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3433 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3434 ErrorFound = true; 3435 } else if (CurNM != OMPD_unknown) { 3436 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3437 ++NamedModifiersNumber; 3438 } 3439 FoundNameModifiers[CurNM] = IC; 3440 if (CurNM == OMPD_unknown) 3441 continue; 3442 // Check if the specified name modifier is allowed for the current 3443 // directive. 3444 // At most one if clause with the particular directive-name-modifier can 3445 // appear on the directive. 3446 bool MatchFound = false; 3447 for (auto NM : AllowedNameModifiers) { 3448 if (CurNM == NM) { 3449 MatchFound = true; 3450 break; 3451 } 3452 } 3453 if (!MatchFound) { 3454 S.Diag(IC->getNameModifierLoc(), 3455 diag::err_omp_wrong_if_directive_name_modifier) 3456 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3457 ErrorFound = true; 3458 } 3459 } 3460 } 3461 // If any if clause on the directive includes a directive-name-modifier then 3462 // all if clauses on the directive must include a directive-name-modifier. 3463 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3464 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3465 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3466 diag::err_omp_no_more_if_clause); 3467 } else { 3468 std::string Values; 3469 std::string Sep(", "); 3470 unsigned AllowedCnt = 0; 3471 unsigned TotalAllowedNum = 3472 AllowedNameModifiers.size() - NamedModifiersNumber; 3473 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3474 ++Cnt) { 3475 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3476 if (!FoundNameModifiers[NM]) { 3477 Values += "'"; 3478 Values += getOpenMPDirectiveName(NM); 3479 Values += "'"; 3480 if (AllowedCnt + 2 == TotalAllowedNum) 3481 Values += " or "; 3482 else if (AllowedCnt + 1 != TotalAllowedNum) 3483 Values += Sep; 3484 ++AllowedCnt; 3485 } 3486 } 3487 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3488 diag::err_omp_unnamed_if_clause) 3489 << (TotalAllowedNum > 1) << Values; 3490 } 3491 for (SourceLocation Loc : NameModifierLoc) { 3492 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3493 } 3494 ErrorFound = true; 3495 } 3496 return ErrorFound; 3497 } 3498 3499 StmtResult Sema::ActOnOpenMPExecutableDirective( 3500 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3501 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3502 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3503 StmtResult Res = StmtError(); 3504 // First check CancelRegion which is then used in checkNestingOfRegions. 3505 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3506 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3507 StartLoc)) 3508 return StmtError(); 3509 3510 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3511 VarsWithInheritedDSAType VarsWithInheritedDSA; 3512 bool ErrorFound = false; 3513 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3514 if (AStmt && !CurContext->isDependentContext()) { 3515 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3516 3517 // Check default data sharing attributes for referenced variables. 3518 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3519 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3520 Stmt *S = AStmt; 3521 while (--ThisCaptureLevel >= 0) 3522 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3523 DSAChecker.Visit(S); 3524 if (DSAChecker.isErrorFound()) 3525 return StmtError(); 3526 // Generate list of implicitly defined firstprivate variables. 3527 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3528 3529 SmallVector<Expr *, 4> ImplicitFirstprivates( 3530 DSAChecker.getImplicitFirstprivate().begin(), 3531 DSAChecker.getImplicitFirstprivate().end()); 3532 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3533 DSAChecker.getImplicitMap().end()); 3534 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3535 for (OMPClause *C : Clauses) { 3536 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3537 for (Expr *E : IRC->taskgroup_descriptors()) 3538 if (E) 3539 ImplicitFirstprivates.emplace_back(E); 3540 } 3541 } 3542 if (!ImplicitFirstprivates.empty()) { 3543 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3544 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3545 SourceLocation())) { 3546 ClausesWithImplicit.push_back(Implicit); 3547 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3548 ImplicitFirstprivates.size(); 3549 } else { 3550 ErrorFound = true; 3551 } 3552 } 3553 if (!ImplicitMaps.empty()) { 3554 CXXScopeSpec MapperIdScopeSpec; 3555 DeclarationNameInfo MapperId; 3556 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3557 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 3558 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 3559 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 3560 ClausesWithImplicit.emplace_back(Implicit); 3561 ErrorFound |= 3562 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3563 } else { 3564 ErrorFound = true; 3565 } 3566 } 3567 } 3568 3569 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3570 switch (Kind) { 3571 case OMPD_parallel: 3572 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3573 EndLoc); 3574 AllowedNameModifiers.push_back(OMPD_parallel); 3575 break; 3576 case OMPD_simd: 3577 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3578 VarsWithInheritedDSA); 3579 break; 3580 case OMPD_for: 3581 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3582 VarsWithInheritedDSA); 3583 break; 3584 case OMPD_for_simd: 3585 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3586 EndLoc, VarsWithInheritedDSA); 3587 break; 3588 case OMPD_sections: 3589 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3590 EndLoc); 3591 break; 3592 case OMPD_section: 3593 assert(ClausesWithImplicit.empty() && 3594 "No clauses are allowed for 'omp section' directive"); 3595 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3596 break; 3597 case OMPD_single: 3598 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3599 EndLoc); 3600 break; 3601 case OMPD_master: 3602 assert(ClausesWithImplicit.empty() && 3603 "No clauses are allowed for 'omp master' directive"); 3604 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3605 break; 3606 case OMPD_critical: 3607 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3608 StartLoc, EndLoc); 3609 break; 3610 case OMPD_parallel_for: 3611 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3612 EndLoc, VarsWithInheritedDSA); 3613 AllowedNameModifiers.push_back(OMPD_parallel); 3614 break; 3615 case OMPD_parallel_for_simd: 3616 Res = ActOnOpenMPParallelForSimdDirective( 3617 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3618 AllowedNameModifiers.push_back(OMPD_parallel); 3619 break; 3620 case OMPD_parallel_sections: 3621 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3622 StartLoc, EndLoc); 3623 AllowedNameModifiers.push_back(OMPD_parallel); 3624 break; 3625 case OMPD_task: 3626 Res = 3627 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3628 AllowedNameModifiers.push_back(OMPD_task); 3629 break; 3630 case OMPD_taskyield: 3631 assert(ClausesWithImplicit.empty() && 3632 "No clauses are allowed for 'omp taskyield' directive"); 3633 assert(AStmt == nullptr && 3634 "No associated statement allowed for 'omp taskyield' directive"); 3635 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3636 break; 3637 case OMPD_barrier: 3638 assert(ClausesWithImplicit.empty() && 3639 "No clauses are allowed for 'omp barrier' directive"); 3640 assert(AStmt == nullptr && 3641 "No associated statement allowed for 'omp barrier' directive"); 3642 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3643 break; 3644 case OMPD_taskwait: 3645 assert(ClausesWithImplicit.empty() && 3646 "No clauses are allowed for 'omp taskwait' directive"); 3647 assert(AStmt == nullptr && 3648 "No associated statement allowed for 'omp taskwait' directive"); 3649 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3650 break; 3651 case OMPD_taskgroup: 3652 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 3653 EndLoc); 3654 break; 3655 case OMPD_flush: 3656 assert(AStmt == nullptr && 3657 "No associated statement allowed for 'omp flush' directive"); 3658 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3659 break; 3660 case OMPD_ordered: 3661 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3662 EndLoc); 3663 break; 3664 case OMPD_atomic: 3665 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3666 EndLoc); 3667 break; 3668 case OMPD_teams: 3669 Res = 3670 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3671 break; 3672 case OMPD_target: 3673 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3674 EndLoc); 3675 AllowedNameModifiers.push_back(OMPD_target); 3676 break; 3677 case OMPD_target_parallel: 3678 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3679 StartLoc, EndLoc); 3680 AllowedNameModifiers.push_back(OMPD_target); 3681 AllowedNameModifiers.push_back(OMPD_parallel); 3682 break; 3683 case OMPD_target_parallel_for: 3684 Res = ActOnOpenMPTargetParallelForDirective( 3685 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3686 AllowedNameModifiers.push_back(OMPD_target); 3687 AllowedNameModifiers.push_back(OMPD_parallel); 3688 break; 3689 case OMPD_cancellation_point: 3690 assert(ClausesWithImplicit.empty() && 3691 "No clauses are allowed for 'omp cancellation point' directive"); 3692 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3693 "cancellation point' directive"); 3694 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3695 break; 3696 case OMPD_cancel: 3697 assert(AStmt == nullptr && 3698 "No associated statement allowed for 'omp cancel' directive"); 3699 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3700 CancelRegion); 3701 AllowedNameModifiers.push_back(OMPD_cancel); 3702 break; 3703 case OMPD_target_data: 3704 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3705 EndLoc); 3706 AllowedNameModifiers.push_back(OMPD_target_data); 3707 break; 3708 case OMPD_target_enter_data: 3709 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3710 EndLoc, AStmt); 3711 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3712 break; 3713 case OMPD_target_exit_data: 3714 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3715 EndLoc, AStmt); 3716 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3717 break; 3718 case OMPD_taskloop: 3719 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3720 EndLoc, VarsWithInheritedDSA); 3721 AllowedNameModifiers.push_back(OMPD_taskloop); 3722 break; 3723 case OMPD_taskloop_simd: 3724 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3725 EndLoc, VarsWithInheritedDSA); 3726 AllowedNameModifiers.push_back(OMPD_taskloop); 3727 break; 3728 case OMPD_distribute: 3729 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3730 EndLoc, VarsWithInheritedDSA); 3731 break; 3732 case OMPD_target_update: 3733 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 3734 EndLoc, AStmt); 3735 AllowedNameModifiers.push_back(OMPD_target_update); 3736 break; 3737 case OMPD_distribute_parallel_for: 3738 Res = ActOnOpenMPDistributeParallelForDirective( 3739 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3740 AllowedNameModifiers.push_back(OMPD_parallel); 3741 break; 3742 case OMPD_distribute_parallel_for_simd: 3743 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3744 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3745 AllowedNameModifiers.push_back(OMPD_parallel); 3746 break; 3747 case OMPD_distribute_simd: 3748 Res = ActOnOpenMPDistributeSimdDirective( 3749 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3750 break; 3751 case OMPD_target_parallel_for_simd: 3752 Res = ActOnOpenMPTargetParallelForSimdDirective( 3753 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3754 AllowedNameModifiers.push_back(OMPD_target); 3755 AllowedNameModifiers.push_back(OMPD_parallel); 3756 break; 3757 case OMPD_target_simd: 3758 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3759 EndLoc, VarsWithInheritedDSA); 3760 AllowedNameModifiers.push_back(OMPD_target); 3761 break; 3762 case OMPD_teams_distribute: 3763 Res = ActOnOpenMPTeamsDistributeDirective( 3764 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3765 break; 3766 case OMPD_teams_distribute_simd: 3767 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3768 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3769 break; 3770 case OMPD_teams_distribute_parallel_for_simd: 3771 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3772 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3773 AllowedNameModifiers.push_back(OMPD_parallel); 3774 break; 3775 case OMPD_teams_distribute_parallel_for: 3776 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3777 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3778 AllowedNameModifiers.push_back(OMPD_parallel); 3779 break; 3780 case OMPD_target_teams: 3781 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3782 EndLoc); 3783 AllowedNameModifiers.push_back(OMPD_target); 3784 break; 3785 case OMPD_target_teams_distribute: 3786 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3787 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3788 AllowedNameModifiers.push_back(OMPD_target); 3789 break; 3790 case OMPD_target_teams_distribute_parallel_for: 3791 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3792 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3793 AllowedNameModifiers.push_back(OMPD_target); 3794 AllowedNameModifiers.push_back(OMPD_parallel); 3795 break; 3796 case OMPD_target_teams_distribute_parallel_for_simd: 3797 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3798 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3799 AllowedNameModifiers.push_back(OMPD_target); 3800 AllowedNameModifiers.push_back(OMPD_parallel); 3801 break; 3802 case OMPD_target_teams_distribute_simd: 3803 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3804 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3805 AllowedNameModifiers.push_back(OMPD_target); 3806 break; 3807 case OMPD_declare_target: 3808 case OMPD_end_declare_target: 3809 case OMPD_threadprivate: 3810 case OMPD_allocate: 3811 case OMPD_declare_reduction: 3812 case OMPD_declare_mapper: 3813 case OMPD_declare_simd: 3814 case OMPD_requires: 3815 llvm_unreachable("OpenMP Directive is not allowed"); 3816 case OMPD_unknown: 3817 llvm_unreachable("Unknown OpenMP directive"); 3818 } 3819 3820 for (const auto &P : VarsWithInheritedDSA) { 3821 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3822 << P.first << P.second->getSourceRange(); 3823 } 3824 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3825 3826 if (!AllowedNameModifiers.empty()) 3827 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3828 ErrorFound; 3829 3830 if (ErrorFound) 3831 return StmtError(); 3832 return Res; 3833 } 3834 3835 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3836 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3837 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3838 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3839 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3840 assert(Aligneds.size() == Alignments.size()); 3841 assert(Linears.size() == LinModifiers.size()); 3842 assert(Linears.size() == Steps.size()); 3843 if (!DG || DG.get().isNull()) 3844 return DeclGroupPtrTy(); 3845 3846 if (!DG.get().isSingleDecl()) { 3847 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3848 return DG; 3849 } 3850 Decl *ADecl = DG.get().getSingleDecl(); 3851 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3852 ADecl = FTD->getTemplatedDecl(); 3853 3854 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3855 if (!FD) { 3856 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3857 return DeclGroupPtrTy(); 3858 } 3859 3860 // OpenMP [2.8.2, declare simd construct, Description] 3861 // The parameter of the simdlen clause must be a constant positive integer 3862 // expression. 3863 ExprResult SL; 3864 if (Simdlen) 3865 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3866 // OpenMP [2.8.2, declare simd construct, Description] 3867 // The special this pointer can be used as if was one of the arguments to the 3868 // function in any of the linear, aligned, or uniform clauses. 3869 // The uniform clause declares one or more arguments to have an invariant 3870 // value for all concurrent invocations of the function in the execution of a 3871 // single SIMD loop. 3872 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 3873 const Expr *UniformedLinearThis = nullptr; 3874 for (const Expr *E : Uniforms) { 3875 E = E->IgnoreParenImpCasts(); 3876 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3877 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3878 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3879 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3880 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3881 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 3882 continue; 3883 } 3884 if (isa<CXXThisExpr>(E)) { 3885 UniformedLinearThis = E; 3886 continue; 3887 } 3888 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3889 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3890 } 3891 // OpenMP [2.8.2, declare simd construct, Description] 3892 // The aligned clause declares that the object to which each list item points 3893 // is aligned to the number of bytes expressed in the optional parameter of 3894 // the aligned clause. 3895 // The special this pointer can be used as if was one of the arguments to the 3896 // function in any of the linear, aligned, or uniform clauses. 3897 // The type of list items appearing in the aligned clause must be array, 3898 // pointer, reference to array, or reference to pointer. 3899 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 3900 const Expr *AlignedThis = nullptr; 3901 for (const Expr *E : Aligneds) { 3902 E = E->IgnoreParenImpCasts(); 3903 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3904 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3905 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3906 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3907 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3908 ->getCanonicalDecl() == CanonPVD) { 3909 // OpenMP [2.8.1, simd construct, Restrictions] 3910 // A list-item cannot appear in more than one aligned clause. 3911 if (AlignedArgs.count(CanonPVD) > 0) { 3912 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3913 << 1 << E->getSourceRange(); 3914 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3915 diag::note_omp_explicit_dsa) 3916 << getOpenMPClauseName(OMPC_aligned); 3917 continue; 3918 } 3919 AlignedArgs[CanonPVD] = E; 3920 QualType QTy = PVD->getType() 3921 .getNonReferenceType() 3922 .getUnqualifiedType() 3923 .getCanonicalType(); 3924 const Type *Ty = QTy.getTypePtrOrNull(); 3925 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3926 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3927 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3928 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3929 } 3930 continue; 3931 } 3932 } 3933 if (isa<CXXThisExpr>(E)) { 3934 if (AlignedThis) { 3935 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3936 << 2 << E->getSourceRange(); 3937 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3938 << getOpenMPClauseName(OMPC_aligned); 3939 } 3940 AlignedThis = E; 3941 continue; 3942 } 3943 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3944 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3945 } 3946 // The optional parameter of the aligned clause, alignment, must be a constant 3947 // positive integer expression. If no optional parameter is specified, 3948 // implementation-defined default alignments for SIMD instructions on the 3949 // target platforms are assumed. 3950 SmallVector<const Expr *, 4> NewAligns; 3951 for (Expr *E : Alignments) { 3952 ExprResult Align; 3953 if (E) 3954 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3955 NewAligns.push_back(Align.get()); 3956 } 3957 // OpenMP [2.8.2, declare simd construct, Description] 3958 // The linear clause declares one or more list items to be private to a SIMD 3959 // lane and to have a linear relationship with respect to the iteration space 3960 // of a loop. 3961 // The special this pointer can be used as if was one of the arguments to the 3962 // function in any of the linear, aligned, or uniform clauses. 3963 // When a linear-step expression is specified in a linear clause it must be 3964 // either a constant integer expression or an integer-typed parameter that is 3965 // specified in a uniform clause on the directive. 3966 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 3967 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3968 auto MI = LinModifiers.begin(); 3969 for (const Expr *E : Linears) { 3970 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3971 ++MI; 3972 E = E->IgnoreParenImpCasts(); 3973 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3974 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3975 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3976 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3977 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3978 ->getCanonicalDecl() == CanonPVD) { 3979 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3980 // A list-item cannot appear in more than one linear clause. 3981 if (LinearArgs.count(CanonPVD) > 0) { 3982 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3983 << getOpenMPClauseName(OMPC_linear) 3984 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3985 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3986 diag::note_omp_explicit_dsa) 3987 << getOpenMPClauseName(OMPC_linear); 3988 continue; 3989 } 3990 // Each argument can appear in at most one uniform or linear clause. 3991 if (UniformedArgs.count(CanonPVD) > 0) { 3992 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3993 << getOpenMPClauseName(OMPC_linear) 3994 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3995 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3996 diag::note_omp_explicit_dsa) 3997 << getOpenMPClauseName(OMPC_uniform); 3998 continue; 3999 } 4000 LinearArgs[CanonPVD] = E; 4001 if (E->isValueDependent() || E->isTypeDependent() || 4002 E->isInstantiationDependent() || 4003 E->containsUnexpandedParameterPack()) 4004 continue; 4005 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4006 PVD->getOriginalType()); 4007 continue; 4008 } 4009 } 4010 if (isa<CXXThisExpr>(E)) { 4011 if (UniformedLinearThis) { 4012 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4013 << getOpenMPClauseName(OMPC_linear) 4014 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4015 << E->getSourceRange(); 4016 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4017 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4018 : OMPC_linear); 4019 continue; 4020 } 4021 UniformedLinearThis = E; 4022 if (E->isValueDependent() || E->isTypeDependent() || 4023 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4024 continue; 4025 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4026 E->getType()); 4027 continue; 4028 } 4029 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4030 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4031 } 4032 Expr *Step = nullptr; 4033 Expr *NewStep = nullptr; 4034 SmallVector<Expr *, 4> NewSteps; 4035 for (Expr *E : Steps) { 4036 // Skip the same step expression, it was checked already. 4037 if (Step == E || !E) { 4038 NewSteps.push_back(E ? NewStep : nullptr); 4039 continue; 4040 } 4041 Step = E; 4042 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4043 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4044 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4045 if (UniformedArgs.count(CanonPVD) == 0) { 4046 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4047 << Step->getSourceRange(); 4048 } else if (E->isValueDependent() || E->isTypeDependent() || 4049 E->isInstantiationDependent() || 4050 E->containsUnexpandedParameterPack() || 4051 CanonPVD->getType()->hasIntegerRepresentation()) { 4052 NewSteps.push_back(Step); 4053 } else { 4054 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4055 << Step->getSourceRange(); 4056 } 4057 continue; 4058 } 4059 NewStep = Step; 4060 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4061 !Step->isInstantiationDependent() && 4062 !Step->containsUnexpandedParameterPack()) { 4063 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4064 .get(); 4065 if (NewStep) 4066 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4067 } 4068 NewSteps.push_back(NewStep); 4069 } 4070 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4071 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4072 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4073 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4074 const_cast<Expr **>(Linears.data()), Linears.size(), 4075 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4076 NewSteps.data(), NewSteps.size(), SR); 4077 ADecl->addAttr(NewAttr); 4078 return ConvertDeclToDeclGroup(ADecl); 4079 } 4080 4081 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4082 Stmt *AStmt, 4083 SourceLocation StartLoc, 4084 SourceLocation EndLoc) { 4085 if (!AStmt) 4086 return StmtError(); 4087 4088 auto *CS = cast<CapturedStmt>(AStmt); 4089 // 1.2.2 OpenMP Language Terminology 4090 // Structured block - An executable statement with a single entry at the 4091 // top and a single exit at the bottom. 4092 // The point of exit cannot be a branch out of the structured block. 4093 // longjmp() and throw() must not violate the entry/exit criteria. 4094 CS->getCapturedDecl()->setNothrow(); 4095 4096 setFunctionHasBranchProtectedScope(); 4097 4098 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4099 DSAStack->isCancelRegion()); 4100 } 4101 4102 namespace { 4103 /// Helper class for checking canonical form of the OpenMP loops and 4104 /// extracting iteration space of each loop in the loop nest, that will be used 4105 /// for IR generation. 4106 class OpenMPIterationSpaceChecker { 4107 /// Reference to Sema. 4108 Sema &SemaRef; 4109 /// A location for diagnostics (when there is no some better location). 4110 SourceLocation DefaultLoc; 4111 /// A location for diagnostics (when increment is not compatible). 4112 SourceLocation ConditionLoc; 4113 /// A source location for referring to loop init later. 4114 SourceRange InitSrcRange; 4115 /// A source location for referring to condition later. 4116 SourceRange ConditionSrcRange; 4117 /// A source location for referring to increment later. 4118 SourceRange IncrementSrcRange; 4119 /// Loop variable. 4120 ValueDecl *LCDecl = nullptr; 4121 /// Reference to loop variable. 4122 Expr *LCRef = nullptr; 4123 /// Lower bound (initializer for the var). 4124 Expr *LB = nullptr; 4125 /// Upper bound. 4126 Expr *UB = nullptr; 4127 /// Loop step (increment). 4128 Expr *Step = nullptr; 4129 /// This flag is true when condition is one of: 4130 /// Var < UB 4131 /// Var <= UB 4132 /// UB > Var 4133 /// UB >= Var 4134 /// This will have no value when the condition is != 4135 llvm::Optional<bool> TestIsLessOp; 4136 /// This flag is true when condition is strict ( < or > ). 4137 bool TestIsStrictOp = false; 4138 /// This flag is true when step is subtracted on each iteration. 4139 bool SubtractStep = false; 4140 4141 public: 4142 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 4143 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 4144 /// Check init-expr for canonical loop form and save loop counter 4145 /// variable - #Var and its initialization value - #LB. 4146 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4147 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4148 /// for less/greater and for strict/non-strict comparison. 4149 bool checkAndSetCond(Expr *S); 4150 /// Check incr-expr for canonical loop form and return true if it 4151 /// does not conform, otherwise save loop step (#Step). 4152 bool checkAndSetInc(Expr *S); 4153 /// Return the loop counter variable. 4154 ValueDecl *getLoopDecl() const { return LCDecl; } 4155 /// Return the reference expression to loop counter variable. 4156 Expr *getLoopDeclRefExpr() const { return LCRef; } 4157 /// Source range of the loop init. 4158 SourceRange getInitSrcRange() const { return InitSrcRange; } 4159 /// Source range of the loop condition. 4160 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4161 /// Source range of the loop increment. 4162 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4163 /// True if the step should be subtracted. 4164 bool shouldSubtractStep() const { return SubtractStep; } 4165 /// True, if the compare operator is strict (<, > or !=). 4166 bool isStrictTestOp() const { return TestIsStrictOp; } 4167 /// Build the expression to calculate the number of iterations. 4168 Expr *buildNumIterations( 4169 Scope *S, const bool LimitedType, 4170 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4171 /// Build the precondition expression for the loops. 4172 Expr * 4173 buildPreCond(Scope *S, Expr *Cond, 4174 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4175 /// Build reference expression to the counter be used for codegen. 4176 DeclRefExpr * 4177 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4178 DSAStackTy &DSA) const; 4179 /// Build reference expression to the private counter be used for 4180 /// codegen. 4181 Expr *buildPrivateCounterVar() const; 4182 /// Build initialization of the counter be used for codegen. 4183 Expr *buildCounterInit() const; 4184 /// Build step of the counter be used for codegen. 4185 Expr *buildCounterStep() const; 4186 /// Build loop data with counter value for depend clauses in ordered 4187 /// directives. 4188 Expr * 4189 buildOrderedLoopData(Scope *S, Expr *Counter, 4190 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4191 SourceLocation Loc, Expr *Inc = nullptr, 4192 OverloadedOperatorKind OOK = OO_Amp); 4193 /// Return true if any expression is dependent. 4194 bool dependent() const; 4195 4196 private: 4197 /// Check the right-hand side of an assignment in the increment 4198 /// expression. 4199 bool checkAndSetIncRHS(Expr *RHS); 4200 /// Helper to set loop counter variable and its initializer. 4201 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 4202 /// Helper to set upper bound. 4203 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4204 SourceRange SR, SourceLocation SL); 4205 /// Helper to set loop increment. 4206 bool setStep(Expr *NewStep, bool Subtract); 4207 }; 4208 4209 bool OpenMPIterationSpaceChecker::dependent() const { 4210 if (!LCDecl) { 4211 assert(!LB && !UB && !Step); 4212 return false; 4213 } 4214 return LCDecl->getType()->isDependentType() || 4215 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4216 (Step && Step->isValueDependent()); 4217 } 4218 4219 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4220 Expr *NewLCRefExpr, 4221 Expr *NewLB) { 4222 // State consistency checking to ensure correct usage. 4223 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4224 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4225 if (!NewLCDecl || !NewLB) 4226 return true; 4227 LCDecl = getCanonicalDecl(NewLCDecl); 4228 LCRef = NewLCRefExpr; 4229 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4230 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4231 if ((Ctor->isCopyOrMoveConstructor() || 4232 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4233 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4234 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4235 LB = NewLB; 4236 return false; 4237 } 4238 4239 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4240 llvm::Optional<bool> LessOp, 4241 bool StrictOp, SourceRange SR, 4242 SourceLocation SL) { 4243 // State consistency checking to ensure correct usage. 4244 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4245 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4246 if (!NewUB) 4247 return true; 4248 UB = NewUB; 4249 if (LessOp) 4250 TestIsLessOp = LessOp; 4251 TestIsStrictOp = StrictOp; 4252 ConditionSrcRange = SR; 4253 ConditionLoc = SL; 4254 return false; 4255 } 4256 4257 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4258 // State consistency checking to ensure correct usage. 4259 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4260 if (!NewStep) 4261 return true; 4262 if (!NewStep->isValueDependent()) { 4263 // Check that the step is integer expression. 4264 SourceLocation StepLoc = NewStep->getBeginLoc(); 4265 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4266 StepLoc, getExprAsWritten(NewStep)); 4267 if (Val.isInvalid()) 4268 return true; 4269 NewStep = Val.get(); 4270 4271 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4272 // If test-expr is of form var relational-op b and relational-op is < or 4273 // <= then incr-expr must cause var to increase on each iteration of the 4274 // loop. If test-expr is of form var relational-op b and relational-op is 4275 // > or >= then incr-expr must cause var to decrease on each iteration of 4276 // the loop. 4277 // If test-expr is of form b relational-op var and relational-op is < or 4278 // <= then incr-expr must cause var to decrease on each iteration of the 4279 // loop. If test-expr is of form b relational-op var and relational-op is 4280 // > or >= then incr-expr must cause var to increase on each iteration of 4281 // the loop. 4282 llvm::APSInt Result; 4283 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4284 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4285 bool IsConstNeg = 4286 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4287 bool IsConstPos = 4288 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4289 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4290 4291 // != with increment is treated as <; != with decrement is treated as > 4292 if (!TestIsLessOp.hasValue()) 4293 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4294 if (UB && (IsConstZero || 4295 (TestIsLessOp.getValue() ? 4296 (IsConstNeg || (IsUnsigned && Subtract)) : 4297 (IsConstPos || (IsUnsigned && !Subtract))))) { 4298 SemaRef.Diag(NewStep->getExprLoc(), 4299 diag::err_omp_loop_incr_not_compatible) 4300 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4301 SemaRef.Diag(ConditionLoc, 4302 diag::note_omp_loop_cond_requres_compatible_incr) 4303 << TestIsLessOp.getValue() << ConditionSrcRange; 4304 return true; 4305 } 4306 if (TestIsLessOp.getValue() == Subtract) { 4307 NewStep = 4308 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4309 .get(); 4310 Subtract = !Subtract; 4311 } 4312 } 4313 4314 Step = NewStep; 4315 SubtractStep = Subtract; 4316 return false; 4317 } 4318 4319 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 4320 // Check init-expr for canonical loop form and save loop counter 4321 // variable - #Var and its initialization value - #LB. 4322 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 4323 // var = lb 4324 // integer-type var = lb 4325 // random-access-iterator-type var = lb 4326 // pointer-type var = lb 4327 // 4328 if (!S) { 4329 if (EmitDiags) { 4330 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 4331 } 4332 return true; 4333 } 4334 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4335 if (!ExprTemp->cleanupsHaveSideEffects()) 4336 S = ExprTemp->getSubExpr(); 4337 4338 InitSrcRange = S->getSourceRange(); 4339 if (Expr *E = dyn_cast<Expr>(S)) 4340 S = E->IgnoreParens(); 4341 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4342 if (BO->getOpcode() == BO_Assign) { 4343 Expr *LHS = BO->getLHS()->IgnoreParens(); 4344 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4345 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4346 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4347 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4348 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 4349 } 4350 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4351 if (ME->isArrow() && 4352 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4353 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4354 } 4355 } 4356 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4357 if (DS->isSingleDecl()) { 4358 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4359 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4360 // Accept non-canonical init form here but emit ext. warning. 4361 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4362 SemaRef.Diag(S->getBeginLoc(), 4363 diag::ext_omp_loop_not_canonical_init) 4364 << S->getSourceRange(); 4365 return setLCDeclAndLB( 4366 Var, 4367 buildDeclRefExpr(SemaRef, Var, 4368 Var->getType().getNonReferenceType(), 4369 DS->getBeginLoc()), 4370 Var->getInit()); 4371 } 4372 } 4373 } 4374 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4375 if (CE->getOperator() == OO_Equal) { 4376 Expr *LHS = CE->getArg(0); 4377 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4378 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4379 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4380 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4381 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 4382 } 4383 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4384 if (ME->isArrow() && 4385 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4386 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4387 } 4388 } 4389 } 4390 4391 if (dependent() || SemaRef.CurContext->isDependentContext()) 4392 return false; 4393 if (EmitDiags) { 4394 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 4395 << S->getSourceRange(); 4396 } 4397 return true; 4398 } 4399 4400 /// Ignore parenthesizes, implicit casts, copy constructor and return the 4401 /// variable (which may be the loop variable) if possible. 4402 static const ValueDecl *getInitLCDecl(const Expr *E) { 4403 if (!E) 4404 return nullptr; 4405 E = getExprAsWritten(E); 4406 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 4407 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4408 if ((Ctor->isCopyOrMoveConstructor() || 4409 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4410 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4411 E = CE->getArg(0)->IgnoreParenImpCasts(); 4412 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 4413 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 4414 return getCanonicalDecl(VD); 4415 } 4416 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 4417 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4418 return getCanonicalDecl(ME->getMemberDecl()); 4419 return nullptr; 4420 } 4421 4422 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 4423 // Check test-expr for canonical form, save upper-bound UB, flags for 4424 // less/greater and for strict/non-strict comparison. 4425 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4426 // var relational-op b 4427 // b relational-op var 4428 // 4429 if (!S) { 4430 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 4431 return true; 4432 } 4433 S = getExprAsWritten(S); 4434 SourceLocation CondLoc = S->getBeginLoc(); 4435 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4436 if (BO->isRelationalOp()) { 4437 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4438 return setUB(BO->getRHS(), 4439 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4440 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4441 BO->getSourceRange(), BO->getOperatorLoc()); 4442 if (getInitLCDecl(BO->getRHS()) == LCDecl) 4443 return setUB(BO->getLHS(), 4444 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4445 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4446 BO->getSourceRange(), BO->getOperatorLoc()); 4447 } else if (BO->getOpcode() == BO_NE) 4448 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 4449 BO->getRHS() : BO->getLHS(), 4450 /*LessOp=*/llvm::None, 4451 /*StrictOp=*/true, 4452 BO->getSourceRange(), BO->getOperatorLoc()); 4453 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4454 if (CE->getNumArgs() == 2) { 4455 auto Op = CE->getOperator(); 4456 switch (Op) { 4457 case OO_Greater: 4458 case OO_GreaterEqual: 4459 case OO_Less: 4460 case OO_LessEqual: 4461 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4462 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4463 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4464 CE->getOperatorLoc()); 4465 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 4466 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4467 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4468 CE->getOperatorLoc()); 4469 break; 4470 case OO_ExclaimEqual: 4471 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 4472 CE->getArg(1) : CE->getArg(0), 4473 /*LessOp=*/llvm::None, 4474 /*StrictOp=*/true, 4475 CE->getSourceRange(), 4476 CE->getOperatorLoc()); 4477 break; 4478 default: 4479 break; 4480 } 4481 } 4482 } 4483 if (dependent() || SemaRef.CurContext->isDependentContext()) 4484 return false; 4485 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4486 << S->getSourceRange() << LCDecl; 4487 return true; 4488 } 4489 4490 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 4491 // RHS of canonical loop form increment can be: 4492 // var + incr 4493 // incr + var 4494 // var - incr 4495 // 4496 RHS = RHS->IgnoreParenImpCasts(); 4497 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 4498 if (BO->isAdditiveOp()) { 4499 bool IsAdd = BO->getOpcode() == BO_Add; 4500 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4501 return setStep(BO->getRHS(), !IsAdd); 4502 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 4503 return setStep(BO->getLHS(), /*Subtract=*/false); 4504 } 4505 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 4506 bool IsAdd = CE->getOperator() == OO_Plus; 4507 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 4508 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4509 return setStep(CE->getArg(1), !IsAdd); 4510 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 4511 return setStep(CE->getArg(0), /*Subtract=*/false); 4512 } 4513 } 4514 if (dependent() || SemaRef.CurContext->isDependentContext()) 4515 return false; 4516 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4517 << RHS->getSourceRange() << LCDecl; 4518 return true; 4519 } 4520 4521 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 4522 // Check incr-expr for canonical loop form and return true if it 4523 // does not conform. 4524 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4525 // ++var 4526 // var++ 4527 // --var 4528 // var-- 4529 // var += incr 4530 // var -= incr 4531 // var = var + incr 4532 // var = incr + var 4533 // var = var - incr 4534 // 4535 if (!S) { 4536 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 4537 return true; 4538 } 4539 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4540 if (!ExprTemp->cleanupsHaveSideEffects()) 4541 S = ExprTemp->getSubExpr(); 4542 4543 IncrementSrcRange = S->getSourceRange(); 4544 S = S->IgnoreParens(); 4545 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 4546 if (UO->isIncrementDecrementOp() && 4547 getInitLCDecl(UO->getSubExpr()) == LCDecl) 4548 return setStep(SemaRef 4549 .ActOnIntegerConstant(UO->getBeginLoc(), 4550 (UO->isDecrementOp() ? -1 : 1)) 4551 .get(), 4552 /*Subtract=*/false); 4553 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4554 switch (BO->getOpcode()) { 4555 case BO_AddAssign: 4556 case BO_SubAssign: 4557 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4558 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4559 break; 4560 case BO_Assign: 4561 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4562 return checkAndSetIncRHS(BO->getRHS()); 4563 break; 4564 default: 4565 break; 4566 } 4567 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4568 switch (CE->getOperator()) { 4569 case OO_PlusPlus: 4570 case OO_MinusMinus: 4571 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4572 return setStep(SemaRef 4573 .ActOnIntegerConstant( 4574 CE->getBeginLoc(), 4575 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 4576 .get(), 4577 /*Subtract=*/false); 4578 break; 4579 case OO_PlusEqual: 4580 case OO_MinusEqual: 4581 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4582 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4583 break; 4584 case OO_Equal: 4585 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4586 return checkAndSetIncRHS(CE->getArg(1)); 4587 break; 4588 default: 4589 break; 4590 } 4591 } 4592 if (dependent() || SemaRef.CurContext->isDependentContext()) 4593 return false; 4594 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4595 << S->getSourceRange() << LCDecl; 4596 return true; 4597 } 4598 4599 static ExprResult 4600 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4601 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4602 if (SemaRef.CurContext->isDependentContext()) 4603 return ExprResult(Capture); 4604 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4605 return SemaRef.PerformImplicitConversion( 4606 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4607 /*AllowExplicit=*/true); 4608 auto I = Captures.find(Capture); 4609 if (I != Captures.end()) 4610 return buildCapture(SemaRef, Capture, I->second); 4611 DeclRefExpr *Ref = nullptr; 4612 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4613 Captures[Capture] = Ref; 4614 return Res; 4615 } 4616 4617 /// Build the expression to calculate the number of iterations. 4618 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 4619 Scope *S, const bool LimitedType, 4620 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4621 ExprResult Diff; 4622 QualType VarType = LCDecl->getType().getNonReferenceType(); 4623 if (VarType->isIntegerType() || VarType->isPointerType() || 4624 SemaRef.getLangOpts().CPlusPlus) { 4625 // Upper - Lower 4626 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 4627 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 4628 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4629 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4630 if (!Upper || !Lower) 4631 return nullptr; 4632 4633 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4634 4635 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4636 // BuildBinOp already emitted error, this one is to point user to upper 4637 // and lower bound, and to tell what is passed to 'operator-'. 4638 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4639 << Upper->getSourceRange() << Lower->getSourceRange(); 4640 return nullptr; 4641 } 4642 } 4643 4644 if (!Diff.isUsable()) 4645 return nullptr; 4646 4647 // Upper - Lower [- 1] 4648 if (TestIsStrictOp) 4649 Diff = SemaRef.BuildBinOp( 4650 S, DefaultLoc, BO_Sub, Diff.get(), 4651 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4652 if (!Diff.isUsable()) 4653 return nullptr; 4654 4655 // Upper - Lower [- 1] + Step 4656 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4657 if (!NewStep.isUsable()) 4658 return nullptr; 4659 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4660 if (!Diff.isUsable()) 4661 return nullptr; 4662 4663 // Parentheses (for dumping/debugging purposes only). 4664 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4665 if (!Diff.isUsable()) 4666 return nullptr; 4667 4668 // (Upper - Lower [- 1] + Step) / Step 4669 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4670 if (!Diff.isUsable()) 4671 return nullptr; 4672 4673 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4674 QualType Type = Diff.get()->getType(); 4675 ASTContext &C = SemaRef.Context; 4676 bool UseVarType = VarType->hasIntegerRepresentation() && 4677 C.getTypeSize(Type) > C.getTypeSize(VarType); 4678 if (!Type->isIntegerType() || UseVarType) { 4679 unsigned NewSize = 4680 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4681 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4682 : Type->hasSignedIntegerRepresentation(); 4683 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4684 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4685 Diff = SemaRef.PerformImplicitConversion( 4686 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4687 if (!Diff.isUsable()) 4688 return nullptr; 4689 } 4690 } 4691 if (LimitedType) { 4692 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4693 if (NewSize != C.getTypeSize(Type)) { 4694 if (NewSize < C.getTypeSize(Type)) { 4695 assert(NewSize == 64 && "incorrect loop var size"); 4696 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4697 << InitSrcRange << ConditionSrcRange; 4698 } 4699 QualType NewType = C.getIntTypeForBitwidth( 4700 NewSize, Type->hasSignedIntegerRepresentation() || 4701 C.getTypeSize(Type) < NewSize); 4702 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4703 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4704 Sema::AA_Converting, true); 4705 if (!Diff.isUsable()) 4706 return nullptr; 4707 } 4708 } 4709 } 4710 4711 return Diff.get(); 4712 } 4713 4714 Expr *OpenMPIterationSpaceChecker::buildPreCond( 4715 Scope *S, Expr *Cond, 4716 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4717 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4718 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4719 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4720 4721 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 4722 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 4723 if (!NewLB.isUsable() || !NewUB.isUsable()) 4724 return nullptr; 4725 4726 ExprResult CondExpr = 4727 SemaRef.BuildBinOp(S, DefaultLoc, 4728 TestIsLessOp.getValue() ? 4729 (TestIsStrictOp ? BO_LT : BO_LE) : 4730 (TestIsStrictOp ? BO_GT : BO_GE), 4731 NewLB.get(), NewUB.get()); 4732 if (CondExpr.isUsable()) { 4733 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4734 SemaRef.Context.BoolTy)) 4735 CondExpr = SemaRef.PerformImplicitConversion( 4736 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4737 /*AllowExplicit=*/true); 4738 } 4739 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4740 // Otherwise use original loop condition and evaluate it in runtime. 4741 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4742 } 4743 4744 /// Build reference expression to the counter be used for codegen. 4745 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 4746 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4747 DSAStackTy &DSA) const { 4748 auto *VD = dyn_cast<VarDecl>(LCDecl); 4749 if (!VD) { 4750 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 4751 DeclRefExpr *Ref = buildDeclRefExpr( 4752 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4753 const DSAStackTy::DSAVarData Data = 4754 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4755 // If the loop control decl is explicitly marked as private, do not mark it 4756 // as captured again. 4757 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4758 Captures.insert(std::make_pair(LCRef, Ref)); 4759 return Ref; 4760 } 4761 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 4762 DefaultLoc); 4763 } 4764 4765 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 4766 if (LCDecl && !LCDecl->isInvalidDecl()) { 4767 QualType Type = LCDecl->getType().getNonReferenceType(); 4768 VarDecl *PrivateVar = buildVarDecl( 4769 SemaRef, DefaultLoc, Type, LCDecl->getName(), 4770 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 4771 isa<VarDecl>(LCDecl) 4772 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 4773 : nullptr); 4774 if (PrivateVar->isInvalidDecl()) 4775 return nullptr; 4776 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4777 } 4778 return nullptr; 4779 } 4780 4781 /// Build initialization of the counter to be used for codegen. 4782 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 4783 4784 /// Build step of the counter be used for codegen. 4785 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 4786 4787 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 4788 Scope *S, Expr *Counter, 4789 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 4790 Expr *Inc, OverloadedOperatorKind OOK) { 4791 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 4792 if (!Cnt) 4793 return nullptr; 4794 if (Inc) { 4795 assert((OOK == OO_Plus || OOK == OO_Minus) && 4796 "Expected only + or - operations for depend clauses."); 4797 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 4798 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 4799 if (!Cnt) 4800 return nullptr; 4801 } 4802 ExprResult Diff; 4803 QualType VarType = LCDecl->getType().getNonReferenceType(); 4804 if (VarType->isIntegerType() || VarType->isPointerType() || 4805 SemaRef.getLangOpts().CPlusPlus) { 4806 // Upper - Lower 4807 Expr *Upper = TestIsLessOp.getValue() 4808 ? Cnt 4809 : tryBuildCapture(SemaRef, UB, Captures).get(); 4810 Expr *Lower = TestIsLessOp.getValue() 4811 ? tryBuildCapture(SemaRef, LB, Captures).get() 4812 : Cnt; 4813 if (!Upper || !Lower) 4814 return nullptr; 4815 4816 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4817 4818 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4819 // BuildBinOp already emitted error, this one is to point user to upper 4820 // and lower bound, and to tell what is passed to 'operator-'. 4821 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4822 << Upper->getSourceRange() << Lower->getSourceRange(); 4823 return nullptr; 4824 } 4825 } 4826 4827 if (!Diff.isUsable()) 4828 return nullptr; 4829 4830 // Parentheses (for dumping/debugging purposes only). 4831 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4832 if (!Diff.isUsable()) 4833 return nullptr; 4834 4835 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4836 if (!NewStep.isUsable()) 4837 return nullptr; 4838 // (Upper - Lower) / Step 4839 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4840 if (!Diff.isUsable()) 4841 return nullptr; 4842 4843 return Diff.get(); 4844 } 4845 4846 /// Iteration space of a single for loop. 4847 struct LoopIterationSpace final { 4848 /// True if the condition operator is the strict compare operator (<, > or 4849 /// !=). 4850 bool IsStrictCompare = false; 4851 /// Condition of the loop. 4852 Expr *PreCond = nullptr; 4853 /// This expression calculates the number of iterations in the loop. 4854 /// It is always possible to calculate it before starting the loop. 4855 Expr *NumIterations = nullptr; 4856 /// The loop counter variable. 4857 Expr *CounterVar = nullptr; 4858 /// Private loop counter variable. 4859 Expr *PrivateCounterVar = nullptr; 4860 /// This is initializer for the initial value of #CounterVar. 4861 Expr *CounterInit = nullptr; 4862 /// This is step for the #CounterVar used to generate its update: 4863 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4864 Expr *CounterStep = nullptr; 4865 /// Should step be subtracted? 4866 bool Subtract = false; 4867 /// Source range of the loop init. 4868 SourceRange InitSrcRange; 4869 /// Source range of the loop condition. 4870 SourceRange CondSrcRange; 4871 /// Source range of the loop increment. 4872 SourceRange IncSrcRange; 4873 }; 4874 4875 } // namespace 4876 4877 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4878 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4879 assert(Init && "Expected loop in canonical form."); 4880 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4881 if (AssociatedLoops > 0 && 4882 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4883 DSAStack->loopStart(); 4884 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4885 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 4886 if (ValueDecl *D = ISC.getLoopDecl()) { 4887 auto *VD = dyn_cast<VarDecl>(D); 4888 if (!VD) { 4889 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 4890 VD = Private; 4891 } else { 4892 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 4893 /*WithInit=*/false); 4894 VD = cast<VarDecl>(Ref->getDecl()); 4895 } 4896 } 4897 DSAStack->addLoopControlVariable(D, VD); 4898 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 4899 if (LD != D->getCanonicalDecl()) { 4900 DSAStack->resetPossibleLoopCounter(); 4901 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 4902 MarkDeclarationsReferencedInExpr( 4903 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 4904 Var->getType().getNonLValueExprType(Context), 4905 ForLoc, /*RefersToCapture=*/true)); 4906 } 4907 } 4908 } 4909 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4910 } 4911 } 4912 4913 /// Called on a for stmt to check and extract its iteration space 4914 /// for further processing (such as collapsing). 4915 static bool checkOpenMPIterationSpace( 4916 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4917 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4918 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 4919 Expr *OrderedLoopCountExpr, 4920 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 4921 LoopIterationSpace &ResultIterSpace, 4922 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4923 // OpenMP [2.6, Canonical Loop Form] 4924 // for (init-expr; test-expr; incr-expr) structured-block 4925 auto *For = dyn_cast_or_null<ForStmt>(S); 4926 if (!For) { 4927 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 4928 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4929 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 4930 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4931 if (TotalNestedLoopCount > 1) { 4932 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4933 SemaRef.Diag(DSA.getConstructLoc(), 4934 diag::note_omp_collapse_ordered_expr) 4935 << 2 << CollapseLoopCountExpr->getSourceRange() 4936 << OrderedLoopCountExpr->getSourceRange(); 4937 else if (CollapseLoopCountExpr) 4938 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4939 diag::note_omp_collapse_ordered_expr) 4940 << 0 << CollapseLoopCountExpr->getSourceRange(); 4941 else 4942 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4943 diag::note_omp_collapse_ordered_expr) 4944 << 1 << OrderedLoopCountExpr->getSourceRange(); 4945 } 4946 return true; 4947 } 4948 assert(For->getBody()); 4949 4950 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4951 4952 // Check init. 4953 Stmt *Init = For->getInit(); 4954 if (ISC.checkAndSetInit(Init)) 4955 return true; 4956 4957 bool HasErrors = false; 4958 4959 // Check loop variable's type. 4960 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 4961 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 4962 4963 // OpenMP [2.6, Canonical Loop Form] 4964 // Var is one of the following: 4965 // A variable of signed or unsigned integer type. 4966 // For C++, a variable of a random access iterator type. 4967 // For C, a variable of a pointer type. 4968 QualType VarType = LCDecl->getType().getNonReferenceType(); 4969 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4970 !VarType->isPointerType() && 4971 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4972 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 4973 << SemaRef.getLangOpts().CPlusPlus; 4974 HasErrors = true; 4975 } 4976 4977 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4978 // a Construct 4979 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4980 // parallel for construct is (are) private. 4981 // The loop iteration variable in the associated for-loop of a simd 4982 // construct with just one associated for-loop is linear with a 4983 // constant-linear-step that is the increment of the associated for-loop. 4984 // Exclude loop var from the list of variables with implicitly defined data 4985 // sharing attributes. 4986 VarsWithImplicitDSA.erase(LCDecl); 4987 4988 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4989 // in a Construct, C/C++]. 4990 // The loop iteration variable in the associated for-loop of a simd 4991 // construct with just one associated for-loop may be listed in a linear 4992 // clause with a constant-linear-step that is the increment of the 4993 // associated for-loop. 4994 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4995 // parallel for construct may be listed in a private or lastprivate clause. 4996 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4997 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4998 // declared in the loop and it is predetermined as a private. 4999 OpenMPClauseKind PredeterminedCKind = 5000 isOpenMPSimdDirective(DKind) 5001 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5002 : OMPC_private; 5003 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5004 DVar.CKind != PredeterminedCKind) || 5005 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5006 isOpenMPDistributeDirective(DKind)) && 5007 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5008 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5009 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5010 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5011 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5012 << getOpenMPClauseName(PredeterminedCKind); 5013 if (DVar.RefExpr == nullptr) 5014 DVar.CKind = PredeterminedCKind; 5015 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5016 HasErrors = true; 5017 } else if (LoopDeclRefExpr != nullptr) { 5018 // Make the loop iteration variable private (for worksharing constructs), 5019 // linear (for simd directives with the only one associated loop) or 5020 // lastprivate (for simd directives with several collapsed or ordered 5021 // loops). 5022 if (DVar.CKind == OMPC_unknown) 5023 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5024 } 5025 5026 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5027 5028 // Check test-expr. 5029 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5030 5031 // Check incr-expr. 5032 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5033 } 5034 5035 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5036 return HasErrors; 5037 5038 // Build the loop's iteration space representation. 5039 ResultIterSpace.PreCond = 5040 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5041 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5042 DSA.getCurScope(), 5043 (isOpenMPWorksharingDirective(DKind) || 5044 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5045 Captures); 5046 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5047 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5048 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5049 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5050 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5051 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5052 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5053 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5054 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5055 5056 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5057 ResultIterSpace.NumIterations == nullptr || 5058 ResultIterSpace.CounterVar == nullptr || 5059 ResultIterSpace.PrivateCounterVar == nullptr || 5060 ResultIterSpace.CounterInit == nullptr || 5061 ResultIterSpace.CounterStep == nullptr); 5062 if (!HasErrors && DSA.isOrderedRegion()) { 5063 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5064 if (CurrentNestedLoopCount < 5065 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5066 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5067 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5068 DSA.getOrderedRegionParam().second->setLoopCounter( 5069 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5070 } 5071 } 5072 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5073 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5074 // Erroneous case - clause has some problems. 5075 continue; 5076 } 5077 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5078 Pair.second.size() <= CurrentNestedLoopCount) { 5079 // Erroneous case - clause has some problems. 5080 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5081 continue; 5082 } 5083 Expr *CntValue; 5084 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5085 CntValue = ISC.buildOrderedLoopData( 5086 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5087 Pair.first->getDependencyLoc()); 5088 else 5089 CntValue = ISC.buildOrderedLoopData( 5090 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5091 Pair.first->getDependencyLoc(), 5092 Pair.second[CurrentNestedLoopCount].first, 5093 Pair.second[CurrentNestedLoopCount].second); 5094 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5095 } 5096 } 5097 5098 return HasErrors; 5099 } 5100 5101 /// Build 'VarRef = Start. 5102 static ExprResult 5103 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5104 ExprResult Start, 5105 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5106 // Build 'VarRef = Start. 5107 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5108 if (!NewStart.isUsable()) 5109 return ExprError(); 5110 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5111 VarRef.get()->getType())) { 5112 NewStart = SemaRef.PerformImplicitConversion( 5113 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5114 /*AllowExplicit=*/true); 5115 if (!NewStart.isUsable()) 5116 return ExprError(); 5117 } 5118 5119 ExprResult Init = 5120 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5121 return Init; 5122 } 5123 5124 /// Build 'VarRef = Start + Iter * Step'. 5125 static ExprResult buildCounterUpdate( 5126 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5127 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5128 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5129 // Add parentheses (for debugging purposes only). 5130 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5131 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5132 !Step.isUsable()) 5133 return ExprError(); 5134 5135 ExprResult NewStep = Step; 5136 if (Captures) 5137 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5138 if (NewStep.isInvalid()) 5139 return ExprError(); 5140 ExprResult Update = 5141 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5142 if (!Update.isUsable()) 5143 return ExprError(); 5144 5145 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5146 // 'VarRef = Start (+|-) Iter * Step'. 5147 ExprResult NewStart = Start; 5148 if (Captures) 5149 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5150 if (NewStart.isInvalid()) 5151 return ExprError(); 5152 5153 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5154 ExprResult SavedUpdate = Update; 5155 ExprResult UpdateVal; 5156 if (VarRef.get()->getType()->isOverloadableType() || 5157 NewStart.get()->getType()->isOverloadableType() || 5158 Update.get()->getType()->isOverloadableType()) { 5159 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5160 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5161 Update = 5162 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5163 if (Update.isUsable()) { 5164 UpdateVal = 5165 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5166 VarRef.get(), SavedUpdate.get()); 5167 if (UpdateVal.isUsable()) { 5168 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5169 UpdateVal.get()); 5170 } 5171 } 5172 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5173 } 5174 5175 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5176 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5177 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5178 NewStart.get(), SavedUpdate.get()); 5179 if (!Update.isUsable()) 5180 return ExprError(); 5181 5182 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5183 VarRef.get()->getType())) { 5184 Update = SemaRef.PerformImplicitConversion( 5185 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5186 if (!Update.isUsable()) 5187 return ExprError(); 5188 } 5189 5190 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5191 } 5192 return Update; 5193 } 5194 5195 /// Convert integer expression \a E to make it have at least \a Bits 5196 /// bits. 5197 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5198 if (E == nullptr) 5199 return ExprError(); 5200 ASTContext &C = SemaRef.Context; 5201 QualType OldType = E->getType(); 5202 unsigned HasBits = C.getTypeSize(OldType); 5203 if (HasBits >= Bits) 5204 return ExprResult(E); 5205 // OK to convert to signed, because new type has more bits than old. 5206 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5207 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5208 true); 5209 } 5210 5211 /// Check if the given expression \a E is a constant integer that fits 5212 /// into \a Bits bits. 5213 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5214 if (E == nullptr) 5215 return false; 5216 llvm::APSInt Result; 5217 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5218 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5219 return false; 5220 } 5221 5222 /// Build preinits statement for the given declarations. 5223 static Stmt *buildPreInits(ASTContext &Context, 5224 MutableArrayRef<Decl *> PreInits) { 5225 if (!PreInits.empty()) { 5226 return new (Context) DeclStmt( 5227 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5228 SourceLocation(), SourceLocation()); 5229 } 5230 return nullptr; 5231 } 5232 5233 /// Build preinits statement for the given declarations. 5234 static Stmt * 5235 buildPreInits(ASTContext &Context, 5236 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5237 if (!Captures.empty()) { 5238 SmallVector<Decl *, 16> PreInits; 5239 for (const auto &Pair : Captures) 5240 PreInits.push_back(Pair.second->getDecl()); 5241 return buildPreInits(Context, PreInits); 5242 } 5243 return nullptr; 5244 } 5245 5246 /// Build postupdate expression for the given list of postupdates expressions. 5247 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5248 Expr *PostUpdate = nullptr; 5249 if (!PostUpdates.empty()) { 5250 for (Expr *E : PostUpdates) { 5251 Expr *ConvE = S.BuildCStyleCastExpr( 5252 E->getExprLoc(), 5253 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5254 E->getExprLoc(), E) 5255 .get(); 5256 PostUpdate = PostUpdate 5257 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5258 PostUpdate, ConvE) 5259 .get() 5260 : ConvE; 5261 } 5262 } 5263 return PostUpdate; 5264 } 5265 5266 /// Called on a for stmt to check itself and nested loops (if any). 5267 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5268 /// number of collapsed loops otherwise. 5269 static unsigned 5270 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5271 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5272 DSAStackTy &DSA, 5273 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5274 OMPLoopDirective::HelperExprs &Built) { 5275 unsigned NestedLoopCount = 1; 5276 if (CollapseLoopCountExpr) { 5277 // Found 'collapse' clause - calculate collapse number. 5278 Expr::EvalResult Result; 5279 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 5280 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5281 } 5282 unsigned OrderedLoopCount = 1; 5283 if (OrderedLoopCountExpr) { 5284 // Found 'ordered' clause - calculate collapse number. 5285 Expr::EvalResult EVResult; 5286 if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { 5287 llvm::APSInt Result = EVResult.Val.getInt(); 5288 if (Result.getLimitedValue() < NestedLoopCount) { 5289 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5290 diag::err_omp_wrong_ordered_loop_count) 5291 << OrderedLoopCountExpr->getSourceRange(); 5292 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5293 diag::note_collapse_loop_count) 5294 << CollapseLoopCountExpr->getSourceRange(); 5295 } 5296 OrderedLoopCount = Result.getLimitedValue(); 5297 } 5298 } 5299 // This is helper routine for loop directives (e.g., 'for', 'simd', 5300 // 'for simd', etc.). 5301 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 5302 SmallVector<LoopIterationSpace, 4> IterSpaces( 5303 std::max(OrderedLoopCount, NestedLoopCount)); 5304 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 5305 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5306 if (checkOpenMPIterationSpace( 5307 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5308 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5309 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5310 Captures)) 5311 return 0; 5312 // Move on to the next nested for loop, or to the loop body. 5313 // OpenMP [2.8.1, simd construct, Restrictions] 5314 // All loops associated with the construct must be perfectly nested; that 5315 // is, there must be no intervening code nor any OpenMP directive between 5316 // any two loops. 5317 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5318 } 5319 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 5320 if (checkOpenMPIterationSpace( 5321 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5322 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5323 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5324 Captures)) 5325 return 0; 5326 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 5327 // Handle initialization of captured loop iterator variables. 5328 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 5329 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 5330 Captures[DRE] = DRE; 5331 } 5332 } 5333 // Move on to the next nested for loop, or to the loop body. 5334 // OpenMP [2.8.1, simd construct, Restrictions] 5335 // All loops associated with the construct must be perfectly nested; that 5336 // is, there must be no intervening code nor any OpenMP directive between 5337 // any two loops. 5338 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5339 } 5340 5341 Built.clear(/* size */ NestedLoopCount); 5342 5343 if (SemaRef.CurContext->isDependentContext()) 5344 return NestedLoopCount; 5345 5346 // An example of what is generated for the following code: 5347 // 5348 // #pragma omp simd collapse(2) ordered(2) 5349 // for (i = 0; i < NI; ++i) 5350 // for (k = 0; k < NK; ++k) 5351 // for (j = J0; j < NJ; j+=2) { 5352 // <loop body> 5353 // } 5354 // 5355 // We generate the code below. 5356 // Note: the loop body may be outlined in CodeGen. 5357 // Note: some counters may be C++ classes, operator- is used to find number of 5358 // iterations and operator+= to calculate counter value. 5359 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 5360 // or i64 is currently supported). 5361 // 5362 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 5363 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 5364 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 5365 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 5366 // // similar updates for vars in clauses (e.g. 'linear') 5367 // <loop body (using local i and j)> 5368 // } 5369 // i = NI; // assign final values of counters 5370 // j = NJ; 5371 // 5372 5373 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 5374 // the iteration counts of the collapsed for loops. 5375 // Precondition tests if there is at least one iteration (all conditions are 5376 // true). 5377 auto PreCond = ExprResult(IterSpaces[0].PreCond); 5378 Expr *N0 = IterSpaces[0].NumIterations; 5379 ExprResult LastIteration32 = 5380 widenIterationCount(/*Bits=*/32, 5381 SemaRef 5382 .PerformImplicitConversion( 5383 N0->IgnoreImpCasts(), N0->getType(), 5384 Sema::AA_Converting, /*AllowExplicit=*/true) 5385 .get(), 5386 SemaRef); 5387 ExprResult LastIteration64 = widenIterationCount( 5388 /*Bits=*/64, 5389 SemaRef 5390 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 5391 Sema::AA_Converting, 5392 /*AllowExplicit=*/true) 5393 .get(), 5394 SemaRef); 5395 5396 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 5397 return NestedLoopCount; 5398 5399 ASTContext &C = SemaRef.Context; 5400 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 5401 5402 Scope *CurScope = DSA.getCurScope(); 5403 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 5404 if (PreCond.isUsable()) { 5405 PreCond = 5406 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 5407 PreCond.get(), IterSpaces[Cnt].PreCond); 5408 } 5409 Expr *N = IterSpaces[Cnt].NumIterations; 5410 SourceLocation Loc = N->getExprLoc(); 5411 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 5412 if (LastIteration32.isUsable()) 5413 LastIteration32 = SemaRef.BuildBinOp( 5414 CurScope, Loc, BO_Mul, LastIteration32.get(), 5415 SemaRef 5416 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5417 Sema::AA_Converting, 5418 /*AllowExplicit=*/true) 5419 .get()); 5420 if (LastIteration64.isUsable()) 5421 LastIteration64 = SemaRef.BuildBinOp( 5422 CurScope, Loc, BO_Mul, LastIteration64.get(), 5423 SemaRef 5424 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5425 Sema::AA_Converting, 5426 /*AllowExplicit=*/true) 5427 .get()); 5428 } 5429 5430 // Choose either the 32-bit or 64-bit version. 5431 ExprResult LastIteration = LastIteration64; 5432 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 5433 (LastIteration32.isUsable() && 5434 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 5435 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 5436 fitsInto( 5437 /*Bits=*/32, 5438 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 5439 LastIteration64.get(), SemaRef)))) 5440 LastIteration = LastIteration32; 5441 QualType VType = LastIteration.get()->getType(); 5442 QualType RealVType = VType; 5443 QualType StrideVType = VType; 5444 if (isOpenMPTaskLoopDirective(DKind)) { 5445 VType = 5446 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 5447 StrideVType = 5448 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 5449 } 5450 5451 if (!LastIteration.isUsable()) 5452 return 0; 5453 5454 // Save the number of iterations. 5455 ExprResult NumIterations = LastIteration; 5456 { 5457 LastIteration = SemaRef.BuildBinOp( 5458 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 5459 LastIteration.get(), 5460 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5461 if (!LastIteration.isUsable()) 5462 return 0; 5463 } 5464 5465 // Calculate the last iteration number beforehand instead of doing this on 5466 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5467 llvm::APSInt Result; 5468 bool IsConstant = 5469 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5470 ExprResult CalcLastIteration; 5471 if (!IsConstant) { 5472 ExprResult SaveRef = 5473 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5474 LastIteration = SaveRef; 5475 5476 // Prepare SaveRef + 1. 5477 NumIterations = SemaRef.BuildBinOp( 5478 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 5479 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5480 if (!NumIterations.isUsable()) 5481 return 0; 5482 } 5483 5484 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5485 5486 // Build variables passed into runtime, necessary for worksharing directives. 5487 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 5488 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5489 isOpenMPDistributeDirective(DKind)) { 5490 // Lower bound variable, initialized with zero. 5491 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5492 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5493 SemaRef.AddInitializerToDecl(LBDecl, 5494 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5495 /*DirectInit*/ false); 5496 5497 // Upper bound variable, initialized with last iteration number. 5498 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 5499 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 5500 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 5501 /*DirectInit*/ false); 5502 5503 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 5504 // This will be used to implement clause 'lastprivate'. 5505 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 5506 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 5507 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 5508 SemaRef.AddInitializerToDecl(ILDecl, 5509 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5510 /*DirectInit*/ false); 5511 5512 // Stride variable returned by runtime (we initialize it to 1 by default). 5513 VarDecl *STDecl = 5514 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 5515 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 5516 SemaRef.AddInitializerToDecl(STDecl, 5517 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 5518 /*DirectInit*/ false); 5519 5520 // Build expression: UB = min(UB, LastIteration) 5521 // It is necessary for CodeGen of directives with static scheduling. 5522 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 5523 UB.get(), LastIteration.get()); 5524 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5525 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 5526 LastIteration.get(), UB.get()); 5527 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 5528 CondOp.get()); 5529 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 5530 5531 // If we have a combined directive that combines 'distribute', 'for' or 5532 // 'simd' we need to be able to access the bounds of the schedule of the 5533 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 5534 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 5535 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5536 // Lower bound variable, initialized with zero. 5537 VarDecl *CombLBDecl = 5538 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 5539 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 5540 SemaRef.AddInitializerToDecl( 5541 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5542 /*DirectInit*/ false); 5543 5544 // Upper bound variable, initialized with last iteration number. 5545 VarDecl *CombUBDecl = 5546 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 5547 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 5548 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 5549 /*DirectInit*/ false); 5550 5551 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 5552 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 5553 ExprResult CombCondOp = 5554 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 5555 LastIteration.get(), CombUB.get()); 5556 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 5557 CombCondOp.get()); 5558 CombEUB = 5559 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 5560 5561 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 5562 // We expect to have at least 2 more parameters than the 'parallel' 5563 // directive does - the lower and upper bounds of the previous schedule. 5564 assert(CD->getNumParams() >= 4 && 5565 "Unexpected number of parameters in loop combined directive"); 5566 5567 // Set the proper type for the bounds given what we learned from the 5568 // enclosed loops. 5569 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 5570 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 5571 5572 // Previous lower and upper bounds are obtained from the region 5573 // parameters. 5574 PrevLB = 5575 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 5576 PrevUB = 5577 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 5578 } 5579 } 5580 5581 // Build the iteration variable and its initialization before loop. 5582 ExprResult IV; 5583 ExprResult Init, CombInit; 5584 { 5585 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 5586 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 5587 Expr *RHS = 5588 (isOpenMPWorksharingDirective(DKind) || 5589 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5590 ? LB.get() 5591 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5592 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 5593 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 5594 5595 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5596 Expr *CombRHS = 5597 (isOpenMPWorksharingDirective(DKind) || 5598 isOpenMPTaskLoopDirective(DKind) || 5599 isOpenMPDistributeDirective(DKind)) 5600 ? CombLB.get() 5601 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5602 CombInit = 5603 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 5604 CombInit = 5605 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 5606 } 5607 } 5608 5609 bool UseStrictCompare = 5610 RealVType->hasUnsignedIntegerRepresentation() && 5611 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 5612 return LIS.IsStrictCompare; 5613 }); 5614 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 5615 // unsigned IV)) for worksharing loops. 5616 SourceLocation CondLoc = AStmt->getBeginLoc(); 5617 Expr *BoundUB = UB.get(); 5618 if (UseStrictCompare) { 5619 BoundUB = 5620 SemaRef 5621 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 5622 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5623 .get(); 5624 BoundUB = 5625 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 5626 } 5627 ExprResult Cond = 5628 (isOpenMPWorksharingDirective(DKind) || 5629 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5630 ? SemaRef.BuildBinOp(CurScope, CondLoc, 5631 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 5632 BoundUB) 5633 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5634 NumIterations.get()); 5635 ExprResult CombDistCond; 5636 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5637 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5638 NumIterations.get()); 5639 } 5640 5641 ExprResult CombCond; 5642 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5643 Expr *BoundCombUB = CombUB.get(); 5644 if (UseStrictCompare) { 5645 BoundCombUB = 5646 SemaRef 5647 .BuildBinOp( 5648 CurScope, CondLoc, BO_Add, BoundCombUB, 5649 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5650 .get(); 5651 BoundCombUB = 5652 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 5653 .get(); 5654 } 5655 CombCond = 5656 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 5657 IV.get(), BoundCombUB); 5658 } 5659 // Loop increment (IV = IV + 1) 5660 SourceLocation IncLoc = AStmt->getBeginLoc(); 5661 ExprResult Inc = 5662 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 5663 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 5664 if (!Inc.isUsable()) 5665 return 0; 5666 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 5667 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 5668 if (!Inc.isUsable()) 5669 return 0; 5670 5671 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 5672 // Used for directives with static scheduling. 5673 // In combined construct, add combined version that use CombLB and CombUB 5674 // base variables for the update 5675 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 5676 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5677 isOpenMPDistributeDirective(DKind)) { 5678 // LB + ST 5679 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 5680 if (!NextLB.isUsable()) 5681 return 0; 5682 // LB = LB + ST 5683 NextLB = 5684 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 5685 NextLB = 5686 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 5687 if (!NextLB.isUsable()) 5688 return 0; 5689 // UB + ST 5690 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 5691 if (!NextUB.isUsable()) 5692 return 0; 5693 // UB = UB + ST 5694 NextUB = 5695 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 5696 NextUB = 5697 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 5698 if (!NextUB.isUsable()) 5699 return 0; 5700 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5701 CombNextLB = 5702 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 5703 if (!NextLB.isUsable()) 5704 return 0; 5705 // LB = LB + ST 5706 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 5707 CombNextLB.get()); 5708 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 5709 /*DiscardedValue*/ false); 5710 if (!CombNextLB.isUsable()) 5711 return 0; 5712 // UB + ST 5713 CombNextUB = 5714 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 5715 if (!CombNextUB.isUsable()) 5716 return 0; 5717 // UB = UB + ST 5718 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 5719 CombNextUB.get()); 5720 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 5721 /*DiscardedValue*/ false); 5722 if (!CombNextUB.isUsable()) 5723 return 0; 5724 } 5725 } 5726 5727 // Create increment expression for distribute loop when combined in a same 5728 // directive with for as IV = IV + ST; ensure upper bound expression based 5729 // on PrevUB instead of NumIterations - used to implement 'for' when found 5730 // in combination with 'distribute', like in 'distribute parallel for' 5731 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 5732 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 5733 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5734 DistCond = SemaRef.BuildBinOp( 5735 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 5736 assert(DistCond.isUsable() && "distribute cond expr was not built"); 5737 5738 DistInc = 5739 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 5740 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5741 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 5742 DistInc.get()); 5743 DistInc = 5744 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 5745 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5746 5747 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 5748 // construct 5749 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 5750 ExprResult IsUBGreater = 5751 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 5752 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5753 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 5754 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 5755 CondOp.get()); 5756 PrevEUB = 5757 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 5758 5759 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 5760 // parallel for is in combination with a distribute directive with 5761 // schedule(static, 1) 5762 Expr *BoundPrevUB = PrevUB.get(); 5763 if (UseStrictCompare) { 5764 BoundPrevUB = 5765 SemaRef 5766 .BuildBinOp( 5767 CurScope, CondLoc, BO_Add, BoundPrevUB, 5768 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5769 .get(); 5770 BoundPrevUB = 5771 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 5772 .get(); 5773 } 5774 ParForInDistCond = 5775 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 5776 IV.get(), BoundPrevUB); 5777 } 5778 5779 // Build updates and final values of the loop counters. 5780 bool HasErrors = false; 5781 Built.Counters.resize(NestedLoopCount); 5782 Built.Inits.resize(NestedLoopCount); 5783 Built.Updates.resize(NestedLoopCount); 5784 Built.Finals.resize(NestedLoopCount); 5785 { 5786 // We implement the following algorithm for obtaining the 5787 // original loop iteration variable values based on the 5788 // value of the collapsed loop iteration variable IV. 5789 // 5790 // Let n+1 be the number of collapsed loops in the nest. 5791 // Iteration variables (I0, I1, .... In) 5792 // Iteration counts (N0, N1, ... Nn) 5793 // 5794 // Acc = IV; 5795 // 5796 // To compute Ik for loop k, 0 <= k <= n, generate: 5797 // Prod = N(k+1) * N(k+2) * ... * Nn; 5798 // Ik = Acc / Prod; 5799 // Acc -= Ik * Prod; 5800 // 5801 ExprResult Acc = IV; 5802 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5803 LoopIterationSpace &IS = IterSpaces[Cnt]; 5804 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 5805 ExprResult Iter; 5806 5807 // Compute prod 5808 ExprResult Prod = 5809 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 5810 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 5811 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 5812 IterSpaces[K].NumIterations); 5813 5814 // Iter = Acc / Prod 5815 // If there is at least one more inner loop to avoid 5816 // multiplication by 1. 5817 if (Cnt + 1 < NestedLoopCount) 5818 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 5819 Acc.get(), Prod.get()); 5820 else 5821 Iter = Acc; 5822 if (!Iter.isUsable()) { 5823 HasErrors = true; 5824 break; 5825 } 5826 5827 // Update Acc: 5828 // Acc -= Iter * Prod 5829 // Check if there is at least one more inner loop to avoid 5830 // multiplication by 1. 5831 if (Cnt + 1 < NestedLoopCount) 5832 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 5833 Iter.get(), Prod.get()); 5834 else 5835 Prod = Iter; 5836 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 5837 Acc.get(), Prod.get()); 5838 5839 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 5840 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 5841 DeclRefExpr *CounterVar = buildDeclRefExpr( 5842 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 5843 /*RefersToCapture=*/true); 5844 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 5845 IS.CounterInit, Captures); 5846 if (!Init.isUsable()) { 5847 HasErrors = true; 5848 break; 5849 } 5850 ExprResult Update = buildCounterUpdate( 5851 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 5852 IS.CounterStep, IS.Subtract, &Captures); 5853 if (!Update.isUsable()) { 5854 HasErrors = true; 5855 break; 5856 } 5857 5858 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 5859 ExprResult Final = buildCounterUpdate( 5860 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 5861 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 5862 if (!Final.isUsable()) { 5863 HasErrors = true; 5864 break; 5865 } 5866 5867 if (!Update.isUsable() || !Final.isUsable()) { 5868 HasErrors = true; 5869 break; 5870 } 5871 // Save results 5872 Built.Counters[Cnt] = IS.CounterVar; 5873 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 5874 Built.Inits[Cnt] = Init.get(); 5875 Built.Updates[Cnt] = Update.get(); 5876 Built.Finals[Cnt] = Final.get(); 5877 } 5878 } 5879 5880 if (HasErrors) 5881 return 0; 5882 5883 // Save results 5884 Built.IterationVarRef = IV.get(); 5885 Built.LastIteration = LastIteration.get(); 5886 Built.NumIterations = NumIterations.get(); 5887 Built.CalcLastIteration = SemaRef 5888 .ActOnFinishFullExpr(CalcLastIteration.get(), 5889 /*DiscardedValue*/ false) 5890 .get(); 5891 Built.PreCond = PreCond.get(); 5892 Built.PreInits = buildPreInits(C, Captures); 5893 Built.Cond = Cond.get(); 5894 Built.Init = Init.get(); 5895 Built.Inc = Inc.get(); 5896 Built.LB = LB.get(); 5897 Built.UB = UB.get(); 5898 Built.IL = IL.get(); 5899 Built.ST = ST.get(); 5900 Built.EUB = EUB.get(); 5901 Built.NLB = NextLB.get(); 5902 Built.NUB = NextUB.get(); 5903 Built.PrevLB = PrevLB.get(); 5904 Built.PrevUB = PrevUB.get(); 5905 Built.DistInc = DistInc.get(); 5906 Built.PrevEUB = PrevEUB.get(); 5907 Built.DistCombinedFields.LB = CombLB.get(); 5908 Built.DistCombinedFields.UB = CombUB.get(); 5909 Built.DistCombinedFields.EUB = CombEUB.get(); 5910 Built.DistCombinedFields.Init = CombInit.get(); 5911 Built.DistCombinedFields.Cond = CombCond.get(); 5912 Built.DistCombinedFields.NLB = CombNextLB.get(); 5913 Built.DistCombinedFields.NUB = CombNextUB.get(); 5914 Built.DistCombinedFields.DistCond = CombDistCond.get(); 5915 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 5916 5917 return NestedLoopCount; 5918 } 5919 5920 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 5921 auto CollapseClauses = 5922 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 5923 if (CollapseClauses.begin() != CollapseClauses.end()) 5924 return (*CollapseClauses.begin())->getNumForLoops(); 5925 return nullptr; 5926 } 5927 5928 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 5929 auto OrderedClauses = 5930 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 5931 if (OrderedClauses.begin() != OrderedClauses.end()) 5932 return (*OrderedClauses.begin())->getNumForLoops(); 5933 return nullptr; 5934 } 5935 5936 static bool checkSimdlenSafelenSpecified(Sema &S, 5937 const ArrayRef<OMPClause *> Clauses) { 5938 const OMPSafelenClause *Safelen = nullptr; 5939 const OMPSimdlenClause *Simdlen = nullptr; 5940 5941 for (const OMPClause *Clause : Clauses) { 5942 if (Clause->getClauseKind() == OMPC_safelen) 5943 Safelen = cast<OMPSafelenClause>(Clause); 5944 else if (Clause->getClauseKind() == OMPC_simdlen) 5945 Simdlen = cast<OMPSimdlenClause>(Clause); 5946 if (Safelen && Simdlen) 5947 break; 5948 } 5949 5950 if (Simdlen && Safelen) { 5951 const Expr *SimdlenLength = Simdlen->getSimdlen(); 5952 const Expr *SafelenLength = Safelen->getSafelen(); 5953 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 5954 SimdlenLength->isInstantiationDependent() || 5955 SimdlenLength->containsUnexpandedParameterPack()) 5956 return false; 5957 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 5958 SafelenLength->isInstantiationDependent() || 5959 SafelenLength->containsUnexpandedParameterPack()) 5960 return false; 5961 Expr::EvalResult SimdlenResult, SafelenResult; 5962 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 5963 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 5964 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 5965 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 5966 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 5967 // If both simdlen and safelen clauses are specified, the value of the 5968 // simdlen parameter must be less than or equal to the value of the safelen 5969 // parameter. 5970 if (SimdlenRes > SafelenRes) { 5971 S.Diag(SimdlenLength->getExprLoc(), 5972 diag::err_omp_wrong_simdlen_safelen_values) 5973 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 5974 return true; 5975 } 5976 } 5977 return false; 5978 } 5979 5980 StmtResult 5981 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 5982 SourceLocation StartLoc, SourceLocation EndLoc, 5983 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5984 if (!AStmt) 5985 return StmtError(); 5986 5987 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5988 OMPLoopDirective::HelperExprs B; 5989 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5990 // define the nested loops number. 5991 unsigned NestedLoopCount = checkOpenMPLoop( 5992 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5993 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5994 if (NestedLoopCount == 0) 5995 return StmtError(); 5996 5997 assert((CurContext->isDependentContext() || B.builtAll()) && 5998 "omp simd loop exprs were not built"); 5999 6000 if (!CurContext->isDependentContext()) { 6001 // Finalize the clauses that need pre-built expressions for CodeGen. 6002 for (OMPClause *C : Clauses) { 6003 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6004 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6005 B.NumIterations, *this, CurScope, 6006 DSAStack)) 6007 return StmtError(); 6008 } 6009 } 6010 6011 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6012 return StmtError(); 6013 6014 setFunctionHasBranchProtectedScope(); 6015 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6016 Clauses, AStmt, B); 6017 } 6018 6019 StmtResult 6020 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6021 SourceLocation StartLoc, SourceLocation EndLoc, 6022 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6023 if (!AStmt) 6024 return StmtError(); 6025 6026 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6027 OMPLoopDirective::HelperExprs B; 6028 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6029 // define the nested loops number. 6030 unsigned NestedLoopCount = checkOpenMPLoop( 6031 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6032 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6033 if (NestedLoopCount == 0) 6034 return StmtError(); 6035 6036 assert((CurContext->isDependentContext() || B.builtAll()) && 6037 "omp for loop exprs were not built"); 6038 6039 if (!CurContext->isDependentContext()) { 6040 // Finalize the clauses that need pre-built expressions for CodeGen. 6041 for (OMPClause *C : Clauses) { 6042 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6043 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6044 B.NumIterations, *this, CurScope, 6045 DSAStack)) 6046 return StmtError(); 6047 } 6048 } 6049 6050 setFunctionHasBranchProtectedScope(); 6051 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6052 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6053 } 6054 6055 StmtResult Sema::ActOnOpenMPForSimdDirective( 6056 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6057 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6058 if (!AStmt) 6059 return StmtError(); 6060 6061 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6062 OMPLoopDirective::HelperExprs B; 6063 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6064 // define the nested loops number. 6065 unsigned NestedLoopCount = 6066 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6067 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6068 VarsWithImplicitDSA, B); 6069 if (NestedLoopCount == 0) 6070 return StmtError(); 6071 6072 assert((CurContext->isDependentContext() || B.builtAll()) && 6073 "omp for simd loop exprs were not built"); 6074 6075 if (!CurContext->isDependentContext()) { 6076 // Finalize the clauses that need pre-built expressions for CodeGen. 6077 for (OMPClause *C : Clauses) { 6078 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6079 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6080 B.NumIterations, *this, CurScope, 6081 DSAStack)) 6082 return StmtError(); 6083 } 6084 } 6085 6086 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6087 return StmtError(); 6088 6089 setFunctionHasBranchProtectedScope(); 6090 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6091 Clauses, AStmt, B); 6092 } 6093 6094 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6095 Stmt *AStmt, 6096 SourceLocation StartLoc, 6097 SourceLocation EndLoc) { 6098 if (!AStmt) 6099 return StmtError(); 6100 6101 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6102 auto BaseStmt = AStmt; 6103 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6104 BaseStmt = CS->getCapturedStmt(); 6105 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6106 auto S = C->children(); 6107 if (S.begin() == S.end()) 6108 return StmtError(); 6109 // All associated statements must be '#pragma omp section' except for 6110 // the first one. 6111 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6112 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6113 if (SectionStmt) 6114 Diag(SectionStmt->getBeginLoc(), 6115 diag::err_omp_sections_substmt_not_section); 6116 return StmtError(); 6117 } 6118 cast<OMPSectionDirective>(SectionStmt) 6119 ->setHasCancel(DSAStack->isCancelRegion()); 6120 } 6121 } else { 6122 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6123 return StmtError(); 6124 } 6125 6126 setFunctionHasBranchProtectedScope(); 6127 6128 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6129 DSAStack->isCancelRegion()); 6130 } 6131 6132 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6133 SourceLocation StartLoc, 6134 SourceLocation EndLoc) { 6135 if (!AStmt) 6136 return StmtError(); 6137 6138 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6139 6140 setFunctionHasBranchProtectedScope(); 6141 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6142 6143 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6144 DSAStack->isCancelRegion()); 6145 } 6146 6147 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6148 Stmt *AStmt, 6149 SourceLocation StartLoc, 6150 SourceLocation EndLoc) { 6151 if (!AStmt) 6152 return StmtError(); 6153 6154 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6155 6156 setFunctionHasBranchProtectedScope(); 6157 6158 // OpenMP [2.7.3, single Construct, Restrictions] 6159 // The copyprivate clause must not be used with the nowait clause. 6160 const OMPClause *Nowait = nullptr; 6161 const OMPClause *Copyprivate = nullptr; 6162 for (const OMPClause *Clause : Clauses) { 6163 if (Clause->getClauseKind() == OMPC_nowait) 6164 Nowait = Clause; 6165 else if (Clause->getClauseKind() == OMPC_copyprivate) 6166 Copyprivate = Clause; 6167 if (Copyprivate && Nowait) { 6168 Diag(Copyprivate->getBeginLoc(), 6169 diag::err_omp_single_copyprivate_with_nowait); 6170 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6171 return StmtError(); 6172 } 6173 } 6174 6175 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6176 } 6177 6178 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6179 SourceLocation StartLoc, 6180 SourceLocation EndLoc) { 6181 if (!AStmt) 6182 return StmtError(); 6183 6184 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6185 6186 setFunctionHasBranchProtectedScope(); 6187 6188 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6189 } 6190 6191 StmtResult Sema::ActOnOpenMPCriticalDirective( 6192 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6193 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6194 if (!AStmt) 6195 return StmtError(); 6196 6197 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6198 6199 bool ErrorFound = false; 6200 llvm::APSInt Hint; 6201 SourceLocation HintLoc; 6202 bool DependentHint = false; 6203 for (const OMPClause *C : Clauses) { 6204 if (C->getClauseKind() == OMPC_hint) { 6205 if (!DirName.getName()) { 6206 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6207 ErrorFound = true; 6208 } 6209 Expr *E = cast<OMPHintClause>(C)->getHint(); 6210 if (E->isTypeDependent() || E->isValueDependent() || 6211 E->isInstantiationDependent()) { 6212 DependentHint = true; 6213 } else { 6214 Hint = E->EvaluateKnownConstInt(Context); 6215 HintLoc = C->getBeginLoc(); 6216 } 6217 } 6218 } 6219 if (ErrorFound) 6220 return StmtError(); 6221 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6222 if (Pair.first && DirName.getName() && !DependentHint) { 6223 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6224 Diag(StartLoc, diag::err_omp_critical_with_hint); 6225 if (HintLoc.isValid()) 6226 Diag(HintLoc, diag::note_omp_critical_hint_here) 6227 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6228 else 6229 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6230 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6231 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6232 << 1 6233 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6234 /*Radix=*/10, /*Signed=*/false); 6235 } else { 6236 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6237 } 6238 } 6239 } 6240 6241 setFunctionHasBranchProtectedScope(); 6242 6243 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6244 Clauses, AStmt); 6245 if (!Pair.first && DirName.getName() && !DependentHint) 6246 DSAStack->addCriticalWithHint(Dir, Hint); 6247 return Dir; 6248 } 6249 6250 StmtResult Sema::ActOnOpenMPParallelForDirective( 6251 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6252 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6253 if (!AStmt) 6254 return StmtError(); 6255 6256 auto *CS = cast<CapturedStmt>(AStmt); 6257 // 1.2.2 OpenMP Language Terminology 6258 // Structured block - An executable statement with a single entry at the 6259 // top and a single exit at the bottom. 6260 // The point of exit cannot be a branch out of the structured block. 6261 // longjmp() and throw() must not violate the entry/exit criteria. 6262 CS->getCapturedDecl()->setNothrow(); 6263 6264 OMPLoopDirective::HelperExprs B; 6265 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6266 // define the nested loops number. 6267 unsigned NestedLoopCount = 6268 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6269 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6270 VarsWithImplicitDSA, B); 6271 if (NestedLoopCount == 0) 6272 return StmtError(); 6273 6274 assert((CurContext->isDependentContext() || B.builtAll()) && 6275 "omp parallel for loop exprs were not built"); 6276 6277 if (!CurContext->isDependentContext()) { 6278 // Finalize the clauses that need pre-built expressions for CodeGen. 6279 for (OMPClause *C : Clauses) { 6280 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6281 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6282 B.NumIterations, *this, CurScope, 6283 DSAStack)) 6284 return StmtError(); 6285 } 6286 } 6287 6288 setFunctionHasBranchProtectedScope(); 6289 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6290 NestedLoopCount, Clauses, AStmt, B, 6291 DSAStack->isCancelRegion()); 6292 } 6293 6294 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6295 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6296 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6297 if (!AStmt) 6298 return StmtError(); 6299 6300 auto *CS = cast<CapturedStmt>(AStmt); 6301 // 1.2.2 OpenMP Language Terminology 6302 // Structured block - An executable statement with a single entry at the 6303 // top and a single exit at the bottom. 6304 // The point of exit cannot be a branch out of the structured block. 6305 // longjmp() and throw() must not violate the entry/exit criteria. 6306 CS->getCapturedDecl()->setNothrow(); 6307 6308 OMPLoopDirective::HelperExprs B; 6309 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6310 // define the nested loops number. 6311 unsigned NestedLoopCount = 6312 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 6313 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6314 VarsWithImplicitDSA, B); 6315 if (NestedLoopCount == 0) 6316 return StmtError(); 6317 6318 if (!CurContext->isDependentContext()) { 6319 // Finalize the clauses that need pre-built expressions for CodeGen. 6320 for (OMPClause *C : Clauses) { 6321 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6322 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6323 B.NumIterations, *this, CurScope, 6324 DSAStack)) 6325 return StmtError(); 6326 } 6327 } 6328 6329 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6330 return StmtError(); 6331 6332 setFunctionHasBranchProtectedScope(); 6333 return OMPParallelForSimdDirective::Create( 6334 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6335 } 6336 6337 StmtResult 6338 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 6339 Stmt *AStmt, SourceLocation StartLoc, 6340 SourceLocation EndLoc) { 6341 if (!AStmt) 6342 return StmtError(); 6343 6344 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6345 auto BaseStmt = AStmt; 6346 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6347 BaseStmt = CS->getCapturedStmt(); 6348 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6349 auto S = C->children(); 6350 if (S.begin() == S.end()) 6351 return StmtError(); 6352 // All associated statements must be '#pragma omp section' except for 6353 // the first one. 6354 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6355 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6356 if (SectionStmt) 6357 Diag(SectionStmt->getBeginLoc(), 6358 diag::err_omp_parallel_sections_substmt_not_section); 6359 return StmtError(); 6360 } 6361 cast<OMPSectionDirective>(SectionStmt) 6362 ->setHasCancel(DSAStack->isCancelRegion()); 6363 } 6364 } else { 6365 Diag(AStmt->getBeginLoc(), 6366 diag::err_omp_parallel_sections_not_compound_stmt); 6367 return StmtError(); 6368 } 6369 6370 setFunctionHasBranchProtectedScope(); 6371 6372 return OMPParallelSectionsDirective::Create( 6373 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 6374 } 6375 6376 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 6377 Stmt *AStmt, SourceLocation StartLoc, 6378 SourceLocation EndLoc) { 6379 if (!AStmt) 6380 return StmtError(); 6381 6382 auto *CS = cast<CapturedStmt>(AStmt); 6383 // 1.2.2 OpenMP Language Terminology 6384 // Structured block - An executable statement with a single entry at the 6385 // top and a single exit at the bottom. 6386 // The point of exit cannot be a branch out of the structured block. 6387 // longjmp() and throw() must not violate the entry/exit criteria. 6388 CS->getCapturedDecl()->setNothrow(); 6389 6390 setFunctionHasBranchProtectedScope(); 6391 6392 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6393 DSAStack->isCancelRegion()); 6394 } 6395 6396 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 6397 SourceLocation EndLoc) { 6398 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 6399 } 6400 6401 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 6402 SourceLocation EndLoc) { 6403 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 6404 } 6405 6406 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 6407 SourceLocation EndLoc) { 6408 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 6409 } 6410 6411 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 6412 Stmt *AStmt, 6413 SourceLocation StartLoc, 6414 SourceLocation EndLoc) { 6415 if (!AStmt) 6416 return StmtError(); 6417 6418 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6419 6420 setFunctionHasBranchProtectedScope(); 6421 6422 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 6423 AStmt, 6424 DSAStack->getTaskgroupReductionRef()); 6425 } 6426 6427 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 6428 SourceLocation StartLoc, 6429 SourceLocation EndLoc) { 6430 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 6431 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 6432 } 6433 6434 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 6435 Stmt *AStmt, 6436 SourceLocation StartLoc, 6437 SourceLocation EndLoc) { 6438 const OMPClause *DependFound = nullptr; 6439 const OMPClause *DependSourceClause = nullptr; 6440 const OMPClause *DependSinkClause = nullptr; 6441 bool ErrorFound = false; 6442 const OMPThreadsClause *TC = nullptr; 6443 const OMPSIMDClause *SC = nullptr; 6444 for (const OMPClause *C : Clauses) { 6445 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 6446 DependFound = C; 6447 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 6448 if (DependSourceClause) { 6449 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 6450 << getOpenMPDirectiveName(OMPD_ordered) 6451 << getOpenMPClauseName(OMPC_depend) << 2; 6452 ErrorFound = true; 6453 } else { 6454 DependSourceClause = C; 6455 } 6456 if (DependSinkClause) { 6457 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6458 << 0; 6459 ErrorFound = true; 6460 } 6461 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 6462 if (DependSourceClause) { 6463 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6464 << 1; 6465 ErrorFound = true; 6466 } 6467 DependSinkClause = C; 6468 } 6469 } else if (C->getClauseKind() == OMPC_threads) { 6470 TC = cast<OMPThreadsClause>(C); 6471 } else if (C->getClauseKind() == OMPC_simd) { 6472 SC = cast<OMPSIMDClause>(C); 6473 } 6474 } 6475 if (!ErrorFound && !SC && 6476 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 6477 // OpenMP [2.8.1,simd Construct, Restrictions] 6478 // An ordered construct with the simd clause is the only OpenMP construct 6479 // that can appear in the simd region. 6480 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 6481 ErrorFound = true; 6482 } else if (DependFound && (TC || SC)) { 6483 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 6484 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 6485 ErrorFound = true; 6486 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 6487 Diag(DependFound->getBeginLoc(), 6488 diag::err_omp_ordered_directive_without_param); 6489 ErrorFound = true; 6490 } else if (TC || Clauses.empty()) { 6491 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 6492 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 6493 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 6494 << (TC != nullptr); 6495 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 6496 ErrorFound = true; 6497 } 6498 } 6499 if ((!AStmt && !DependFound) || ErrorFound) 6500 return StmtError(); 6501 6502 if (AStmt) { 6503 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6504 6505 setFunctionHasBranchProtectedScope(); 6506 } 6507 6508 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6509 } 6510 6511 namespace { 6512 /// Helper class for checking expression in 'omp atomic [update]' 6513 /// construct. 6514 class OpenMPAtomicUpdateChecker { 6515 /// Error results for atomic update expressions. 6516 enum ExprAnalysisErrorCode { 6517 /// A statement is not an expression statement. 6518 NotAnExpression, 6519 /// Expression is not builtin binary or unary operation. 6520 NotABinaryOrUnaryExpression, 6521 /// Unary operation is not post-/pre- increment/decrement operation. 6522 NotAnUnaryIncDecExpression, 6523 /// An expression is not of scalar type. 6524 NotAScalarType, 6525 /// A binary operation is not an assignment operation. 6526 NotAnAssignmentOp, 6527 /// RHS part of the binary operation is not a binary expression. 6528 NotABinaryExpression, 6529 /// RHS part is not additive/multiplicative/shift/biwise binary 6530 /// expression. 6531 NotABinaryOperator, 6532 /// RHS binary operation does not have reference to the updated LHS 6533 /// part. 6534 NotAnUpdateExpression, 6535 /// No errors is found. 6536 NoError 6537 }; 6538 /// Reference to Sema. 6539 Sema &SemaRef; 6540 /// A location for note diagnostics (when error is found). 6541 SourceLocation NoteLoc; 6542 /// 'x' lvalue part of the source atomic expression. 6543 Expr *X; 6544 /// 'expr' rvalue part of the source atomic expression. 6545 Expr *E; 6546 /// Helper expression of the form 6547 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6548 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6549 Expr *UpdateExpr; 6550 /// Is 'x' a LHS in a RHS part of full update expression. It is 6551 /// important for non-associative operations. 6552 bool IsXLHSInRHSPart; 6553 BinaryOperatorKind Op; 6554 SourceLocation OpLoc; 6555 /// true if the source expression is a postfix unary operation, false 6556 /// if it is a prefix unary operation. 6557 bool IsPostfixUpdate; 6558 6559 public: 6560 OpenMPAtomicUpdateChecker(Sema &SemaRef) 6561 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 6562 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 6563 /// Check specified statement that it is suitable for 'atomic update' 6564 /// constructs and extract 'x', 'expr' and Operation from the original 6565 /// expression. If DiagId and NoteId == 0, then only check is performed 6566 /// without error notification. 6567 /// \param DiagId Diagnostic which should be emitted if error is found. 6568 /// \param NoteId Diagnostic note for the main error message. 6569 /// \return true if statement is not an update expression, false otherwise. 6570 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 6571 /// Return the 'x' lvalue part of the source atomic expression. 6572 Expr *getX() const { return X; } 6573 /// Return the 'expr' rvalue part of the source atomic expression. 6574 Expr *getExpr() const { return E; } 6575 /// Return the update expression used in calculation of the updated 6576 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6577 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6578 Expr *getUpdateExpr() const { return UpdateExpr; } 6579 /// Return true if 'x' is LHS in RHS part of full update expression, 6580 /// false otherwise. 6581 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 6582 6583 /// true if the source expression is a postfix unary operation, false 6584 /// if it is a prefix unary operation. 6585 bool isPostfixUpdate() const { return IsPostfixUpdate; } 6586 6587 private: 6588 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 6589 unsigned NoteId = 0); 6590 }; 6591 } // namespace 6592 6593 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 6594 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 6595 ExprAnalysisErrorCode ErrorFound = NoError; 6596 SourceLocation ErrorLoc, NoteLoc; 6597 SourceRange ErrorRange, NoteRange; 6598 // Allowed constructs are: 6599 // x = x binop expr; 6600 // x = expr binop x; 6601 if (AtomicBinOp->getOpcode() == BO_Assign) { 6602 X = AtomicBinOp->getLHS(); 6603 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 6604 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 6605 if (AtomicInnerBinOp->isMultiplicativeOp() || 6606 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 6607 AtomicInnerBinOp->isBitwiseOp()) { 6608 Op = AtomicInnerBinOp->getOpcode(); 6609 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 6610 Expr *LHS = AtomicInnerBinOp->getLHS(); 6611 Expr *RHS = AtomicInnerBinOp->getRHS(); 6612 llvm::FoldingSetNodeID XId, LHSId, RHSId; 6613 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 6614 /*Canonical=*/true); 6615 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 6616 /*Canonical=*/true); 6617 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 6618 /*Canonical=*/true); 6619 if (XId == LHSId) { 6620 E = RHS; 6621 IsXLHSInRHSPart = true; 6622 } else if (XId == RHSId) { 6623 E = LHS; 6624 IsXLHSInRHSPart = false; 6625 } else { 6626 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6627 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6628 NoteLoc = X->getExprLoc(); 6629 NoteRange = X->getSourceRange(); 6630 ErrorFound = NotAnUpdateExpression; 6631 } 6632 } else { 6633 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6634 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6635 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 6636 NoteRange = SourceRange(NoteLoc, NoteLoc); 6637 ErrorFound = NotABinaryOperator; 6638 } 6639 } else { 6640 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 6641 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 6642 ErrorFound = NotABinaryExpression; 6643 } 6644 } else { 6645 ErrorLoc = AtomicBinOp->getExprLoc(); 6646 ErrorRange = AtomicBinOp->getSourceRange(); 6647 NoteLoc = AtomicBinOp->getOperatorLoc(); 6648 NoteRange = SourceRange(NoteLoc, NoteLoc); 6649 ErrorFound = NotAnAssignmentOp; 6650 } 6651 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6652 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6653 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6654 return true; 6655 } 6656 if (SemaRef.CurContext->isDependentContext()) 6657 E = X = UpdateExpr = nullptr; 6658 return ErrorFound != NoError; 6659 } 6660 6661 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 6662 unsigned NoteId) { 6663 ExprAnalysisErrorCode ErrorFound = NoError; 6664 SourceLocation ErrorLoc, NoteLoc; 6665 SourceRange ErrorRange, NoteRange; 6666 // Allowed constructs are: 6667 // x++; 6668 // x--; 6669 // ++x; 6670 // --x; 6671 // x binop= expr; 6672 // x = x binop expr; 6673 // x = expr binop x; 6674 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 6675 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 6676 if (AtomicBody->getType()->isScalarType() || 6677 AtomicBody->isInstantiationDependent()) { 6678 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 6679 AtomicBody->IgnoreParenImpCasts())) { 6680 // Check for Compound Assignment Operation 6681 Op = BinaryOperator::getOpForCompoundAssignment( 6682 AtomicCompAssignOp->getOpcode()); 6683 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 6684 E = AtomicCompAssignOp->getRHS(); 6685 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 6686 IsXLHSInRHSPart = true; 6687 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 6688 AtomicBody->IgnoreParenImpCasts())) { 6689 // Check for Binary Operation 6690 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 6691 return true; 6692 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 6693 AtomicBody->IgnoreParenImpCasts())) { 6694 // Check for Unary Operation 6695 if (AtomicUnaryOp->isIncrementDecrementOp()) { 6696 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 6697 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 6698 OpLoc = AtomicUnaryOp->getOperatorLoc(); 6699 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 6700 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 6701 IsXLHSInRHSPart = true; 6702 } else { 6703 ErrorFound = NotAnUnaryIncDecExpression; 6704 ErrorLoc = AtomicUnaryOp->getExprLoc(); 6705 ErrorRange = AtomicUnaryOp->getSourceRange(); 6706 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 6707 NoteRange = SourceRange(NoteLoc, NoteLoc); 6708 } 6709 } else if (!AtomicBody->isInstantiationDependent()) { 6710 ErrorFound = NotABinaryOrUnaryExpression; 6711 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 6712 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 6713 } 6714 } else { 6715 ErrorFound = NotAScalarType; 6716 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 6717 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6718 } 6719 } else { 6720 ErrorFound = NotAnExpression; 6721 NoteLoc = ErrorLoc = S->getBeginLoc(); 6722 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6723 } 6724 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6725 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6726 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6727 return true; 6728 } 6729 if (SemaRef.CurContext->isDependentContext()) 6730 E = X = UpdateExpr = nullptr; 6731 if (ErrorFound == NoError && E && X) { 6732 // Build an update expression of form 'OpaqueValueExpr(x) binop 6733 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 6734 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 6735 auto *OVEX = new (SemaRef.getASTContext()) 6736 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 6737 auto *OVEExpr = new (SemaRef.getASTContext()) 6738 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 6739 ExprResult Update = 6740 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 6741 IsXLHSInRHSPart ? OVEExpr : OVEX); 6742 if (Update.isInvalid()) 6743 return true; 6744 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 6745 Sema::AA_Casting); 6746 if (Update.isInvalid()) 6747 return true; 6748 UpdateExpr = Update.get(); 6749 } 6750 return ErrorFound != NoError; 6751 } 6752 6753 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 6754 Stmt *AStmt, 6755 SourceLocation StartLoc, 6756 SourceLocation EndLoc) { 6757 if (!AStmt) 6758 return StmtError(); 6759 6760 auto *CS = cast<CapturedStmt>(AStmt); 6761 // 1.2.2 OpenMP Language Terminology 6762 // Structured block - An executable statement with a single entry at the 6763 // top and a single exit at the bottom. 6764 // The point of exit cannot be a branch out of the structured block. 6765 // longjmp() and throw() must not violate the entry/exit criteria. 6766 OpenMPClauseKind AtomicKind = OMPC_unknown; 6767 SourceLocation AtomicKindLoc; 6768 for (const OMPClause *C : Clauses) { 6769 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 6770 C->getClauseKind() == OMPC_update || 6771 C->getClauseKind() == OMPC_capture) { 6772 if (AtomicKind != OMPC_unknown) { 6773 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 6774 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 6775 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 6776 << getOpenMPClauseName(AtomicKind); 6777 } else { 6778 AtomicKind = C->getClauseKind(); 6779 AtomicKindLoc = C->getBeginLoc(); 6780 } 6781 } 6782 } 6783 6784 Stmt *Body = CS->getCapturedStmt(); 6785 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 6786 Body = EWC->getSubExpr(); 6787 6788 Expr *X = nullptr; 6789 Expr *V = nullptr; 6790 Expr *E = nullptr; 6791 Expr *UE = nullptr; 6792 bool IsXLHSInRHSPart = false; 6793 bool IsPostfixUpdate = false; 6794 // OpenMP [2.12.6, atomic Construct] 6795 // In the next expressions: 6796 // * x and v (as applicable) are both l-value expressions with scalar type. 6797 // * During the execution of an atomic region, multiple syntactic 6798 // occurrences of x must designate the same storage location. 6799 // * Neither of v and expr (as applicable) may access the storage location 6800 // designated by x. 6801 // * Neither of x and expr (as applicable) may access the storage location 6802 // designated by v. 6803 // * expr is an expression with scalar type. 6804 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 6805 // * binop, binop=, ++, and -- are not overloaded operators. 6806 // * The expression x binop expr must be numerically equivalent to x binop 6807 // (expr). This requirement is satisfied if the operators in expr have 6808 // precedence greater than binop, or by using parentheses around expr or 6809 // subexpressions of expr. 6810 // * The expression expr binop x must be numerically equivalent to (expr) 6811 // binop x. This requirement is satisfied if the operators in expr have 6812 // precedence equal to or greater than binop, or by using parentheses around 6813 // expr or subexpressions of expr. 6814 // * For forms that allow multiple occurrences of x, the number of times 6815 // that x is evaluated is unspecified. 6816 if (AtomicKind == OMPC_read) { 6817 enum { 6818 NotAnExpression, 6819 NotAnAssignmentOp, 6820 NotAScalarType, 6821 NotAnLValue, 6822 NoError 6823 } ErrorFound = NoError; 6824 SourceLocation ErrorLoc, NoteLoc; 6825 SourceRange ErrorRange, NoteRange; 6826 // If clause is read: 6827 // v = x; 6828 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6829 const auto *AtomicBinOp = 6830 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6831 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6832 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6833 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 6834 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6835 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 6836 if (!X->isLValue() || !V->isLValue()) { 6837 const Expr *NotLValueExpr = X->isLValue() ? V : X; 6838 ErrorFound = NotAnLValue; 6839 ErrorLoc = AtomicBinOp->getExprLoc(); 6840 ErrorRange = AtomicBinOp->getSourceRange(); 6841 NoteLoc = NotLValueExpr->getExprLoc(); 6842 NoteRange = NotLValueExpr->getSourceRange(); 6843 } 6844 } else if (!X->isInstantiationDependent() || 6845 !V->isInstantiationDependent()) { 6846 const Expr *NotScalarExpr = 6847 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6848 ? V 6849 : X; 6850 ErrorFound = NotAScalarType; 6851 ErrorLoc = AtomicBinOp->getExprLoc(); 6852 ErrorRange = AtomicBinOp->getSourceRange(); 6853 NoteLoc = NotScalarExpr->getExprLoc(); 6854 NoteRange = NotScalarExpr->getSourceRange(); 6855 } 6856 } else if (!AtomicBody->isInstantiationDependent()) { 6857 ErrorFound = NotAnAssignmentOp; 6858 ErrorLoc = AtomicBody->getExprLoc(); 6859 ErrorRange = AtomicBody->getSourceRange(); 6860 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6861 : AtomicBody->getExprLoc(); 6862 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6863 : AtomicBody->getSourceRange(); 6864 } 6865 } else { 6866 ErrorFound = NotAnExpression; 6867 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6868 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6869 } 6870 if (ErrorFound != NoError) { 6871 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 6872 << ErrorRange; 6873 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6874 << NoteRange; 6875 return StmtError(); 6876 } 6877 if (CurContext->isDependentContext()) 6878 V = X = nullptr; 6879 } else if (AtomicKind == OMPC_write) { 6880 enum { 6881 NotAnExpression, 6882 NotAnAssignmentOp, 6883 NotAScalarType, 6884 NotAnLValue, 6885 NoError 6886 } ErrorFound = NoError; 6887 SourceLocation ErrorLoc, NoteLoc; 6888 SourceRange ErrorRange, NoteRange; 6889 // If clause is write: 6890 // x = expr; 6891 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6892 const auto *AtomicBinOp = 6893 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6894 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6895 X = AtomicBinOp->getLHS(); 6896 E = AtomicBinOp->getRHS(); 6897 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6898 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 6899 if (!X->isLValue()) { 6900 ErrorFound = NotAnLValue; 6901 ErrorLoc = AtomicBinOp->getExprLoc(); 6902 ErrorRange = AtomicBinOp->getSourceRange(); 6903 NoteLoc = X->getExprLoc(); 6904 NoteRange = X->getSourceRange(); 6905 } 6906 } else if (!X->isInstantiationDependent() || 6907 !E->isInstantiationDependent()) { 6908 const Expr *NotScalarExpr = 6909 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6910 ? E 6911 : X; 6912 ErrorFound = NotAScalarType; 6913 ErrorLoc = AtomicBinOp->getExprLoc(); 6914 ErrorRange = AtomicBinOp->getSourceRange(); 6915 NoteLoc = NotScalarExpr->getExprLoc(); 6916 NoteRange = NotScalarExpr->getSourceRange(); 6917 } 6918 } else if (!AtomicBody->isInstantiationDependent()) { 6919 ErrorFound = NotAnAssignmentOp; 6920 ErrorLoc = AtomicBody->getExprLoc(); 6921 ErrorRange = AtomicBody->getSourceRange(); 6922 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6923 : AtomicBody->getExprLoc(); 6924 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6925 : AtomicBody->getSourceRange(); 6926 } 6927 } else { 6928 ErrorFound = NotAnExpression; 6929 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6930 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6931 } 6932 if (ErrorFound != NoError) { 6933 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 6934 << ErrorRange; 6935 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6936 << NoteRange; 6937 return StmtError(); 6938 } 6939 if (CurContext->isDependentContext()) 6940 E = X = nullptr; 6941 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 6942 // If clause is update: 6943 // x++; 6944 // x--; 6945 // ++x; 6946 // --x; 6947 // x binop= expr; 6948 // x = x binop expr; 6949 // x = expr binop x; 6950 OpenMPAtomicUpdateChecker Checker(*this); 6951 if (Checker.checkStatement( 6952 Body, (AtomicKind == OMPC_update) 6953 ? diag::err_omp_atomic_update_not_expression_statement 6954 : diag::err_omp_atomic_not_expression_statement, 6955 diag::note_omp_atomic_update)) 6956 return StmtError(); 6957 if (!CurContext->isDependentContext()) { 6958 E = Checker.getExpr(); 6959 X = Checker.getX(); 6960 UE = Checker.getUpdateExpr(); 6961 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6962 } 6963 } else if (AtomicKind == OMPC_capture) { 6964 enum { 6965 NotAnAssignmentOp, 6966 NotACompoundStatement, 6967 NotTwoSubstatements, 6968 NotASpecificExpression, 6969 NoError 6970 } ErrorFound = NoError; 6971 SourceLocation ErrorLoc, NoteLoc; 6972 SourceRange ErrorRange, NoteRange; 6973 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6974 // If clause is a capture: 6975 // v = x++; 6976 // v = x--; 6977 // v = ++x; 6978 // v = --x; 6979 // v = x binop= expr; 6980 // v = x = x binop expr; 6981 // v = x = expr binop x; 6982 const auto *AtomicBinOp = 6983 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6984 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6985 V = AtomicBinOp->getLHS(); 6986 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6987 OpenMPAtomicUpdateChecker Checker(*this); 6988 if (Checker.checkStatement( 6989 Body, diag::err_omp_atomic_capture_not_expression_statement, 6990 diag::note_omp_atomic_update)) 6991 return StmtError(); 6992 E = Checker.getExpr(); 6993 X = Checker.getX(); 6994 UE = Checker.getUpdateExpr(); 6995 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6996 IsPostfixUpdate = Checker.isPostfixUpdate(); 6997 } else if (!AtomicBody->isInstantiationDependent()) { 6998 ErrorLoc = AtomicBody->getExprLoc(); 6999 ErrorRange = AtomicBody->getSourceRange(); 7000 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7001 : AtomicBody->getExprLoc(); 7002 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7003 : AtomicBody->getSourceRange(); 7004 ErrorFound = NotAnAssignmentOp; 7005 } 7006 if (ErrorFound != NoError) { 7007 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7008 << ErrorRange; 7009 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7010 return StmtError(); 7011 } 7012 if (CurContext->isDependentContext()) 7013 UE = V = E = X = nullptr; 7014 } else { 7015 // If clause is a capture: 7016 // { v = x; x = expr; } 7017 // { v = x; x++; } 7018 // { v = x; x--; } 7019 // { v = x; ++x; } 7020 // { v = x; --x; } 7021 // { v = x; x binop= expr; } 7022 // { v = x; x = x binop expr; } 7023 // { v = x; x = expr binop x; } 7024 // { x++; v = x; } 7025 // { x--; v = x; } 7026 // { ++x; v = x; } 7027 // { --x; v = x; } 7028 // { x binop= expr; v = x; } 7029 // { x = x binop expr; v = x; } 7030 // { x = expr binop x; v = x; } 7031 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7032 // Check that this is { expr1; expr2; } 7033 if (CS->size() == 2) { 7034 Stmt *First = CS->body_front(); 7035 Stmt *Second = CS->body_back(); 7036 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7037 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7038 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7039 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7040 // Need to find what subexpression is 'v' and what is 'x'. 7041 OpenMPAtomicUpdateChecker Checker(*this); 7042 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7043 BinaryOperator *BinOp = nullptr; 7044 if (IsUpdateExprFound) { 7045 BinOp = dyn_cast<BinaryOperator>(First); 7046 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7047 } 7048 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7049 // { v = x; x++; } 7050 // { v = x; x--; } 7051 // { v = x; ++x; } 7052 // { v = x; --x; } 7053 // { v = x; x binop= expr; } 7054 // { v = x; x = x binop expr; } 7055 // { v = x; x = expr binop x; } 7056 // Check that the first expression has form v = x. 7057 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7058 llvm::FoldingSetNodeID XId, PossibleXId; 7059 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7060 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7061 IsUpdateExprFound = XId == PossibleXId; 7062 if (IsUpdateExprFound) { 7063 V = BinOp->getLHS(); 7064 X = Checker.getX(); 7065 E = Checker.getExpr(); 7066 UE = Checker.getUpdateExpr(); 7067 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7068 IsPostfixUpdate = true; 7069 } 7070 } 7071 if (!IsUpdateExprFound) { 7072 IsUpdateExprFound = !Checker.checkStatement(First); 7073 BinOp = nullptr; 7074 if (IsUpdateExprFound) { 7075 BinOp = dyn_cast<BinaryOperator>(Second); 7076 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7077 } 7078 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7079 // { x++; v = x; } 7080 // { x--; v = x; } 7081 // { ++x; v = x; } 7082 // { --x; v = x; } 7083 // { x binop= expr; v = x; } 7084 // { x = x binop expr; v = x; } 7085 // { x = expr binop x; v = x; } 7086 // Check that the second expression has form v = x. 7087 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7088 llvm::FoldingSetNodeID XId, PossibleXId; 7089 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7090 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7091 IsUpdateExprFound = XId == PossibleXId; 7092 if (IsUpdateExprFound) { 7093 V = BinOp->getLHS(); 7094 X = Checker.getX(); 7095 E = Checker.getExpr(); 7096 UE = Checker.getUpdateExpr(); 7097 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7098 IsPostfixUpdate = false; 7099 } 7100 } 7101 } 7102 if (!IsUpdateExprFound) { 7103 // { v = x; x = expr; } 7104 auto *FirstExpr = dyn_cast<Expr>(First); 7105 auto *SecondExpr = dyn_cast<Expr>(Second); 7106 if (!FirstExpr || !SecondExpr || 7107 !(FirstExpr->isInstantiationDependent() || 7108 SecondExpr->isInstantiationDependent())) { 7109 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7110 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7111 ErrorFound = NotAnAssignmentOp; 7112 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7113 : First->getBeginLoc(); 7114 NoteRange = ErrorRange = FirstBinOp 7115 ? FirstBinOp->getSourceRange() 7116 : SourceRange(ErrorLoc, ErrorLoc); 7117 } else { 7118 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7119 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7120 ErrorFound = NotAnAssignmentOp; 7121 NoteLoc = ErrorLoc = SecondBinOp 7122 ? SecondBinOp->getOperatorLoc() 7123 : Second->getBeginLoc(); 7124 NoteRange = ErrorRange = 7125 SecondBinOp ? SecondBinOp->getSourceRange() 7126 : SourceRange(ErrorLoc, ErrorLoc); 7127 } else { 7128 Expr *PossibleXRHSInFirst = 7129 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7130 Expr *PossibleXLHSInSecond = 7131 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7132 llvm::FoldingSetNodeID X1Id, X2Id; 7133 PossibleXRHSInFirst->Profile(X1Id, Context, 7134 /*Canonical=*/true); 7135 PossibleXLHSInSecond->Profile(X2Id, Context, 7136 /*Canonical=*/true); 7137 IsUpdateExprFound = X1Id == X2Id; 7138 if (IsUpdateExprFound) { 7139 V = FirstBinOp->getLHS(); 7140 X = SecondBinOp->getLHS(); 7141 E = SecondBinOp->getRHS(); 7142 UE = nullptr; 7143 IsXLHSInRHSPart = false; 7144 IsPostfixUpdate = true; 7145 } else { 7146 ErrorFound = NotASpecificExpression; 7147 ErrorLoc = FirstBinOp->getExprLoc(); 7148 ErrorRange = FirstBinOp->getSourceRange(); 7149 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7150 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7151 } 7152 } 7153 } 7154 } 7155 } 7156 } else { 7157 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7158 NoteRange = ErrorRange = 7159 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7160 ErrorFound = NotTwoSubstatements; 7161 } 7162 } else { 7163 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7164 NoteRange = ErrorRange = 7165 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7166 ErrorFound = NotACompoundStatement; 7167 } 7168 if (ErrorFound != NoError) { 7169 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7170 << ErrorRange; 7171 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7172 return StmtError(); 7173 } 7174 if (CurContext->isDependentContext()) 7175 UE = V = E = X = nullptr; 7176 } 7177 } 7178 7179 setFunctionHasBranchProtectedScope(); 7180 7181 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7182 X, V, E, UE, IsXLHSInRHSPart, 7183 IsPostfixUpdate); 7184 } 7185 7186 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7187 Stmt *AStmt, 7188 SourceLocation StartLoc, 7189 SourceLocation EndLoc) { 7190 if (!AStmt) 7191 return StmtError(); 7192 7193 auto *CS = cast<CapturedStmt>(AStmt); 7194 // 1.2.2 OpenMP Language Terminology 7195 // Structured block - An executable statement with a single entry at the 7196 // top and a single exit at the bottom. 7197 // The point of exit cannot be a branch out of the structured block. 7198 // longjmp() and throw() must not violate the entry/exit criteria. 7199 CS->getCapturedDecl()->setNothrow(); 7200 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7201 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7202 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7203 // 1.2.2 OpenMP Language Terminology 7204 // Structured block - An executable statement with a single entry at the 7205 // top and a single exit at the bottom. 7206 // The point of exit cannot be a branch out of the structured block. 7207 // longjmp() and throw() must not violate the entry/exit criteria. 7208 CS->getCapturedDecl()->setNothrow(); 7209 } 7210 7211 // OpenMP [2.16, Nesting of Regions] 7212 // If specified, a teams construct must be contained within a target 7213 // construct. That target construct must contain no statements or directives 7214 // outside of the teams construct. 7215 if (DSAStack->hasInnerTeamsRegion()) { 7216 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7217 bool OMPTeamsFound = true; 7218 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7219 auto I = CS->body_begin(); 7220 while (I != CS->body_end()) { 7221 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7222 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7223 OMPTeamsFound) { 7224 7225 OMPTeamsFound = false; 7226 break; 7227 } 7228 ++I; 7229 } 7230 assert(I != CS->body_end() && "Not found statement"); 7231 S = *I; 7232 } else { 7233 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7234 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7235 } 7236 if (!OMPTeamsFound) { 7237 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7238 Diag(DSAStack->getInnerTeamsRegionLoc(), 7239 diag::note_omp_nested_teams_construct_here); 7240 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7241 << isa<OMPExecutableDirective>(S); 7242 return StmtError(); 7243 } 7244 } 7245 7246 setFunctionHasBranchProtectedScope(); 7247 7248 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7249 } 7250 7251 StmtResult 7252 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7253 Stmt *AStmt, SourceLocation StartLoc, 7254 SourceLocation EndLoc) { 7255 if (!AStmt) 7256 return StmtError(); 7257 7258 auto *CS = cast<CapturedStmt>(AStmt); 7259 // 1.2.2 OpenMP Language Terminology 7260 // Structured block - An executable statement with a single entry at the 7261 // top and a single exit at the bottom. 7262 // The point of exit cannot be a branch out of the structured block. 7263 // longjmp() and throw() must not violate the entry/exit criteria. 7264 CS->getCapturedDecl()->setNothrow(); 7265 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7266 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7267 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7268 // 1.2.2 OpenMP Language Terminology 7269 // Structured block - An executable statement with a single entry at the 7270 // top and a single exit at the bottom. 7271 // The point of exit cannot be a branch out of the structured block. 7272 // longjmp() and throw() must not violate the entry/exit criteria. 7273 CS->getCapturedDecl()->setNothrow(); 7274 } 7275 7276 setFunctionHasBranchProtectedScope(); 7277 7278 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7279 AStmt); 7280 } 7281 7282 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7283 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7284 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7285 if (!AStmt) 7286 return StmtError(); 7287 7288 auto *CS = cast<CapturedStmt>(AStmt); 7289 // 1.2.2 OpenMP Language Terminology 7290 // Structured block - An executable statement with a single entry at the 7291 // top and a single exit at the bottom. 7292 // The point of exit cannot be a branch out of the structured block. 7293 // longjmp() and throw() must not violate the entry/exit criteria. 7294 CS->getCapturedDecl()->setNothrow(); 7295 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7296 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7297 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7298 // 1.2.2 OpenMP Language Terminology 7299 // Structured block - An executable statement with a single entry at the 7300 // top and a single exit at the bottom. 7301 // The point of exit cannot be a branch out of the structured block. 7302 // longjmp() and throw() must not violate the entry/exit criteria. 7303 CS->getCapturedDecl()->setNothrow(); 7304 } 7305 7306 OMPLoopDirective::HelperExprs B; 7307 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7308 // define the nested loops number. 7309 unsigned NestedLoopCount = 7310 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 7311 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7312 VarsWithImplicitDSA, B); 7313 if (NestedLoopCount == 0) 7314 return StmtError(); 7315 7316 assert((CurContext->isDependentContext() || B.builtAll()) && 7317 "omp target parallel for loop exprs were not built"); 7318 7319 if (!CurContext->isDependentContext()) { 7320 // Finalize the clauses that need pre-built expressions for CodeGen. 7321 for (OMPClause *C : Clauses) { 7322 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7323 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7324 B.NumIterations, *this, CurScope, 7325 DSAStack)) 7326 return StmtError(); 7327 } 7328 } 7329 7330 setFunctionHasBranchProtectedScope(); 7331 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 7332 NestedLoopCount, Clauses, AStmt, 7333 B, DSAStack->isCancelRegion()); 7334 } 7335 7336 /// Check for existence of a map clause in the list of clauses. 7337 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 7338 const OpenMPClauseKind K) { 7339 return llvm::any_of( 7340 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 7341 } 7342 7343 template <typename... Params> 7344 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 7345 const Params... ClauseTypes) { 7346 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 7347 } 7348 7349 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 7350 Stmt *AStmt, 7351 SourceLocation StartLoc, 7352 SourceLocation EndLoc) { 7353 if (!AStmt) 7354 return StmtError(); 7355 7356 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7357 7358 // OpenMP [2.10.1, Restrictions, p. 97] 7359 // At least one map clause must appear on the directive. 7360 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 7361 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7362 << "'map' or 'use_device_ptr'" 7363 << getOpenMPDirectiveName(OMPD_target_data); 7364 return StmtError(); 7365 } 7366 7367 setFunctionHasBranchProtectedScope(); 7368 7369 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7370 AStmt); 7371 } 7372 7373 StmtResult 7374 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 7375 SourceLocation StartLoc, 7376 SourceLocation EndLoc, Stmt *AStmt) { 7377 if (!AStmt) 7378 return StmtError(); 7379 7380 auto *CS = cast<CapturedStmt>(AStmt); 7381 // 1.2.2 OpenMP Language Terminology 7382 // Structured block - An executable statement with a single entry at the 7383 // top and a single exit at the bottom. 7384 // The point of exit cannot be a branch out of the structured block. 7385 // longjmp() and throw() must not violate the entry/exit criteria. 7386 CS->getCapturedDecl()->setNothrow(); 7387 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 7388 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7389 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7390 // 1.2.2 OpenMP Language Terminology 7391 // Structured block - An executable statement with a single entry at the 7392 // top and a single exit at the bottom. 7393 // The point of exit cannot be a branch out of the structured block. 7394 // longjmp() and throw() must not violate the entry/exit criteria. 7395 CS->getCapturedDecl()->setNothrow(); 7396 } 7397 7398 // OpenMP [2.10.2, Restrictions, p. 99] 7399 // At least one map clause must appear on the directive. 7400 if (!hasClauses(Clauses, OMPC_map)) { 7401 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7402 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 7403 return StmtError(); 7404 } 7405 7406 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7407 AStmt); 7408 } 7409 7410 StmtResult 7411 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 7412 SourceLocation StartLoc, 7413 SourceLocation EndLoc, Stmt *AStmt) { 7414 if (!AStmt) 7415 return StmtError(); 7416 7417 auto *CS = cast<CapturedStmt>(AStmt); 7418 // 1.2.2 OpenMP Language Terminology 7419 // Structured block - An executable statement with a single entry at the 7420 // top and a single exit at the bottom. 7421 // The point of exit cannot be a branch out of the structured block. 7422 // longjmp() and throw() must not violate the entry/exit criteria. 7423 CS->getCapturedDecl()->setNothrow(); 7424 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 7425 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7426 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7427 // 1.2.2 OpenMP Language Terminology 7428 // Structured block - An executable statement with a single entry at the 7429 // top and a single exit at the bottom. 7430 // The point of exit cannot be a branch out of the structured block. 7431 // longjmp() and throw() must not violate the entry/exit criteria. 7432 CS->getCapturedDecl()->setNothrow(); 7433 } 7434 7435 // OpenMP [2.10.3, Restrictions, p. 102] 7436 // At least one map clause must appear on the directive. 7437 if (!hasClauses(Clauses, OMPC_map)) { 7438 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7439 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 7440 return StmtError(); 7441 } 7442 7443 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7444 AStmt); 7445 } 7446 7447 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 7448 SourceLocation StartLoc, 7449 SourceLocation EndLoc, 7450 Stmt *AStmt) { 7451 if (!AStmt) 7452 return StmtError(); 7453 7454 auto *CS = cast<CapturedStmt>(AStmt); 7455 // 1.2.2 OpenMP Language Terminology 7456 // Structured block - An executable statement with a single entry at the 7457 // top and a single exit at the bottom. 7458 // The point of exit cannot be a branch out of the structured block. 7459 // longjmp() and throw() must not violate the entry/exit criteria. 7460 CS->getCapturedDecl()->setNothrow(); 7461 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 7462 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7463 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7464 // 1.2.2 OpenMP Language Terminology 7465 // Structured block - An executable statement with a single entry at the 7466 // top and a single exit at the bottom. 7467 // The point of exit cannot be a branch out of the structured block. 7468 // longjmp() and throw() must not violate the entry/exit criteria. 7469 CS->getCapturedDecl()->setNothrow(); 7470 } 7471 7472 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 7473 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 7474 return StmtError(); 7475 } 7476 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 7477 AStmt); 7478 } 7479 7480 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 7481 Stmt *AStmt, SourceLocation StartLoc, 7482 SourceLocation EndLoc) { 7483 if (!AStmt) 7484 return StmtError(); 7485 7486 auto *CS = cast<CapturedStmt>(AStmt); 7487 // 1.2.2 OpenMP Language Terminology 7488 // Structured block - An executable statement with a single entry at the 7489 // top and a single exit at the bottom. 7490 // The point of exit cannot be a branch out of the structured block. 7491 // longjmp() and throw() must not violate the entry/exit criteria. 7492 CS->getCapturedDecl()->setNothrow(); 7493 7494 setFunctionHasBranchProtectedScope(); 7495 7496 DSAStack->setParentTeamsRegionLoc(StartLoc); 7497 7498 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7499 } 7500 7501 StmtResult 7502 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 7503 SourceLocation EndLoc, 7504 OpenMPDirectiveKind CancelRegion) { 7505 if (DSAStack->isParentNowaitRegion()) { 7506 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 7507 return StmtError(); 7508 } 7509 if (DSAStack->isParentOrderedRegion()) { 7510 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 7511 return StmtError(); 7512 } 7513 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 7514 CancelRegion); 7515 } 7516 7517 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 7518 SourceLocation StartLoc, 7519 SourceLocation EndLoc, 7520 OpenMPDirectiveKind CancelRegion) { 7521 if (DSAStack->isParentNowaitRegion()) { 7522 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 7523 return StmtError(); 7524 } 7525 if (DSAStack->isParentOrderedRegion()) { 7526 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 7527 return StmtError(); 7528 } 7529 DSAStack->setParentCancelRegion(/*Cancel=*/true); 7530 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7531 CancelRegion); 7532 } 7533 7534 static bool checkGrainsizeNumTasksClauses(Sema &S, 7535 ArrayRef<OMPClause *> Clauses) { 7536 const OMPClause *PrevClause = nullptr; 7537 bool ErrorFound = false; 7538 for (const OMPClause *C : Clauses) { 7539 if (C->getClauseKind() == OMPC_grainsize || 7540 C->getClauseKind() == OMPC_num_tasks) { 7541 if (!PrevClause) 7542 PrevClause = C; 7543 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 7544 S.Diag(C->getBeginLoc(), 7545 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 7546 << getOpenMPClauseName(C->getClauseKind()) 7547 << getOpenMPClauseName(PrevClause->getClauseKind()); 7548 S.Diag(PrevClause->getBeginLoc(), 7549 diag::note_omp_previous_grainsize_num_tasks) 7550 << getOpenMPClauseName(PrevClause->getClauseKind()); 7551 ErrorFound = true; 7552 } 7553 } 7554 } 7555 return ErrorFound; 7556 } 7557 7558 static bool checkReductionClauseWithNogroup(Sema &S, 7559 ArrayRef<OMPClause *> Clauses) { 7560 const OMPClause *ReductionClause = nullptr; 7561 const OMPClause *NogroupClause = nullptr; 7562 for (const OMPClause *C : Clauses) { 7563 if (C->getClauseKind() == OMPC_reduction) { 7564 ReductionClause = C; 7565 if (NogroupClause) 7566 break; 7567 continue; 7568 } 7569 if (C->getClauseKind() == OMPC_nogroup) { 7570 NogroupClause = C; 7571 if (ReductionClause) 7572 break; 7573 continue; 7574 } 7575 } 7576 if (ReductionClause && NogroupClause) { 7577 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 7578 << SourceRange(NogroupClause->getBeginLoc(), 7579 NogroupClause->getEndLoc()); 7580 return true; 7581 } 7582 return false; 7583 } 7584 7585 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 7586 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7587 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7588 if (!AStmt) 7589 return StmtError(); 7590 7591 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7592 OMPLoopDirective::HelperExprs B; 7593 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7594 // define the nested loops number. 7595 unsigned NestedLoopCount = 7596 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 7597 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7598 VarsWithImplicitDSA, B); 7599 if (NestedLoopCount == 0) 7600 return StmtError(); 7601 7602 assert((CurContext->isDependentContext() || B.builtAll()) && 7603 "omp for loop exprs were not built"); 7604 7605 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7606 // The grainsize clause and num_tasks clause are mutually exclusive and may 7607 // not appear on the same taskloop directive. 7608 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7609 return StmtError(); 7610 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7611 // If a reduction clause is present on the taskloop directive, the nogroup 7612 // clause must not be specified. 7613 if (checkReductionClauseWithNogroup(*this, Clauses)) 7614 return StmtError(); 7615 7616 setFunctionHasBranchProtectedScope(); 7617 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 7618 NestedLoopCount, Clauses, AStmt, B); 7619 } 7620 7621 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 7622 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7623 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7624 if (!AStmt) 7625 return StmtError(); 7626 7627 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7628 OMPLoopDirective::HelperExprs B; 7629 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7630 // define the nested loops number. 7631 unsigned NestedLoopCount = 7632 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 7633 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7634 VarsWithImplicitDSA, B); 7635 if (NestedLoopCount == 0) 7636 return StmtError(); 7637 7638 assert((CurContext->isDependentContext() || B.builtAll()) && 7639 "omp for loop exprs were not built"); 7640 7641 if (!CurContext->isDependentContext()) { 7642 // Finalize the clauses that need pre-built expressions for CodeGen. 7643 for (OMPClause *C : Clauses) { 7644 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7645 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7646 B.NumIterations, *this, CurScope, 7647 DSAStack)) 7648 return StmtError(); 7649 } 7650 } 7651 7652 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7653 // The grainsize clause and num_tasks clause are mutually exclusive and may 7654 // not appear on the same taskloop directive. 7655 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7656 return StmtError(); 7657 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7658 // If a reduction clause is present on the taskloop directive, the nogroup 7659 // clause must not be specified. 7660 if (checkReductionClauseWithNogroup(*this, Clauses)) 7661 return StmtError(); 7662 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7663 return StmtError(); 7664 7665 setFunctionHasBranchProtectedScope(); 7666 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 7667 NestedLoopCount, Clauses, AStmt, B); 7668 } 7669 7670 StmtResult Sema::ActOnOpenMPDistributeDirective( 7671 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7672 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7673 if (!AStmt) 7674 return StmtError(); 7675 7676 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7677 OMPLoopDirective::HelperExprs B; 7678 // In presence of clause 'collapse' with number of loops, it will 7679 // define the nested loops number. 7680 unsigned NestedLoopCount = 7681 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 7682 nullptr /*ordered not a clause on distribute*/, AStmt, 7683 *this, *DSAStack, VarsWithImplicitDSA, B); 7684 if (NestedLoopCount == 0) 7685 return StmtError(); 7686 7687 assert((CurContext->isDependentContext() || B.builtAll()) && 7688 "omp for loop exprs were not built"); 7689 7690 setFunctionHasBranchProtectedScope(); 7691 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 7692 NestedLoopCount, Clauses, AStmt, B); 7693 } 7694 7695 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 7696 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7697 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7698 if (!AStmt) 7699 return StmtError(); 7700 7701 auto *CS = cast<CapturedStmt>(AStmt); 7702 // 1.2.2 OpenMP Language Terminology 7703 // Structured block - An executable statement with a single entry at the 7704 // top and a single exit at the bottom. 7705 // The point of exit cannot be a branch out of the structured block. 7706 // longjmp() and throw() must not violate the entry/exit criteria. 7707 CS->getCapturedDecl()->setNothrow(); 7708 for (int ThisCaptureLevel = 7709 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 7710 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7711 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7712 // 1.2.2 OpenMP Language Terminology 7713 // Structured block - An executable statement with a single entry at the 7714 // top and a single exit at the bottom. 7715 // The point of exit cannot be a branch out of the structured block. 7716 // longjmp() and throw() must not violate the entry/exit criteria. 7717 CS->getCapturedDecl()->setNothrow(); 7718 } 7719 7720 OMPLoopDirective::HelperExprs B; 7721 // In presence of clause 'collapse' with number of loops, it will 7722 // define the nested loops number. 7723 unsigned NestedLoopCount = checkOpenMPLoop( 7724 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7725 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7726 VarsWithImplicitDSA, B); 7727 if (NestedLoopCount == 0) 7728 return StmtError(); 7729 7730 assert((CurContext->isDependentContext() || B.builtAll()) && 7731 "omp for loop exprs were not built"); 7732 7733 setFunctionHasBranchProtectedScope(); 7734 return OMPDistributeParallelForDirective::Create( 7735 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7736 DSAStack->isCancelRegion()); 7737 } 7738 7739 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 7740 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7741 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7742 if (!AStmt) 7743 return StmtError(); 7744 7745 auto *CS = cast<CapturedStmt>(AStmt); 7746 // 1.2.2 OpenMP Language Terminology 7747 // Structured block - An executable statement with a single entry at the 7748 // top and a single exit at the bottom. 7749 // The point of exit cannot be a branch out of the structured block. 7750 // longjmp() and throw() must not violate the entry/exit criteria. 7751 CS->getCapturedDecl()->setNothrow(); 7752 for (int ThisCaptureLevel = 7753 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 7754 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7755 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7756 // 1.2.2 OpenMP Language Terminology 7757 // Structured block - An executable statement with a single entry at the 7758 // top and a single exit at the bottom. 7759 // The point of exit cannot be a branch out of the structured block. 7760 // longjmp() and throw() must not violate the entry/exit criteria. 7761 CS->getCapturedDecl()->setNothrow(); 7762 } 7763 7764 OMPLoopDirective::HelperExprs B; 7765 // In presence of clause 'collapse' with number of loops, it will 7766 // define the nested loops number. 7767 unsigned NestedLoopCount = checkOpenMPLoop( 7768 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7769 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7770 VarsWithImplicitDSA, B); 7771 if (NestedLoopCount == 0) 7772 return StmtError(); 7773 7774 assert((CurContext->isDependentContext() || B.builtAll()) && 7775 "omp for loop exprs were not built"); 7776 7777 if (!CurContext->isDependentContext()) { 7778 // Finalize the clauses that need pre-built expressions for CodeGen. 7779 for (OMPClause *C : Clauses) { 7780 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7781 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7782 B.NumIterations, *this, CurScope, 7783 DSAStack)) 7784 return StmtError(); 7785 } 7786 } 7787 7788 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7789 return StmtError(); 7790 7791 setFunctionHasBranchProtectedScope(); 7792 return OMPDistributeParallelForSimdDirective::Create( 7793 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7794 } 7795 7796 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 7797 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7798 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7799 if (!AStmt) 7800 return StmtError(); 7801 7802 auto *CS = cast<CapturedStmt>(AStmt); 7803 // 1.2.2 OpenMP Language Terminology 7804 // Structured block - An executable statement with a single entry at the 7805 // top and a single exit at the bottom. 7806 // The point of exit cannot be a branch out of the structured block. 7807 // longjmp() and throw() must not violate the entry/exit criteria. 7808 CS->getCapturedDecl()->setNothrow(); 7809 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 7810 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7811 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7812 // 1.2.2 OpenMP Language Terminology 7813 // Structured block - An executable statement with a single entry at the 7814 // top and a single exit at the bottom. 7815 // The point of exit cannot be a branch out of the structured block. 7816 // longjmp() and throw() must not violate the entry/exit criteria. 7817 CS->getCapturedDecl()->setNothrow(); 7818 } 7819 7820 OMPLoopDirective::HelperExprs B; 7821 // In presence of clause 'collapse' with number of loops, it will 7822 // define the nested loops number. 7823 unsigned NestedLoopCount = 7824 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 7825 nullptr /*ordered not a clause on distribute*/, CS, *this, 7826 *DSAStack, VarsWithImplicitDSA, B); 7827 if (NestedLoopCount == 0) 7828 return StmtError(); 7829 7830 assert((CurContext->isDependentContext() || B.builtAll()) && 7831 "omp for loop exprs were not built"); 7832 7833 if (!CurContext->isDependentContext()) { 7834 // Finalize the clauses that need pre-built expressions for CodeGen. 7835 for (OMPClause *C : Clauses) { 7836 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7837 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7838 B.NumIterations, *this, CurScope, 7839 DSAStack)) 7840 return StmtError(); 7841 } 7842 } 7843 7844 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7845 return StmtError(); 7846 7847 setFunctionHasBranchProtectedScope(); 7848 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 7849 NestedLoopCount, Clauses, AStmt, B); 7850 } 7851 7852 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 7853 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7854 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7855 if (!AStmt) 7856 return StmtError(); 7857 7858 auto *CS = cast<CapturedStmt>(AStmt); 7859 // 1.2.2 OpenMP Language Terminology 7860 // Structured block - An executable statement with a single entry at the 7861 // top and a single exit at the bottom. 7862 // The point of exit cannot be a branch out of the structured block. 7863 // longjmp() and throw() must not violate the entry/exit criteria. 7864 CS->getCapturedDecl()->setNothrow(); 7865 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7866 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7867 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7868 // 1.2.2 OpenMP Language Terminology 7869 // Structured block - An executable statement with a single entry at the 7870 // top and a single exit at the bottom. 7871 // The point of exit cannot be a branch out of the structured block. 7872 // longjmp() and throw() must not violate the entry/exit criteria. 7873 CS->getCapturedDecl()->setNothrow(); 7874 } 7875 7876 OMPLoopDirective::HelperExprs B; 7877 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7878 // define the nested loops number. 7879 unsigned NestedLoopCount = checkOpenMPLoop( 7880 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 7881 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7882 VarsWithImplicitDSA, B); 7883 if (NestedLoopCount == 0) 7884 return StmtError(); 7885 7886 assert((CurContext->isDependentContext() || B.builtAll()) && 7887 "omp target parallel for simd loop exprs were not built"); 7888 7889 if (!CurContext->isDependentContext()) { 7890 // Finalize the clauses that need pre-built expressions for CodeGen. 7891 for (OMPClause *C : Clauses) { 7892 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7893 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7894 B.NumIterations, *this, CurScope, 7895 DSAStack)) 7896 return StmtError(); 7897 } 7898 } 7899 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7900 return StmtError(); 7901 7902 setFunctionHasBranchProtectedScope(); 7903 return OMPTargetParallelForSimdDirective::Create( 7904 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7905 } 7906 7907 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 7908 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7909 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7910 if (!AStmt) 7911 return StmtError(); 7912 7913 auto *CS = cast<CapturedStmt>(AStmt); 7914 // 1.2.2 OpenMP Language Terminology 7915 // Structured block - An executable statement with a single entry at the 7916 // top and a single exit at the bottom. 7917 // The point of exit cannot be a branch out of the structured block. 7918 // longjmp() and throw() must not violate the entry/exit criteria. 7919 CS->getCapturedDecl()->setNothrow(); 7920 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 7921 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7922 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7923 // 1.2.2 OpenMP Language Terminology 7924 // Structured block - An executable statement with a single entry at the 7925 // top and a single exit at the bottom. 7926 // The point of exit cannot be a branch out of the structured block. 7927 // longjmp() and throw() must not violate the entry/exit criteria. 7928 CS->getCapturedDecl()->setNothrow(); 7929 } 7930 7931 OMPLoopDirective::HelperExprs B; 7932 // In presence of clause 'collapse' with number of loops, it will define the 7933 // nested loops number. 7934 unsigned NestedLoopCount = 7935 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 7936 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7937 VarsWithImplicitDSA, B); 7938 if (NestedLoopCount == 0) 7939 return StmtError(); 7940 7941 assert((CurContext->isDependentContext() || B.builtAll()) && 7942 "omp target simd loop exprs were not built"); 7943 7944 if (!CurContext->isDependentContext()) { 7945 // Finalize the clauses that need pre-built expressions for CodeGen. 7946 for (OMPClause *C : Clauses) { 7947 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7948 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7949 B.NumIterations, *this, CurScope, 7950 DSAStack)) 7951 return StmtError(); 7952 } 7953 } 7954 7955 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7956 return StmtError(); 7957 7958 setFunctionHasBranchProtectedScope(); 7959 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 7960 NestedLoopCount, Clauses, AStmt, B); 7961 } 7962 7963 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 7964 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7965 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7966 if (!AStmt) 7967 return StmtError(); 7968 7969 auto *CS = cast<CapturedStmt>(AStmt); 7970 // 1.2.2 OpenMP Language Terminology 7971 // Structured block - An executable statement with a single entry at the 7972 // top and a single exit at the bottom. 7973 // The point of exit cannot be a branch out of the structured block. 7974 // longjmp() and throw() must not violate the entry/exit criteria. 7975 CS->getCapturedDecl()->setNothrow(); 7976 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 7977 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7978 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7979 // 1.2.2 OpenMP Language Terminology 7980 // Structured block - An executable statement with a single entry at the 7981 // top and a single exit at the bottom. 7982 // The point of exit cannot be a branch out of the structured block. 7983 // longjmp() and throw() must not violate the entry/exit criteria. 7984 CS->getCapturedDecl()->setNothrow(); 7985 } 7986 7987 OMPLoopDirective::HelperExprs B; 7988 // In presence of clause 'collapse' with number of loops, it will 7989 // define the nested loops number. 7990 unsigned NestedLoopCount = 7991 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 7992 nullptr /*ordered not a clause on distribute*/, CS, *this, 7993 *DSAStack, VarsWithImplicitDSA, B); 7994 if (NestedLoopCount == 0) 7995 return StmtError(); 7996 7997 assert((CurContext->isDependentContext() || B.builtAll()) && 7998 "omp teams distribute loop exprs were not built"); 7999 8000 setFunctionHasBranchProtectedScope(); 8001 8002 DSAStack->setParentTeamsRegionLoc(StartLoc); 8003 8004 return OMPTeamsDistributeDirective::Create( 8005 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8006 } 8007 8008 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8009 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8010 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8011 if (!AStmt) 8012 return StmtError(); 8013 8014 auto *CS = cast<CapturedStmt>(AStmt); 8015 // 1.2.2 OpenMP Language Terminology 8016 // Structured block - An executable statement with a single entry at the 8017 // top and a single exit at the bottom. 8018 // The point of exit cannot be a branch out of the structured block. 8019 // longjmp() and throw() must not violate the entry/exit criteria. 8020 CS->getCapturedDecl()->setNothrow(); 8021 for (int ThisCaptureLevel = 8022 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8023 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8024 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8025 // 1.2.2 OpenMP Language Terminology 8026 // Structured block - An executable statement with a single entry at the 8027 // top and a single exit at the bottom. 8028 // The point of exit cannot be a branch out of the structured block. 8029 // longjmp() and throw() must not violate the entry/exit criteria. 8030 CS->getCapturedDecl()->setNothrow(); 8031 } 8032 8033 8034 OMPLoopDirective::HelperExprs B; 8035 // In presence of clause 'collapse' with number of loops, it will 8036 // define the nested loops number. 8037 unsigned NestedLoopCount = checkOpenMPLoop( 8038 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8039 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8040 VarsWithImplicitDSA, B); 8041 8042 if (NestedLoopCount == 0) 8043 return StmtError(); 8044 8045 assert((CurContext->isDependentContext() || B.builtAll()) && 8046 "omp teams distribute simd loop exprs were not built"); 8047 8048 if (!CurContext->isDependentContext()) { 8049 // Finalize the clauses that need pre-built expressions for CodeGen. 8050 for (OMPClause *C : Clauses) { 8051 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8052 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8053 B.NumIterations, *this, CurScope, 8054 DSAStack)) 8055 return StmtError(); 8056 } 8057 } 8058 8059 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8060 return StmtError(); 8061 8062 setFunctionHasBranchProtectedScope(); 8063 8064 DSAStack->setParentTeamsRegionLoc(StartLoc); 8065 8066 return OMPTeamsDistributeSimdDirective::Create( 8067 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8068 } 8069 8070 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8071 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8072 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8073 if (!AStmt) 8074 return StmtError(); 8075 8076 auto *CS = cast<CapturedStmt>(AStmt); 8077 // 1.2.2 OpenMP Language Terminology 8078 // Structured block - An executable statement with a single entry at the 8079 // top and a single exit at the bottom. 8080 // The point of exit cannot be a branch out of the structured block. 8081 // longjmp() and throw() must not violate the entry/exit criteria. 8082 CS->getCapturedDecl()->setNothrow(); 8083 8084 for (int ThisCaptureLevel = 8085 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8086 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8087 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8088 // 1.2.2 OpenMP Language Terminology 8089 // Structured block - An executable statement with a single entry at the 8090 // top and a single exit at the bottom. 8091 // The point of exit cannot be a branch out of the structured block. 8092 // longjmp() and throw() must not violate the entry/exit criteria. 8093 CS->getCapturedDecl()->setNothrow(); 8094 } 8095 8096 OMPLoopDirective::HelperExprs B; 8097 // In presence of clause 'collapse' with number of loops, it will 8098 // define the nested loops number. 8099 unsigned NestedLoopCount = checkOpenMPLoop( 8100 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8101 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8102 VarsWithImplicitDSA, B); 8103 8104 if (NestedLoopCount == 0) 8105 return StmtError(); 8106 8107 assert((CurContext->isDependentContext() || B.builtAll()) && 8108 "omp for loop exprs were not built"); 8109 8110 if (!CurContext->isDependentContext()) { 8111 // Finalize the clauses that need pre-built expressions for CodeGen. 8112 for (OMPClause *C : Clauses) { 8113 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8114 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8115 B.NumIterations, *this, CurScope, 8116 DSAStack)) 8117 return StmtError(); 8118 } 8119 } 8120 8121 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8122 return StmtError(); 8123 8124 setFunctionHasBranchProtectedScope(); 8125 8126 DSAStack->setParentTeamsRegionLoc(StartLoc); 8127 8128 return OMPTeamsDistributeParallelForSimdDirective::Create( 8129 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8130 } 8131 8132 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8133 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8134 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8135 if (!AStmt) 8136 return StmtError(); 8137 8138 auto *CS = cast<CapturedStmt>(AStmt); 8139 // 1.2.2 OpenMP Language Terminology 8140 // Structured block - An executable statement with a single entry at the 8141 // top and a single exit at the bottom. 8142 // The point of exit cannot be a branch out of the structured block. 8143 // longjmp() and throw() must not violate the entry/exit criteria. 8144 CS->getCapturedDecl()->setNothrow(); 8145 8146 for (int ThisCaptureLevel = 8147 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8148 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8149 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8150 // 1.2.2 OpenMP Language Terminology 8151 // Structured block - An executable statement with a single entry at the 8152 // top and a single exit at the bottom. 8153 // The point of exit cannot be a branch out of the structured block. 8154 // longjmp() and throw() must not violate the entry/exit criteria. 8155 CS->getCapturedDecl()->setNothrow(); 8156 } 8157 8158 OMPLoopDirective::HelperExprs B; 8159 // In presence of clause 'collapse' with number of loops, it will 8160 // define the nested loops number. 8161 unsigned NestedLoopCount = checkOpenMPLoop( 8162 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8163 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8164 VarsWithImplicitDSA, B); 8165 8166 if (NestedLoopCount == 0) 8167 return StmtError(); 8168 8169 assert((CurContext->isDependentContext() || B.builtAll()) && 8170 "omp for loop exprs were not built"); 8171 8172 setFunctionHasBranchProtectedScope(); 8173 8174 DSAStack->setParentTeamsRegionLoc(StartLoc); 8175 8176 return OMPTeamsDistributeParallelForDirective::Create( 8177 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8178 DSAStack->isCancelRegion()); 8179 } 8180 8181 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8182 Stmt *AStmt, 8183 SourceLocation StartLoc, 8184 SourceLocation EndLoc) { 8185 if (!AStmt) 8186 return StmtError(); 8187 8188 auto *CS = cast<CapturedStmt>(AStmt); 8189 // 1.2.2 OpenMP Language Terminology 8190 // Structured block - An executable statement with a single entry at the 8191 // top and a single exit at the bottom. 8192 // The point of exit cannot be a branch out of the structured block. 8193 // longjmp() and throw() must not violate the entry/exit criteria. 8194 CS->getCapturedDecl()->setNothrow(); 8195 8196 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8197 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8198 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8199 // 1.2.2 OpenMP Language Terminology 8200 // Structured block - An executable statement with a single entry at the 8201 // top and a single exit at the bottom. 8202 // The point of exit cannot be a branch out of the structured block. 8203 // longjmp() and throw() must not violate the entry/exit criteria. 8204 CS->getCapturedDecl()->setNothrow(); 8205 } 8206 setFunctionHasBranchProtectedScope(); 8207 8208 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8209 AStmt); 8210 } 8211 8212 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8213 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8214 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8215 if (!AStmt) 8216 return StmtError(); 8217 8218 auto *CS = cast<CapturedStmt>(AStmt); 8219 // 1.2.2 OpenMP Language Terminology 8220 // Structured block - An executable statement with a single entry at the 8221 // top and a single exit at the bottom. 8222 // The point of exit cannot be a branch out of the structured block. 8223 // longjmp() and throw() must not violate the entry/exit criteria. 8224 CS->getCapturedDecl()->setNothrow(); 8225 for (int ThisCaptureLevel = 8226 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8227 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8228 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8229 // 1.2.2 OpenMP Language Terminology 8230 // Structured block - An executable statement with a single entry at the 8231 // top and a single exit at the bottom. 8232 // The point of exit cannot be a branch out of the structured block. 8233 // longjmp() and throw() must not violate the entry/exit criteria. 8234 CS->getCapturedDecl()->setNothrow(); 8235 } 8236 8237 OMPLoopDirective::HelperExprs B; 8238 // In presence of clause 'collapse' with number of loops, it will 8239 // define the nested loops number. 8240 unsigned NestedLoopCount = checkOpenMPLoop( 8241 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8242 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8243 VarsWithImplicitDSA, B); 8244 if (NestedLoopCount == 0) 8245 return StmtError(); 8246 8247 assert((CurContext->isDependentContext() || B.builtAll()) && 8248 "omp target teams distribute loop exprs were not built"); 8249 8250 setFunctionHasBranchProtectedScope(); 8251 return OMPTargetTeamsDistributeDirective::Create( 8252 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8253 } 8254 8255 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8256 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8257 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8258 if (!AStmt) 8259 return StmtError(); 8260 8261 auto *CS = cast<CapturedStmt>(AStmt); 8262 // 1.2.2 OpenMP Language Terminology 8263 // Structured block - An executable statement with a single entry at the 8264 // top and a single exit at the bottom. 8265 // The point of exit cannot be a branch out of the structured block. 8266 // longjmp() and throw() must not violate the entry/exit criteria. 8267 CS->getCapturedDecl()->setNothrow(); 8268 for (int ThisCaptureLevel = 8269 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8270 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8271 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8272 // 1.2.2 OpenMP Language Terminology 8273 // Structured block - An executable statement with a single entry at the 8274 // top and a single exit at the bottom. 8275 // The point of exit cannot be a branch out of the structured block. 8276 // longjmp() and throw() must not violate the entry/exit criteria. 8277 CS->getCapturedDecl()->setNothrow(); 8278 } 8279 8280 OMPLoopDirective::HelperExprs B; 8281 // In presence of clause 'collapse' with number of loops, it will 8282 // define the nested loops number. 8283 unsigned NestedLoopCount = checkOpenMPLoop( 8284 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8285 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8286 VarsWithImplicitDSA, B); 8287 if (NestedLoopCount == 0) 8288 return StmtError(); 8289 8290 assert((CurContext->isDependentContext() || B.builtAll()) && 8291 "omp target teams distribute parallel for loop exprs were not built"); 8292 8293 if (!CurContext->isDependentContext()) { 8294 // Finalize the clauses that need pre-built expressions for CodeGen. 8295 for (OMPClause *C : Clauses) { 8296 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8297 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8298 B.NumIterations, *this, CurScope, 8299 DSAStack)) 8300 return StmtError(); 8301 } 8302 } 8303 8304 setFunctionHasBranchProtectedScope(); 8305 return OMPTargetTeamsDistributeParallelForDirective::Create( 8306 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8307 DSAStack->isCancelRegion()); 8308 } 8309 8310 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 8311 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8312 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8313 if (!AStmt) 8314 return StmtError(); 8315 8316 auto *CS = cast<CapturedStmt>(AStmt); 8317 // 1.2.2 OpenMP Language Terminology 8318 // Structured block - An executable statement with a single entry at the 8319 // top and a single exit at the bottom. 8320 // The point of exit cannot be a branch out of the structured block. 8321 // longjmp() and throw() must not violate the entry/exit criteria. 8322 CS->getCapturedDecl()->setNothrow(); 8323 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 8324 OMPD_target_teams_distribute_parallel_for_simd); 8325 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8326 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8327 // 1.2.2 OpenMP Language Terminology 8328 // Structured block - An executable statement with a single entry at the 8329 // top and a single exit at the bottom. 8330 // The point of exit cannot be a branch out of the structured block. 8331 // longjmp() and throw() must not violate the entry/exit criteria. 8332 CS->getCapturedDecl()->setNothrow(); 8333 } 8334 8335 OMPLoopDirective::HelperExprs B; 8336 // In presence of clause 'collapse' with number of loops, it will 8337 // define the nested loops number. 8338 unsigned NestedLoopCount = 8339 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 8340 getCollapseNumberExpr(Clauses), 8341 nullptr /*ordered not a clause on distribute*/, CS, *this, 8342 *DSAStack, VarsWithImplicitDSA, B); 8343 if (NestedLoopCount == 0) 8344 return StmtError(); 8345 8346 assert((CurContext->isDependentContext() || B.builtAll()) && 8347 "omp target teams distribute parallel for simd loop exprs were not " 8348 "built"); 8349 8350 if (!CurContext->isDependentContext()) { 8351 // Finalize the clauses that need pre-built expressions for CodeGen. 8352 for (OMPClause *C : Clauses) { 8353 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8354 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8355 B.NumIterations, *this, CurScope, 8356 DSAStack)) 8357 return StmtError(); 8358 } 8359 } 8360 8361 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8362 return StmtError(); 8363 8364 setFunctionHasBranchProtectedScope(); 8365 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 8366 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8367 } 8368 8369 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 8370 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8371 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8372 if (!AStmt) 8373 return StmtError(); 8374 8375 auto *CS = cast<CapturedStmt>(AStmt); 8376 // 1.2.2 OpenMP Language Terminology 8377 // Structured block - An executable statement with a single entry at the 8378 // top and a single exit at the bottom. 8379 // The point of exit cannot be a branch out of the structured block. 8380 // longjmp() and throw() must not violate the entry/exit criteria. 8381 CS->getCapturedDecl()->setNothrow(); 8382 for (int ThisCaptureLevel = 8383 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 8384 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8385 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8386 // 1.2.2 OpenMP Language Terminology 8387 // Structured block - An executable statement with a single entry at the 8388 // top and a single exit at the bottom. 8389 // The point of exit cannot be a branch out of the structured block. 8390 // longjmp() and throw() must not violate the entry/exit criteria. 8391 CS->getCapturedDecl()->setNothrow(); 8392 } 8393 8394 OMPLoopDirective::HelperExprs B; 8395 // In presence of clause 'collapse' with number of loops, it will 8396 // define the nested loops number. 8397 unsigned NestedLoopCount = checkOpenMPLoop( 8398 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8399 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8400 VarsWithImplicitDSA, B); 8401 if (NestedLoopCount == 0) 8402 return StmtError(); 8403 8404 assert((CurContext->isDependentContext() || B.builtAll()) && 8405 "omp target teams distribute simd loop exprs were not built"); 8406 8407 if (!CurContext->isDependentContext()) { 8408 // Finalize the clauses that need pre-built expressions for CodeGen. 8409 for (OMPClause *C : Clauses) { 8410 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8411 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8412 B.NumIterations, *this, CurScope, 8413 DSAStack)) 8414 return StmtError(); 8415 } 8416 } 8417 8418 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8419 return StmtError(); 8420 8421 setFunctionHasBranchProtectedScope(); 8422 return OMPTargetTeamsDistributeSimdDirective::Create( 8423 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8424 } 8425 8426 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 8427 SourceLocation StartLoc, 8428 SourceLocation LParenLoc, 8429 SourceLocation EndLoc) { 8430 OMPClause *Res = nullptr; 8431 switch (Kind) { 8432 case OMPC_final: 8433 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 8434 break; 8435 case OMPC_num_threads: 8436 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 8437 break; 8438 case OMPC_safelen: 8439 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 8440 break; 8441 case OMPC_simdlen: 8442 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 8443 break; 8444 case OMPC_allocator: 8445 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 8446 break; 8447 case OMPC_collapse: 8448 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 8449 break; 8450 case OMPC_ordered: 8451 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 8452 break; 8453 case OMPC_device: 8454 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 8455 break; 8456 case OMPC_num_teams: 8457 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 8458 break; 8459 case OMPC_thread_limit: 8460 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 8461 break; 8462 case OMPC_priority: 8463 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 8464 break; 8465 case OMPC_grainsize: 8466 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 8467 break; 8468 case OMPC_num_tasks: 8469 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 8470 break; 8471 case OMPC_hint: 8472 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 8473 break; 8474 case OMPC_if: 8475 case OMPC_default: 8476 case OMPC_proc_bind: 8477 case OMPC_schedule: 8478 case OMPC_private: 8479 case OMPC_firstprivate: 8480 case OMPC_lastprivate: 8481 case OMPC_shared: 8482 case OMPC_reduction: 8483 case OMPC_task_reduction: 8484 case OMPC_in_reduction: 8485 case OMPC_linear: 8486 case OMPC_aligned: 8487 case OMPC_copyin: 8488 case OMPC_copyprivate: 8489 case OMPC_nowait: 8490 case OMPC_untied: 8491 case OMPC_mergeable: 8492 case OMPC_threadprivate: 8493 case OMPC_allocate: 8494 case OMPC_flush: 8495 case OMPC_read: 8496 case OMPC_write: 8497 case OMPC_update: 8498 case OMPC_capture: 8499 case OMPC_seq_cst: 8500 case OMPC_depend: 8501 case OMPC_threads: 8502 case OMPC_simd: 8503 case OMPC_map: 8504 case OMPC_nogroup: 8505 case OMPC_dist_schedule: 8506 case OMPC_defaultmap: 8507 case OMPC_unknown: 8508 case OMPC_uniform: 8509 case OMPC_to: 8510 case OMPC_from: 8511 case OMPC_use_device_ptr: 8512 case OMPC_is_device_ptr: 8513 case OMPC_unified_address: 8514 case OMPC_unified_shared_memory: 8515 case OMPC_reverse_offload: 8516 case OMPC_dynamic_allocators: 8517 case OMPC_atomic_default_mem_order: 8518 llvm_unreachable("Clause is not allowed."); 8519 } 8520 return Res; 8521 } 8522 8523 // An OpenMP directive such as 'target parallel' has two captured regions: 8524 // for the 'target' and 'parallel' respectively. This function returns 8525 // the region in which to capture expressions associated with a clause. 8526 // A return value of OMPD_unknown signifies that the expression should not 8527 // be captured. 8528 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 8529 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 8530 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 8531 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8532 switch (CKind) { 8533 case OMPC_if: 8534 switch (DKind) { 8535 case OMPD_target_parallel: 8536 case OMPD_target_parallel_for: 8537 case OMPD_target_parallel_for_simd: 8538 // If this clause applies to the nested 'parallel' region, capture within 8539 // the 'target' region, otherwise do not capture. 8540 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8541 CaptureRegion = OMPD_target; 8542 break; 8543 case OMPD_target_teams_distribute_parallel_for: 8544 case OMPD_target_teams_distribute_parallel_for_simd: 8545 // If this clause applies to the nested 'parallel' region, capture within 8546 // the 'teams' region, otherwise do not capture. 8547 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8548 CaptureRegion = OMPD_teams; 8549 break; 8550 case OMPD_teams_distribute_parallel_for: 8551 case OMPD_teams_distribute_parallel_for_simd: 8552 CaptureRegion = OMPD_teams; 8553 break; 8554 case OMPD_target_update: 8555 case OMPD_target_enter_data: 8556 case OMPD_target_exit_data: 8557 CaptureRegion = OMPD_task; 8558 break; 8559 case OMPD_cancel: 8560 case OMPD_parallel: 8561 case OMPD_parallel_sections: 8562 case OMPD_parallel_for: 8563 case OMPD_parallel_for_simd: 8564 case OMPD_target: 8565 case OMPD_target_simd: 8566 case OMPD_target_teams: 8567 case OMPD_target_teams_distribute: 8568 case OMPD_target_teams_distribute_simd: 8569 case OMPD_distribute_parallel_for: 8570 case OMPD_distribute_parallel_for_simd: 8571 case OMPD_task: 8572 case OMPD_taskloop: 8573 case OMPD_taskloop_simd: 8574 case OMPD_target_data: 8575 // Do not capture if-clause expressions. 8576 break; 8577 case OMPD_threadprivate: 8578 case OMPD_allocate: 8579 case OMPD_taskyield: 8580 case OMPD_barrier: 8581 case OMPD_taskwait: 8582 case OMPD_cancellation_point: 8583 case OMPD_flush: 8584 case OMPD_declare_reduction: 8585 case OMPD_declare_mapper: 8586 case OMPD_declare_simd: 8587 case OMPD_declare_target: 8588 case OMPD_end_declare_target: 8589 case OMPD_teams: 8590 case OMPD_simd: 8591 case OMPD_for: 8592 case OMPD_for_simd: 8593 case OMPD_sections: 8594 case OMPD_section: 8595 case OMPD_single: 8596 case OMPD_master: 8597 case OMPD_critical: 8598 case OMPD_taskgroup: 8599 case OMPD_distribute: 8600 case OMPD_ordered: 8601 case OMPD_atomic: 8602 case OMPD_distribute_simd: 8603 case OMPD_teams_distribute: 8604 case OMPD_teams_distribute_simd: 8605 case OMPD_requires: 8606 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 8607 case OMPD_unknown: 8608 llvm_unreachable("Unknown OpenMP directive"); 8609 } 8610 break; 8611 case OMPC_num_threads: 8612 switch (DKind) { 8613 case OMPD_target_parallel: 8614 case OMPD_target_parallel_for: 8615 case OMPD_target_parallel_for_simd: 8616 CaptureRegion = OMPD_target; 8617 break; 8618 case OMPD_teams_distribute_parallel_for: 8619 case OMPD_teams_distribute_parallel_for_simd: 8620 case OMPD_target_teams_distribute_parallel_for: 8621 case OMPD_target_teams_distribute_parallel_for_simd: 8622 CaptureRegion = OMPD_teams; 8623 break; 8624 case OMPD_parallel: 8625 case OMPD_parallel_sections: 8626 case OMPD_parallel_for: 8627 case OMPD_parallel_for_simd: 8628 case OMPD_distribute_parallel_for: 8629 case OMPD_distribute_parallel_for_simd: 8630 // Do not capture num_threads-clause expressions. 8631 break; 8632 case OMPD_target_data: 8633 case OMPD_target_enter_data: 8634 case OMPD_target_exit_data: 8635 case OMPD_target_update: 8636 case OMPD_target: 8637 case OMPD_target_simd: 8638 case OMPD_target_teams: 8639 case OMPD_target_teams_distribute: 8640 case OMPD_target_teams_distribute_simd: 8641 case OMPD_cancel: 8642 case OMPD_task: 8643 case OMPD_taskloop: 8644 case OMPD_taskloop_simd: 8645 case OMPD_threadprivate: 8646 case OMPD_allocate: 8647 case OMPD_taskyield: 8648 case OMPD_barrier: 8649 case OMPD_taskwait: 8650 case OMPD_cancellation_point: 8651 case OMPD_flush: 8652 case OMPD_declare_reduction: 8653 case OMPD_declare_mapper: 8654 case OMPD_declare_simd: 8655 case OMPD_declare_target: 8656 case OMPD_end_declare_target: 8657 case OMPD_teams: 8658 case OMPD_simd: 8659 case OMPD_for: 8660 case OMPD_for_simd: 8661 case OMPD_sections: 8662 case OMPD_section: 8663 case OMPD_single: 8664 case OMPD_master: 8665 case OMPD_critical: 8666 case OMPD_taskgroup: 8667 case OMPD_distribute: 8668 case OMPD_ordered: 8669 case OMPD_atomic: 8670 case OMPD_distribute_simd: 8671 case OMPD_teams_distribute: 8672 case OMPD_teams_distribute_simd: 8673 case OMPD_requires: 8674 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 8675 case OMPD_unknown: 8676 llvm_unreachable("Unknown OpenMP directive"); 8677 } 8678 break; 8679 case OMPC_num_teams: 8680 switch (DKind) { 8681 case OMPD_target_teams: 8682 case OMPD_target_teams_distribute: 8683 case OMPD_target_teams_distribute_simd: 8684 case OMPD_target_teams_distribute_parallel_for: 8685 case OMPD_target_teams_distribute_parallel_for_simd: 8686 CaptureRegion = OMPD_target; 8687 break; 8688 case OMPD_teams_distribute_parallel_for: 8689 case OMPD_teams_distribute_parallel_for_simd: 8690 case OMPD_teams: 8691 case OMPD_teams_distribute: 8692 case OMPD_teams_distribute_simd: 8693 // Do not capture num_teams-clause expressions. 8694 break; 8695 case OMPD_distribute_parallel_for: 8696 case OMPD_distribute_parallel_for_simd: 8697 case OMPD_task: 8698 case OMPD_taskloop: 8699 case OMPD_taskloop_simd: 8700 case OMPD_target_data: 8701 case OMPD_target_enter_data: 8702 case OMPD_target_exit_data: 8703 case OMPD_target_update: 8704 case OMPD_cancel: 8705 case OMPD_parallel: 8706 case OMPD_parallel_sections: 8707 case OMPD_parallel_for: 8708 case OMPD_parallel_for_simd: 8709 case OMPD_target: 8710 case OMPD_target_simd: 8711 case OMPD_target_parallel: 8712 case OMPD_target_parallel_for: 8713 case OMPD_target_parallel_for_simd: 8714 case OMPD_threadprivate: 8715 case OMPD_allocate: 8716 case OMPD_taskyield: 8717 case OMPD_barrier: 8718 case OMPD_taskwait: 8719 case OMPD_cancellation_point: 8720 case OMPD_flush: 8721 case OMPD_declare_reduction: 8722 case OMPD_declare_mapper: 8723 case OMPD_declare_simd: 8724 case OMPD_declare_target: 8725 case OMPD_end_declare_target: 8726 case OMPD_simd: 8727 case OMPD_for: 8728 case OMPD_for_simd: 8729 case OMPD_sections: 8730 case OMPD_section: 8731 case OMPD_single: 8732 case OMPD_master: 8733 case OMPD_critical: 8734 case OMPD_taskgroup: 8735 case OMPD_distribute: 8736 case OMPD_ordered: 8737 case OMPD_atomic: 8738 case OMPD_distribute_simd: 8739 case OMPD_requires: 8740 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8741 case OMPD_unknown: 8742 llvm_unreachable("Unknown OpenMP directive"); 8743 } 8744 break; 8745 case OMPC_thread_limit: 8746 switch (DKind) { 8747 case OMPD_target_teams: 8748 case OMPD_target_teams_distribute: 8749 case OMPD_target_teams_distribute_simd: 8750 case OMPD_target_teams_distribute_parallel_for: 8751 case OMPD_target_teams_distribute_parallel_for_simd: 8752 CaptureRegion = OMPD_target; 8753 break; 8754 case OMPD_teams_distribute_parallel_for: 8755 case OMPD_teams_distribute_parallel_for_simd: 8756 case OMPD_teams: 8757 case OMPD_teams_distribute: 8758 case OMPD_teams_distribute_simd: 8759 // Do not capture thread_limit-clause expressions. 8760 break; 8761 case OMPD_distribute_parallel_for: 8762 case OMPD_distribute_parallel_for_simd: 8763 case OMPD_task: 8764 case OMPD_taskloop: 8765 case OMPD_taskloop_simd: 8766 case OMPD_target_data: 8767 case OMPD_target_enter_data: 8768 case OMPD_target_exit_data: 8769 case OMPD_target_update: 8770 case OMPD_cancel: 8771 case OMPD_parallel: 8772 case OMPD_parallel_sections: 8773 case OMPD_parallel_for: 8774 case OMPD_parallel_for_simd: 8775 case OMPD_target: 8776 case OMPD_target_simd: 8777 case OMPD_target_parallel: 8778 case OMPD_target_parallel_for: 8779 case OMPD_target_parallel_for_simd: 8780 case OMPD_threadprivate: 8781 case OMPD_allocate: 8782 case OMPD_taskyield: 8783 case OMPD_barrier: 8784 case OMPD_taskwait: 8785 case OMPD_cancellation_point: 8786 case OMPD_flush: 8787 case OMPD_declare_reduction: 8788 case OMPD_declare_mapper: 8789 case OMPD_declare_simd: 8790 case OMPD_declare_target: 8791 case OMPD_end_declare_target: 8792 case OMPD_simd: 8793 case OMPD_for: 8794 case OMPD_for_simd: 8795 case OMPD_sections: 8796 case OMPD_section: 8797 case OMPD_single: 8798 case OMPD_master: 8799 case OMPD_critical: 8800 case OMPD_taskgroup: 8801 case OMPD_distribute: 8802 case OMPD_ordered: 8803 case OMPD_atomic: 8804 case OMPD_distribute_simd: 8805 case OMPD_requires: 8806 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 8807 case OMPD_unknown: 8808 llvm_unreachable("Unknown OpenMP directive"); 8809 } 8810 break; 8811 case OMPC_schedule: 8812 switch (DKind) { 8813 case OMPD_parallel_for: 8814 case OMPD_parallel_for_simd: 8815 case OMPD_distribute_parallel_for: 8816 case OMPD_distribute_parallel_for_simd: 8817 case OMPD_teams_distribute_parallel_for: 8818 case OMPD_teams_distribute_parallel_for_simd: 8819 case OMPD_target_parallel_for: 8820 case OMPD_target_parallel_for_simd: 8821 case OMPD_target_teams_distribute_parallel_for: 8822 case OMPD_target_teams_distribute_parallel_for_simd: 8823 CaptureRegion = OMPD_parallel; 8824 break; 8825 case OMPD_for: 8826 case OMPD_for_simd: 8827 // Do not capture schedule-clause expressions. 8828 break; 8829 case OMPD_task: 8830 case OMPD_taskloop: 8831 case OMPD_taskloop_simd: 8832 case OMPD_target_data: 8833 case OMPD_target_enter_data: 8834 case OMPD_target_exit_data: 8835 case OMPD_target_update: 8836 case OMPD_teams: 8837 case OMPD_teams_distribute: 8838 case OMPD_teams_distribute_simd: 8839 case OMPD_target_teams_distribute: 8840 case OMPD_target_teams_distribute_simd: 8841 case OMPD_target: 8842 case OMPD_target_simd: 8843 case OMPD_target_parallel: 8844 case OMPD_cancel: 8845 case OMPD_parallel: 8846 case OMPD_parallel_sections: 8847 case OMPD_threadprivate: 8848 case OMPD_allocate: 8849 case OMPD_taskyield: 8850 case OMPD_barrier: 8851 case OMPD_taskwait: 8852 case OMPD_cancellation_point: 8853 case OMPD_flush: 8854 case OMPD_declare_reduction: 8855 case OMPD_declare_mapper: 8856 case OMPD_declare_simd: 8857 case OMPD_declare_target: 8858 case OMPD_end_declare_target: 8859 case OMPD_simd: 8860 case OMPD_sections: 8861 case OMPD_section: 8862 case OMPD_single: 8863 case OMPD_master: 8864 case OMPD_critical: 8865 case OMPD_taskgroup: 8866 case OMPD_distribute: 8867 case OMPD_ordered: 8868 case OMPD_atomic: 8869 case OMPD_distribute_simd: 8870 case OMPD_target_teams: 8871 case OMPD_requires: 8872 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8873 case OMPD_unknown: 8874 llvm_unreachable("Unknown OpenMP directive"); 8875 } 8876 break; 8877 case OMPC_dist_schedule: 8878 switch (DKind) { 8879 case OMPD_teams_distribute_parallel_for: 8880 case OMPD_teams_distribute_parallel_for_simd: 8881 case OMPD_teams_distribute: 8882 case OMPD_teams_distribute_simd: 8883 case OMPD_target_teams_distribute_parallel_for: 8884 case OMPD_target_teams_distribute_parallel_for_simd: 8885 case OMPD_target_teams_distribute: 8886 case OMPD_target_teams_distribute_simd: 8887 CaptureRegion = OMPD_teams; 8888 break; 8889 case OMPD_distribute_parallel_for: 8890 case OMPD_distribute_parallel_for_simd: 8891 case OMPD_distribute: 8892 case OMPD_distribute_simd: 8893 // Do not capture thread_limit-clause expressions. 8894 break; 8895 case OMPD_parallel_for: 8896 case OMPD_parallel_for_simd: 8897 case OMPD_target_parallel_for_simd: 8898 case OMPD_target_parallel_for: 8899 case OMPD_task: 8900 case OMPD_taskloop: 8901 case OMPD_taskloop_simd: 8902 case OMPD_target_data: 8903 case OMPD_target_enter_data: 8904 case OMPD_target_exit_data: 8905 case OMPD_target_update: 8906 case OMPD_teams: 8907 case OMPD_target: 8908 case OMPD_target_simd: 8909 case OMPD_target_parallel: 8910 case OMPD_cancel: 8911 case OMPD_parallel: 8912 case OMPD_parallel_sections: 8913 case OMPD_threadprivate: 8914 case OMPD_allocate: 8915 case OMPD_taskyield: 8916 case OMPD_barrier: 8917 case OMPD_taskwait: 8918 case OMPD_cancellation_point: 8919 case OMPD_flush: 8920 case OMPD_declare_reduction: 8921 case OMPD_declare_mapper: 8922 case OMPD_declare_simd: 8923 case OMPD_declare_target: 8924 case OMPD_end_declare_target: 8925 case OMPD_simd: 8926 case OMPD_for: 8927 case OMPD_for_simd: 8928 case OMPD_sections: 8929 case OMPD_section: 8930 case OMPD_single: 8931 case OMPD_master: 8932 case OMPD_critical: 8933 case OMPD_taskgroup: 8934 case OMPD_ordered: 8935 case OMPD_atomic: 8936 case OMPD_target_teams: 8937 case OMPD_requires: 8938 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8939 case OMPD_unknown: 8940 llvm_unreachable("Unknown OpenMP directive"); 8941 } 8942 break; 8943 case OMPC_device: 8944 switch (DKind) { 8945 case OMPD_target_update: 8946 case OMPD_target_enter_data: 8947 case OMPD_target_exit_data: 8948 case OMPD_target: 8949 case OMPD_target_simd: 8950 case OMPD_target_teams: 8951 case OMPD_target_parallel: 8952 case OMPD_target_teams_distribute: 8953 case OMPD_target_teams_distribute_simd: 8954 case OMPD_target_parallel_for: 8955 case OMPD_target_parallel_for_simd: 8956 case OMPD_target_teams_distribute_parallel_for: 8957 case OMPD_target_teams_distribute_parallel_for_simd: 8958 CaptureRegion = OMPD_task; 8959 break; 8960 case OMPD_target_data: 8961 // Do not capture device-clause expressions. 8962 break; 8963 case OMPD_teams_distribute_parallel_for: 8964 case OMPD_teams_distribute_parallel_for_simd: 8965 case OMPD_teams: 8966 case OMPD_teams_distribute: 8967 case OMPD_teams_distribute_simd: 8968 case OMPD_distribute_parallel_for: 8969 case OMPD_distribute_parallel_for_simd: 8970 case OMPD_task: 8971 case OMPD_taskloop: 8972 case OMPD_taskloop_simd: 8973 case OMPD_cancel: 8974 case OMPD_parallel: 8975 case OMPD_parallel_sections: 8976 case OMPD_parallel_for: 8977 case OMPD_parallel_for_simd: 8978 case OMPD_threadprivate: 8979 case OMPD_allocate: 8980 case OMPD_taskyield: 8981 case OMPD_barrier: 8982 case OMPD_taskwait: 8983 case OMPD_cancellation_point: 8984 case OMPD_flush: 8985 case OMPD_declare_reduction: 8986 case OMPD_declare_mapper: 8987 case OMPD_declare_simd: 8988 case OMPD_declare_target: 8989 case OMPD_end_declare_target: 8990 case OMPD_simd: 8991 case OMPD_for: 8992 case OMPD_for_simd: 8993 case OMPD_sections: 8994 case OMPD_section: 8995 case OMPD_single: 8996 case OMPD_master: 8997 case OMPD_critical: 8998 case OMPD_taskgroup: 8999 case OMPD_distribute: 9000 case OMPD_ordered: 9001 case OMPD_atomic: 9002 case OMPD_distribute_simd: 9003 case OMPD_requires: 9004 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9005 case OMPD_unknown: 9006 llvm_unreachable("Unknown OpenMP directive"); 9007 } 9008 break; 9009 case OMPC_firstprivate: 9010 case OMPC_lastprivate: 9011 case OMPC_reduction: 9012 case OMPC_task_reduction: 9013 case OMPC_in_reduction: 9014 case OMPC_linear: 9015 case OMPC_default: 9016 case OMPC_proc_bind: 9017 case OMPC_final: 9018 case OMPC_safelen: 9019 case OMPC_simdlen: 9020 case OMPC_allocator: 9021 case OMPC_collapse: 9022 case OMPC_private: 9023 case OMPC_shared: 9024 case OMPC_aligned: 9025 case OMPC_copyin: 9026 case OMPC_copyprivate: 9027 case OMPC_ordered: 9028 case OMPC_nowait: 9029 case OMPC_untied: 9030 case OMPC_mergeable: 9031 case OMPC_threadprivate: 9032 case OMPC_allocate: 9033 case OMPC_flush: 9034 case OMPC_read: 9035 case OMPC_write: 9036 case OMPC_update: 9037 case OMPC_capture: 9038 case OMPC_seq_cst: 9039 case OMPC_depend: 9040 case OMPC_threads: 9041 case OMPC_simd: 9042 case OMPC_map: 9043 case OMPC_priority: 9044 case OMPC_grainsize: 9045 case OMPC_nogroup: 9046 case OMPC_num_tasks: 9047 case OMPC_hint: 9048 case OMPC_defaultmap: 9049 case OMPC_unknown: 9050 case OMPC_uniform: 9051 case OMPC_to: 9052 case OMPC_from: 9053 case OMPC_use_device_ptr: 9054 case OMPC_is_device_ptr: 9055 case OMPC_unified_address: 9056 case OMPC_unified_shared_memory: 9057 case OMPC_reverse_offload: 9058 case OMPC_dynamic_allocators: 9059 case OMPC_atomic_default_mem_order: 9060 llvm_unreachable("Unexpected OpenMP clause."); 9061 } 9062 return CaptureRegion; 9063 } 9064 9065 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9066 Expr *Condition, SourceLocation StartLoc, 9067 SourceLocation LParenLoc, 9068 SourceLocation NameModifierLoc, 9069 SourceLocation ColonLoc, 9070 SourceLocation EndLoc) { 9071 Expr *ValExpr = Condition; 9072 Stmt *HelperValStmt = nullptr; 9073 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9074 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9075 !Condition->isInstantiationDependent() && 9076 !Condition->containsUnexpandedParameterPack()) { 9077 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9078 if (Val.isInvalid()) 9079 return nullptr; 9080 9081 ValExpr = Val.get(); 9082 9083 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9084 CaptureRegion = 9085 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9086 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9087 ValExpr = MakeFullExpr(ValExpr).get(); 9088 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9089 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9090 HelperValStmt = buildPreInits(Context, Captures); 9091 } 9092 } 9093 9094 return new (Context) 9095 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9096 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9097 } 9098 9099 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9100 SourceLocation StartLoc, 9101 SourceLocation LParenLoc, 9102 SourceLocation EndLoc) { 9103 Expr *ValExpr = Condition; 9104 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9105 !Condition->isInstantiationDependent() && 9106 !Condition->containsUnexpandedParameterPack()) { 9107 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9108 if (Val.isInvalid()) 9109 return nullptr; 9110 9111 ValExpr = MakeFullExpr(Val.get()).get(); 9112 } 9113 9114 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9115 } 9116 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9117 Expr *Op) { 9118 if (!Op) 9119 return ExprError(); 9120 9121 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9122 public: 9123 IntConvertDiagnoser() 9124 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9125 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9126 QualType T) override { 9127 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9128 } 9129 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9130 QualType T) override { 9131 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9132 } 9133 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9134 QualType T, 9135 QualType ConvTy) override { 9136 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9137 } 9138 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9139 QualType ConvTy) override { 9140 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9141 << ConvTy->isEnumeralType() << ConvTy; 9142 } 9143 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9144 QualType T) override { 9145 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9146 } 9147 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9148 QualType ConvTy) override { 9149 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9150 << ConvTy->isEnumeralType() << ConvTy; 9151 } 9152 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9153 QualType) override { 9154 llvm_unreachable("conversion functions are permitted"); 9155 } 9156 } ConvertDiagnoser; 9157 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9158 } 9159 9160 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9161 OpenMPClauseKind CKind, 9162 bool StrictlyPositive) { 9163 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9164 !ValExpr->isInstantiationDependent()) { 9165 SourceLocation Loc = ValExpr->getExprLoc(); 9166 ExprResult Value = 9167 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9168 if (Value.isInvalid()) 9169 return false; 9170 9171 ValExpr = Value.get(); 9172 // The expression must evaluate to a non-negative integer value. 9173 llvm::APSInt Result; 9174 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9175 Result.isSigned() && 9176 !((!StrictlyPositive && Result.isNonNegative()) || 9177 (StrictlyPositive && Result.isStrictlyPositive()))) { 9178 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9179 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9180 << ValExpr->getSourceRange(); 9181 return false; 9182 } 9183 } 9184 return true; 9185 } 9186 9187 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9188 SourceLocation StartLoc, 9189 SourceLocation LParenLoc, 9190 SourceLocation EndLoc) { 9191 Expr *ValExpr = NumThreads; 9192 Stmt *HelperValStmt = nullptr; 9193 9194 // OpenMP [2.5, Restrictions] 9195 // The num_threads expression must evaluate to a positive integer value. 9196 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9197 /*StrictlyPositive=*/true)) 9198 return nullptr; 9199 9200 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9201 OpenMPDirectiveKind CaptureRegion = 9202 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9203 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9204 ValExpr = MakeFullExpr(ValExpr).get(); 9205 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9206 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9207 HelperValStmt = buildPreInits(Context, Captures); 9208 } 9209 9210 return new (Context) OMPNumThreadsClause( 9211 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9212 } 9213 9214 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9215 OpenMPClauseKind CKind, 9216 bool StrictlyPositive) { 9217 if (!E) 9218 return ExprError(); 9219 if (E->isValueDependent() || E->isTypeDependent() || 9220 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9221 return E; 9222 llvm::APSInt Result; 9223 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9224 if (ICE.isInvalid()) 9225 return ExprError(); 9226 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9227 (!StrictlyPositive && !Result.isNonNegative())) { 9228 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9229 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9230 << E->getSourceRange(); 9231 return ExprError(); 9232 } 9233 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9234 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9235 << E->getSourceRange(); 9236 return ExprError(); 9237 } 9238 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9239 DSAStack->setAssociatedLoops(Result.getExtValue()); 9240 else if (CKind == OMPC_ordered) 9241 DSAStack->setAssociatedLoops(Result.getExtValue()); 9242 return ICE; 9243 } 9244 9245 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9246 SourceLocation LParenLoc, 9247 SourceLocation EndLoc) { 9248 // OpenMP [2.8.1, simd construct, Description] 9249 // The parameter of the safelen clause must be a constant 9250 // positive integer expression. 9251 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9252 if (Safelen.isInvalid()) 9253 return nullptr; 9254 return new (Context) 9255 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9256 } 9257 9258 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9259 SourceLocation LParenLoc, 9260 SourceLocation EndLoc) { 9261 // OpenMP [2.8.1, simd construct, Description] 9262 // The parameter of the simdlen clause must be a constant 9263 // positive integer expression. 9264 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9265 if (Simdlen.isInvalid()) 9266 return nullptr; 9267 return new (Context) 9268 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9269 } 9270 9271 /// Tries to find omp_allocator_handle_t type. 9272 static bool FindOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9273 QualType &OMPAllocatorHandleT) { 9274 if (!OMPAllocatorHandleT.isNull()) 9275 return true; 9276 DeclarationName OMPAllocatorHandleTName = 9277 &S.getASTContext().Idents.get("omp_allocator_handle_t"); 9278 auto *TD = dyn_cast_or_null<TypeDecl>(S.LookupSingleName( 9279 S.TUScope, OMPAllocatorHandleTName, Loc, Sema::LookupAnyName)); 9280 if (!TD) { 9281 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 9282 return false; 9283 } 9284 OMPAllocatorHandleT = S.getASTContext().getTypeDeclType(TD); 9285 return true; 9286 } 9287 9288 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 9289 SourceLocation LParenLoc, 9290 SourceLocation EndLoc) { 9291 // OpenMP [2.11.3, allocate Directive, Description] 9292 // allocator is an expression of omp_allocator_handle_t type. 9293 if (!FindOMPAllocatorHandleT(*this, A->getExprLoc(), OMPAllocatorHandleT)) 9294 return nullptr; 9295 9296 ExprResult Allocator = DefaultLvalueConversion(A); 9297 if (Allocator.isInvalid()) 9298 return nullptr; 9299 Allocator = PerformImplicitConversion(Allocator.get(), OMPAllocatorHandleT, 9300 Sema::AA_Initializing, 9301 /*AllowExplicit=*/true); 9302 if (Allocator.isInvalid()) 9303 return nullptr; 9304 return new (Context) 9305 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 9306 } 9307 9308 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 9309 SourceLocation StartLoc, 9310 SourceLocation LParenLoc, 9311 SourceLocation EndLoc) { 9312 // OpenMP [2.7.1, loop construct, Description] 9313 // OpenMP [2.8.1, simd construct, Description] 9314 // OpenMP [2.9.6, distribute construct, Description] 9315 // The parameter of the collapse clause must be a constant 9316 // positive integer expression. 9317 ExprResult NumForLoopsResult = 9318 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 9319 if (NumForLoopsResult.isInvalid()) 9320 return nullptr; 9321 return new (Context) 9322 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 9323 } 9324 9325 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 9326 SourceLocation EndLoc, 9327 SourceLocation LParenLoc, 9328 Expr *NumForLoops) { 9329 // OpenMP [2.7.1, loop construct, Description] 9330 // OpenMP [2.8.1, simd construct, Description] 9331 // OpenMP [2.9.6, distribute construct, Description] 9332 // The parameter of the ordered clause must be a constant 9333 // positive integer expression if any. 9334 if (NumForLoops && LParenLoc.isValid()) { 9335 ExprResult NumForLoopsResult = 9336 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 9337 if (NumForLoopsResult.isInvalid()) 9338 return nullptr; 9339 NumForLoops = NumForLoopsResult.get(); 9340 } else { 9341 NumForLoops = nullptr; 9342 } 9343 auto *Clause = OMPOrderedClause::Create( 9344 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 9345 StartLoc, LParenLoc, EndLoc); 9346 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 9347 return Clause; 9348 } 9349 9350 OMPClause *Sema::ActOnOpenMPSimpleClause( 9351 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 9352 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9353 OMPClause *Res = nullptr; 9354 switch (Kind) { 9355 case OMPC_default: 9356 Res = 9357 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 9358 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9359 break; 9360 case OMPC_proc_bind: 9361 Res = ActOnOpenMPProcBindClause( 9362 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 9363 LParenLoc, EndLoc); 9364 break; 9365 case OMPC_atomic_default_mem_order: 9366 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 9367 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 9368 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9369 break; 9370 case OMPC_if: 9371 case OMPC_final: 9372 case OMPC_num_threads: 9373 case OMPC_safelen: 9374 case OMPC_simdlen: 9375 case OMPC_allocator: 9376 case OMPC_collapse: 9377 case OMPC_schedule: 9378 case OMPC_private: 9379 case OMPC_firstprivate: 9380 case OMPC_lastprivate: 9381 case OMPC_shared: 9382 case OMPC_reduction: 9383 case OMPC_task_reduction: 9384 case OMPC_in_reduction: 9385 case OMPC_linear: 9386 case OMPC_aligned: 9387 case OMPC_copyin: 9388 case OMPC_copyprivate: 9389 case OMPC_ordered: 9390 case OMPC_nowait: 9391 case OMPC_untied: 9392 case OMPC_mergeable: 9393 case OMPC_threadprivate: 9394 case OMPC_allocate: 9395 case OMPC_flush: 9396 case OMPC_read: 9397 case OMPC_write: 9398 case OMPC_update: 9399 case OMPC_capture: 9400 case OMPC_seq_cst: 9401 case OMPC_depend: 9402 case OMPC_device: 9403 case OMPC_threads: 9404 case OMPC_simd: 9405 case OMPC_map: 9406 case OMPC_num_teams: 9407 case OMPC_thread_limit: 9408 case OMPC_priority: 9409 case OMPC_grainsize: 9410 case OMPC_nogroup: 9411 case OMPC_num_tasks: 9412 case OMPC_hint: 9413 case OMPC_dist_schedule: 9414 case OMPC_defaultmap: 9415 case OMPC_unknown: 9416 case OMPC_uniform: 9417 case OMPC_to: 9418 case OMPC_from: 9419 case OMPC_use_device_ptr: 9420 case OMPC_is_device_ptr: 9421 case OMPC_unified_address: 9422 case OMPC_unified_shared_memory: 9423 case OMPC_reverse_offload: 9424 case OMPC_dynamic_allocators: 9425 llvm_unreachable("Clause is not allowed."); 9426 } 9427 return Res; 9428 } 9429 9430 static std::string 9431 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 9432 ArrayRef<unsigned> Exclude = llvm::None) { 9433 SmallString<256> Buffer; 9434 llvm::raw_svector_ostream Out(Buffer); 9435 unsigned Bound = Last >= 2 ? Last - 2 : 0; 9436 unsigned Skipped = Exclude.size(); 9437 auto S = Exclude.begin(), E = Exclude.end(); 9438 for (unsigned I = First; I < Last; ++I) { 9439 if (std::find(S, E, I) != E) { 9440 --Skipped; 9441 continue; 9442 } 9443 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 9444 if (I == Bound - Skipped) 9445 Out << " or "; 9446 else if (I != Bound + 1 - Skipped) 9447 Out << ", "; 9448 } 9449 return Out.str(); 9450 } 9451 9452 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 9453 SourceLocation KindKwLoc, 9454 SourceLocation StartLoc, 9455 SourceLocation LParenLoc, 9456 SourceLocation EndLoc) { 9457 if (Kind == OMPC_DEFAULT_unknown) { 9458 static_assert(OMPC_DEFAULT_unknown > 0, 9459 "OMPC_DEFAULT_unknown not greater than 0"); 9460 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9461 << getListOfPossibleValues(OMPC_default, /*First=*/0, 9462 /*Last=*/OMPC_DEFAULT_unknown) 9463 << getOpenMPClauseName(OMPC_default); 9464 return nullptr; 9465 } 9466 switch (Kind) { 9467 case OMPC_DEFAULT_none: 9468 DSAStack->setDefaultDSANone(KindKwLoc); 9469 break; 9470 case OMPC_DEFAULT_shared: 9471 DSAStack->setDefaultDSAShared(KindKwLoc); 9472 break; 9473 case OMPC_DEFAULT_unknown: 9474 llvm_unreachable("Clause kind is not allowed."); 9475 break; 9476 } 9477 return new (Context) 9478 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9479 } 9480 9481 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 9482 SourceLocation KindKwLoc, 9483 SourceLocation StartLoc, 9484 SourceLocation LParenLoc, 9485 SourceLocation EndLoc) { 9486 if (Kind == OMPC_PROC_BIND_unknown) { 9487 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9488 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 9489 /*Last=*/OMPC_PROC_BIND_unknown) 9490 << getOpenMPClauseName(OMPC_proc_bind); 9491 return nullptr; 9492 } 9493 return new (Context) 9494 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9495 } 9496 9497 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 9498 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 9499 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9500 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 9501 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9502 << getListOfPossibleValues( 9503 OMPC_atomic_default_mem_order, /*First=*/0, 9504 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 9505 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 9506 return nullptr; 9507 } 9508 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 9509 LParenLoc, EndLoc); 9510 } 9511 9512 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 9513 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 9514 SourceLocation StartLoc, SourceLocation LParenLoc, 9515 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 9516 SourceLocation EndLoc) { 9517 OMPClause *Res = nullptr; 9518 switch (Kind) { 9519 case OMPC_schedule: 9520 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 9521 assert(Argument.size() == NumberOfElements && 9522 ArgumentLoc.size() == NumberOfElements); 9523 Res = ActOnOpenMPScheduleClause( 9524 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 9525 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 9526 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 9527 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 9528 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 9529 break; 9530 case OMPC_if: 9531 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 9532 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 9533 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 9534 DelimLoc, EndLoc); 9535 break; 9536 case OMPC_dist_schedule: 9537 Res = ActOnOpenMPDistScheduleClause( 9538 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 9539 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 9540 break; 9541 case OMPC_defaultmap: 9542 enum { Modifier, DefaultmapKind }; 9543 Res = ActOnOpenMPDefaultmapClause( 9544 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 9545 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 9546 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 9547 EndLoc); 9548 break; 9549 case OMPC_final: 9550 case OMPC_num_threads: 9551 case OMPC_safelen: 9552 case OMPC_simdlen: 9553 case OMPC_allocator: 9554 case OMPC_collapse: 9555 case OMPC_default: 9556 case OMPC_proc_bind: 9557 case OMPC_private: 9558 case OMPC_firstprivate: 9559 case OMPC_lastprivate: 9560 case OMPC_shared: 9561 case OMPC_reduction: 9562 case OMPC_task_reduction: 9563 case OMPC_in_reduction: 9564 case OMPC_linear: 9565 case OMPC_aligned: 9566 case OMPC_copyin: 9567 case OMPC_copyprivate: 9568 case OMPC_ordered: 9569 case OMPC_nowait: 9570 case OMPC_untied: 9571 case OMPC_mergeable: 9572 case OMPC_threadprivate: 9573 case OMPC_allocate: 9574 case OMPC_flush: 9575 case OMPC_read: 9576 case OMPC_write: 9577 case OMPC_update: 9578 case OMPC_capture: 9579 case OMPC_seq_cst: 9580 case OMPC_depend: 9581 case OMPC_device: 9582 case OMPC_threads: 9583 case OMPC_simd: 9584 case OMPC_map: 9585 case OMPC_num_teams: 9586 case OMPC_thread_limit: 9587 case OMPC_priority: 9588 case OMPC_grainsize: 9589 case OMPC_nogroup: 9590 case OMPC_num_tasks: 9591 case OMPC_hint: 9592 case OMPC_unknown: 9593 case OMPC_uniform: 9594 case OMPC_to: 9595 case OMPC_from: 9596 case OMPC_use_device_ptr: 9597 case OMPC_is_device_ptr: 9598 case OMPC_unified_address: 9599 case OMPC_unified_shared_memory: 9600 case OMPC_reverse_offload: 9601 case OMPC_dynamic_allocators: 9602 case OMPC_atomic_default_mem_order: 9603 llvm_unreachable("Clause is not allowed."); 9604 } 9605 return Res; 9606 } 9607 9608 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 9609 OpenMPScheduleClauseModifier M2, 9610 SourceLocation M1Loc, SourceLocation M2Loc) { 9611 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 9612 SmallVector<unsigned, 2> Excluded; 9613 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 9614 Excluded.push_back(M2); 9615 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 9616 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 9617 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 9618 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 9619 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 9620 << getListOfPossibleValues(OMPC_schedule, 9621 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 9622 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9623 Excluded) 9624 << getOpenMPClauseName(OMPC_schedule); 9625 return true; 9626 } 9627 return false; 9628 } 9629 9630 OMPClause *Sema::ActOnOpenMPScheduleClause( 9631 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 9632 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 9633 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 9634 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 9635 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 9636 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 9637 return nullptr; 9638 // OpenMP, 2.7.1, Loop Construct, Restrictions 9639 // Either the monotonic modifier or the nonmonotonic modifier can be specified 9640 // but not both. 9641 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 9642 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 9643 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 9644 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 9645 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 9646 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 9647 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 9648 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 9649 return nullptr; 9650 } 9651 if (Kind == OMPC_SCHEDULE_unknown) { 9652 std::string Values; 9653 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 9654 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 9655 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9656 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9657 Exclude); 9658 } else { 9659 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9660 /*Last=*/OMPC_SCHEDULE_unknown); 9661 } 9662 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 9663 << Values << getOpenMPClauseName(OMPC_schedule); 9664 return nullptr; 9665 } 9666 // OpenMP, 2.7.1, Loop Construct, Restrictions 9667 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 9668 // schedule(guided). 9669 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 9670 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 9671 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 9672 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 9673 diag::err_omp_schedule_nonmonotonic_static); 9674 return nullptr; 9675 } 9676 Expr *ValExpr = ChunkSize; 9677 Stmt *HelperValStmt = nullptr; 9678 if (ChunkSize) { 9679 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 9680 !ChunkSize->isInstantiationDependent() && 9681 !ChunkSize->containsUnexpandedParameterPack()) { 9682 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 9683 ExprResult Val = 9684 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 9685 if (Val.isInvalid()) 9686 return nullptr; 9687 9688 ValExpr = Val.get(); 9689 9690 // OpenMP [2.7.1, Restrictions] 9691 // chunk_size must be a loop invariant integer expression with a positive 9692 // value. 9693 llvm::APSInt Result; 9694 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 9695 if (Result.isSigned() && !Result.isStrictlyPositive()) { 9696 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 9697 << "schedule" << 1 << ChunkSize->getSourceRange(); 9698 return nullptr; 9699 } 9700 } else if (getOpenMPCaptureRegionForClause( 9701 DSAStack->getCurrentDirective(), OMPC_schedule) != 9702 OMPD_unknown && 9703 !CurContext->isDependentContext()) { 9704 ValExpr = MakeFullExpr(ValExpr).get(); 9705 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9706 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9707 HelperValStmt = buildPreInits(Context, Captures); 9708 } 9709 } 9710 } 9711 9712 return new (Context) 9713 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 9714 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 9715 } 9716 9717 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 9718 SourceLocation StartLoc, 9719 SourceLocation EndLoc) { 9720 OMPClause *Res = nullptr; 9721 switch (Kind) { 9722 case OMPC_ordered: 9723 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 9724 break; 9725 case OMPC_nowait: 9726 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 9727 break; 9728 case OMPC_untied: 9729 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 9730 break; 9731 case OMPC_mergeable: 9732 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 9733 break; 9734 case OMPC_read: 9735 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 9736 break; 9737 case OMPC_write: 9738 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 9739 break; 9740 case OMPC_update: 9741 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 9742 break; 9743 case OMPC_capture: 9744 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 9745 break; 9746 case OMPC_seq_cst: 9747 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 9748 break; 9749 case OMPC_threads: 9750 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 9751 break; 9752 case OMPC_simd: 9753 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 9754 break; 9755 case OMPC_nogroup: 9756 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 9757 break; 9758 case OMPC_unified_address: 9759 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 9760 break; 9761 case OMPC_unified_shared_memory: 9762 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9763 break; 9764 case OMPC_reverse_offload: 9765 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 9766 break; 9767 case OMPC_dynamic_allocators: 9768 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 9769 break; 9770 case OMPC_if: 9771 case OMPC_final: 9772 case OMPC_num_threads: 9773 case OMPC_safelen: 9774 case OMPC_simdlen: 9775 case OMPC_allocator: 9776 case OMPC_collapse: 9777 case OMPC_schedule: 9778 case OMPC_private: 9779 case OMPC_firstprivate: 9780 case OMPC_lastprivate: 9781 case OMPC_shared: 9782 case OMPC_reduction: 9783 case OMPC_task_reduction: 9784 case OMPC_in_reduction: 9785 case OMPC_linear: 9786 case OMPC_aligned: 9787 case OMPC_copyin: 9788 case OMPC_copyprivate: 9789 case OMPC_default: 9790 case OMPC_proc_bind: 9791 case OMPC_threadprivate: 9792 case OMPC_allocate: 9793 case OMPC_flush: 9794 case OMPC_depend: 9795 case OMPC_device: 9796 case OMPC_map: 9797 case OMPC_num_teams: 9798 case OMPC_thread_limit: 9799 case OMPC_priority: 9800 case OMPC_grainsize: 9801 case OMPC_num_tasks: 9802 case OMPC_hint: 9803 case OMPC_dist_schedule: 9804 case OMPC_defaultmap: 9805 case OMPC_unknown: 9806 case OMPC_uniform: 9807 case OMPC_to: 9808 case OMPC_from: 9809 case OMPC_use_device_ptr: 9810 case OMPC_is_device_ptr: 9811 case OMPC_atomic_default_mem_order: 9812 llvm_unreachable("Clause is not allowed."); 9813 } 9814 return Res; 9815 } 9816 9817 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 9818 SourceLocation EndLoc) { 9819 DSAStack->setNowaitRegion(); 9820 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 9821 } 9822 9823 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 9824 SourceLocation EndLoc) { 9825 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 9826 } 9827 9828 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 9829 SourceLocation EndLoc) { 9830 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 9831 } 9832 9833 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 9834 SourceLocation EndLoc) { 9835 return new (Context) OMPReadClause(StartLoc, EndLoc); 9836 } 9837 9838 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 9839 SourceLocation EndLoc) { 9840 return new (Context) OMPWriteClause(StartLoc, EndLoc); 9841 } 9842 9843 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 9844 SourceLocation EndLoc) { 9845 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 9846 } 9847 9848 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 9849 SourceLocation EndLoc) { 9850 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 9851 } 9852 9853 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 9854 SourceLocation EndLoc) { 9855 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 9856 } 9857 9858 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 9859 SourceLocation EndLoc) { 9860 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 9861 } 9862 9863 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 9864 SourceLocation EndLoc) { 9865 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 9866 } 9867 9868 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 9869 SourceLocation EndLoc) { 9870 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 9871 } 9872 9873 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 9874 SourceLocation EndLoc) { 9875 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 9876 } 9877 9878 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 9879 SourceLocation EndLoc) { 9880 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9881 } 9882 9883 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 9884 SourceLocation EndLoc) { 9885 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 9886 } 9887 9888 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 9889 SourceLocation EndLoc) { 9890 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 9891 } 9892 9893 OMPClause *Sema::ActOnOpenMPVarListClause( 9894 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 9895 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 9896 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 9897 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 9898 OpenMPLinearClauseKind LinKind, 9899 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 9900 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 9901 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 9902 SourceLocation StartLoc = Locs.StartLoc; 9903 SourceLocation LParenLoc = Locs.LParenLoc; 9904 SourceLocation EndLoc = Locs.EndLoc; 9905 OMPClause *Res = nullptr; 9906 switch (Kind) { 9907 case OMPC_private: 9908 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9909 break; 9910 case OMPC_firstprivate: 9911 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9912 break; 9913 case OMPC_lastprivate: 9914 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9915 break; 9916 case OMPC_shared: 9917 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 9918 break; 9919 case OMPC_reduction: 9920 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9921 EndLoc, ReductionOrMapperIdScopeSpec, 9922 ReductionOrMapperId); 9923 break; 9924 case OMPC_task_reduction: 9925 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9926 EndLoc, ReductionOrMapperIdScopeSpec, 9927 ReductionOrMapperId); 9928 break; 9929 case OMPC_in_reduction: 9930 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9931 EndLoc, ReductionOrMapperIdScopeSpec, 9932 ReductionOrMapperId); 9933 break; 9934 case OMPC_linear: 9935 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 9936 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 9937 break; 9938 case OMPC_aligned: 9939 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 9940 ColonLoc, EndLoc); 9941 break; 9942 case OMPC_copyin: 9943 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 9944 break; 9945 case OMPC_copyprivate: 9946 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9947 break; 9948 case OMPC_flush: 9949 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 9950 break; 9951 case OMPC_depend: 9952 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 9953 StartLoc, LParenLoc, EndLoc); 9954 break; 9955 case OMPC_map: 9956 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 9957 ReductionOrMapperIdScopeSpec, 9958 ReductionOrMapperId, MapType, IsMapTypeImplicit, 9959 DepLinMapLoc, ColonLoc, VarList, Locs); 9960 break; 9961 case OMPC_to: 9962 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 9963 ReductionOrMapperId, Locs); 9964 break; 9965 case OMPC_from: 9966 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 9967 ReductionOrMapperId, Locs); 9968 break; 9969 case OMPC_use_device_ptr: 9970 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 9971 break; 9972 case OMPC_is_device_ptr: 9973 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 9974 break; 9975 case OMPC_if: 9976 case OMPC_final: 9977 case OMPC_num_threads: 9978 case OMPC_safelen: 9979 case OMPC_simdlen: 9980 case OMPC_allocator: 9981 case OMPC_collapse: 9982 case OMPC_default: 9983 case OMPC_proc_bind: 9984 case OMPC_schedule: 9985 case OMPC_ordered: 9986 case OMPC_nowait: 9987 case OMPC_untied: 9988 case OMPC_mergeable: 9989 case OMPC_threadprivate: 9990 case OMPC_allocate: 9991 case OMPC_read: 9992 case OMPC_write: 9993 case OMPC_update: 9994 case OMPC_capture: 9995 case OMPC_seq_cst: 9996 case OMPC_device: 9997 case OMPC_threads: 9998 case OMPC_simd: 9999 case OMPC_num_teams: 10000 case OMPC_thread_limit: 10001 case OMPC_priority: 10002 case OMPC_grainsize: 10003 case OMPC_nogroup: 10004 case OMPC_num_tasks: 10005 case OMPC_hint: 10006 case OMPC_dist_schedule: 10007 case OMPC_defaultmap: 10008 case OMPC_unknown: 10009 case OMPC_uniform: 10010 case OMPC_unified_address: 10011 case OMPC_unified_shared_memory: 10012 case OMPC_reverse_offload: 10013 case OMPC_dynamic_allocators: 10014 case OMPC_atomic_default_mem_order: 10015 llvm_unreachable("Clause is not allowed."); 10016 } 10017 return Res; 10018 } 10019 10020 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10021 ExprObjectKind OK, SourceLocation Loc) { 10022 ExprResult Res = BuildDeclRefExpr( 10023 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10024 if (!Res.isUsable()) 10025 return ExprError(); 10026 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10027 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10028 if (!Res.isUsable()) 10029 return ExprError(); 10030 } 10031 if (VK != VK_LValue && Res.get()->isGLValue()) { 10032 Res = DefaultLvalueConversion(Res.get()); 10033 if (!Res.isUsable()) 10034 return ExprError(); 10035 } 10036 return Res; 10037 } 10038 10039 static std::pair<ValueDecl *, bool> 10040 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 10041 SourceRange &ERange, bool AllowArraySection = false) { 10042 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 10043 RefExpr->containsUnexpandedParameterPack()) 10044 return std::make_pair(nullptr, true); 10045 10046 // OpenMP [3.1, C/C++] 10047 // A list item is a variable name. 10048 // OpenMP [2.9.3.3, Restrictions, p.1] 10049 // A variable that is part of another variable (as an array or 10050 // structure element) cannot appear in a private clause. 10051 RefExpr = RefExpr->IgnoreParens(); 10052 enum { 10053 NoArrayExpr = -1, 10054 ArraySubscript = 0, 10055 OMPArraySection = 1 10056 } IsArrayExpr = NoArrayExpr; 10057 if (AllowArraySection) { 10058 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 10059 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 10060 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 10061 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10062 RefExpr = Base; 10063 IsArrayExpr = ArraySubscript; 10064 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 10065 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 10066 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 10067 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 10068 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 10069 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10070 RefExpr = Base; 10071 IsArrayExpr = OMPArraySection; 10072 } 10073 } 10074 ELoc = RefExpr->getExprLoc(); 10075 ERange = RefExpr->getSourceRange(); 10076 RefExpr = RefExpr->IgnoreParenImpCasts(); 10077 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 10078 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 10079 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 10080 (S.getCurrentThisType().isNull() || !ME || 10081 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 10082 !isa<FieldDecl>(ME->getMemberDecl()))) { 10083 if (IsArrayExpr != NoArrayExpr) { 10084 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 10085 << ERange; 10086 } else { 10087 S.Diag(ELoc, 10088 AllowArraySection 10089 ? diag::err_omp_expected_var_name_member_expr_or_array_item 10090 : diag::err_omp_expected_var_name_member_expr) 10091 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 10092 } 10093 return std::make_pair(nullptr, false); 10094 } 10095 return std::make_pair( 10096 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 10097 } 10098 10099 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10100 SourceLocation StartLoc, 10101 SourceLocation LParenLoc, 10102 SourceLocation EndLoc) { 10103 SmallVector<Expr *, 8> Vars; 10104 SmallVector<Expr *, 8> PrivateCopies; 10105 for (Expr *RefExpr : VarList) { 10106 assert(RefExpr && "NULL expr in OpenMP private clause."); 10107 SourceLocation ELoc; 10108 SourceRange ERange; 10109 Expr *SimpleRefExpr = RefExpr; 10110 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10111 if (Res.second) { 10112 // It will be analyzed later. 10113 Vars.push_back(RefExpr); 10114 PrivateCopies.push_back(nullptr); 10115 } 10116 ValueDecl *D = Res.first; 10117 if (!D) 10118 continue; 10119 10120 QualType Type = D->getType(); 10121 auto *VD = dyn_cast<VarDecl>(D); 10122 10123 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10124 // A variable that appears in a private clause must not have an incomplete 10125 // type or a reference type. 10126 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10127 continue; 10128 Type = Type.getNonReferenceType(); 10129 10130 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10131 // A variable that is privatized must not have a const-qualified type 10132 // unless it is of class type with a mutable member. This restriction does 10133 // not apply to the firstprivate clause. 10134 // 10135 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10136 // A variable that appears in a private clause must not have a 10137 // const-qualified type unless it is of class type with a mutable member. 10138 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10139 continue; 10140 10141 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10142 // in a Construct] 10143 // Variables with the predetermined data-sharing attributes may not be 10144 // listed in data-sharing attributes clauses, except for the cases 10145 // listed below. For these exceptions only, listing a predetermined 10146 // variable in a data-sharing attribute clause is allowed and overrides 10147 // the variable's predetermined data-sharing attributes. 10148 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10149 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10150 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10151 << getOpenMPClauseName(OMPC_private); 10152 reportOriginalDsa(*this, DSAStack, D, DVar); 10153 continue; 10154 } 10155 10156 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10157 // Variably modified types are not supported for tasks. 10158 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10159 isOpenMPTaskingDirective(CurrDir)) { 10160 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10161 << getOpenMPClauseName(OMPC_private) << Type 10162 << getOpenMPDirectiveName(CurrDir); 10163 bool IsDecl = 10164 !VD || 10165 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10166 Diag(D->getLocation(), 10167 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10168 << D; 10169 continue; 10170 } 10171 10172 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10173 // A list item cannot appear in both a map clause and a data-sharing 10174 // attribute clause on the same construct 10175 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10176 OpenMPClauseKind ConflictKind; 10177 if (DSAStack->checkMappableExprComponentListsForDecl( 10178 VD, /*CurrentRegionOnly=*/true, 10179 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10180 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10181 ConflictKind = WhereFoundClauseKind; 10182 return true; 10183 })) { 10184 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10185 << getOpenMPClauseName(OMPC_private) 10186 << getOpenMPClauseName(ConflictKind) 10187 << getOpenMPDirectiveName(CurrDir); 10188 reportOriginalDsa(*this, DSAStack, D, DVar); 10189 continue; 10190 } 10191 } 10192 10193 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10194 // A variable of class type (or array thereof) that appears in a private 10195 // clause requires an accessible, unambiguous default constructor for the 10196 // class type. 10197 // Generate helper private variable and initialize it with the default 10198 // value. The address of the original variable is replaced by the address of 10199 // the new private variable in CodeGen. This new variable is not added to 10200 // IdResolver, so the code in the OpenMP region uses original variable for 10201 // proper diagnostics. 10202 Type = Type.getUnqualifiedType(); 10203 VarDecl *VDPrivate = 10204 buildVarDecl(*this, ELoc, Type, D->getName(), 10205 D->hasAttrs() ? &D->getAttrs() : nullptr, 10206 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10207 ActOnUninitializedDecl(VDPrivate); 10208 if (VDPrivate->isInvalidDecl()) 10209 continue; 10210 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10211 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10212 10213 DeclRefExpr *Ref = nullptr; 10214 if (!VD && !CurContext->isDependentContext()) 10215 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10216 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10217 Vars.push_back((VD || CurContext->isDependentContext()) 10218 ? RefExpr->IgnoreParens() 10219 : Ref); 10220 PrivateCopies.push_back(VDPrivateRefExpr); 10221 } 10222 10223 if (Vars.empty()) 10224 return nullptr; 10225 10226 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10227 PrivateCopies); 10228 } 10229 10230 namespace { 10231 class DiagsUninitializedSeveretyRAII { 10232 private: 10233 DiagnosticsEngine &Diags; 10234 SourceLocation SavedLoc; 10235 bool IsIgnored = false; 10236 10237 public: 10238 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10239 bool IsIgnored) 10240 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10241 if (!IsIgnored) { 10242 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10243 /*Map*/ diag::Severity::Ignored, Loc); 10244 } 10245 } 10246 ~DiagsUninitializedSeveretyRAII() { 10247 if (!IsIgnored) 10248 Diags.popMappings(SavedLoc); 10249 } 10250 }; 10251 } 10252 10253 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10254 SourceLocation StartLoc, 10255 SourceLocation LParenLoc, 10256 SourceLocation EndLoc) { 10257 SmallVector<Expr *, 8> Vars; 10258 SmallVector<Expr *, 8> PrivateCopies; 10259 SmallVector<Expr *, 8> Inits; 10260 SmallVector<Decl *, 4> ExprCaptures; 10261 bool IsImplicitClause = 10262 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10263 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10264 10265 for (Expr *RefExpr : VarList) { 10266 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10267 SourceLocation ELoc; 10268 SourceRange ERange; 10269 Expr *SimpleRefExpr = RefExpr; 10270 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10271 if (Res.second) { 10272 // It will be analyzed later. 10273 Vars.push_back(RefExpr); 10274 PrivateCopies.push_back(nullptr); 10275 Inits.push_back(nullptr); 10276 } 10277 ValueDecl *D = Res.first; 10278 if (!D) 10279 continue; 10280 10281 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10282 QualType Type = D->getType(); 10283 auto *VD = dyn_cast<VarDecl>(D); 10284 10285 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10286 // A variable that appears in a private clause must not have an incomplete 10287 // type or a reference type. 10288 if (RequireCompleteType(ELoc, Type, 10289 diag::err_omp_firstprivate_incomplete_type)) 10290 continue; 10291 Type = Type.getNonReferenceType(); 10292 10293 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10294 // A variable of class type (or array thereof) that appears in a private 10295 // clause requires an accessible, unambiguous copy constructor for the 10296 // class type. 10297 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10298 10299 // If an implicit firstprivate variable found it was checked already. 10300 DSAStackTy::DSAVarData TopDVar; 10301 if (!IsImplicitClause) { 10302 DSAStackTy::DSAVarData DVar = 10303 DSAStack->getTopDSA(D, /*FromParent=*/false); 10304 TopDVar = DVar; 10305 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10306 bool IsConstant = ElemType.isConstant(Context); 10307 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10308 // A list item that specifies a given variable may not appear in more 10309 // than one clause on the same directive, except that a variable may be 10310 // specified in both firstprivate and lastprivate clauses. 10311 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10312 // A list item may appear in a firstprivate or lastprivate clause but not 10313 // both. 10314 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10315 (isOpenMPDistributeDirective(CurrDir) || 10316 DVar.CKind != OMPC_lastprivate) && 10317 DVar.RefExpr) { 10318 Diag(ELoc, diag::err_omp_wrong_dsa) 10319 << getOpenMPClauseName(DVar.CKind) 10320 << getOpenMPClauseName(OMPC_firstprivate); 10321 reportOriginalDsa(*this, DSAStack, D, DVar); 10322 continue; 10323 } 10324 10325 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10326 // in a Construct] 10327 // Variables with the predetermined data-sharing attributes may not be 10328 // listed in data-sharing attributes clauses, except for the cases 10329 // listed below. For these exceptions only, listing a predetermined 10330 // variable in a data-sharing attribute clause is allowed and overrides 10331 // the variable's predetermined data-sharing attributes. 10332 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10333 // in a Construct, C/C++, p.2] 10334 // Variables with const-qualified type having no mutable member may be 10335 // listed in a firstprivate clause, even if they are static data members. 10336 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 10337 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 10338 Diag(ELoc, diag::err_omp_wrong_dsa) 10339 << getOpenMPClauseName(DVar.CKind) 10340 << getOpenMPClauseName(OMPC_firstprivate); 10341 reportOriginalDsa(*this, DSAStack, D, DVar); 10342 continue; 10343 } 10344 10345 // OpenMP [2.9.3.4, Restrictions, p.2] 10346 // A list item that is private within a parallel region must not appear 10347 // in a firstprivate clause on a worksharing construct if any of the 10348 // worksharing regions arising from the worksharing construct ever bind 10349 // to any of the parallel regions arising from the parallel construct. 10350 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10351 // A list item that is private within a teams region must not appear in a 10352 // firstprivate clause on a distribute construct if any of the distribute 10353 // regions arising from the distribute construct ever bind to any of the 10354 // teams regions arising from the teams construct. 10355 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10356 // A list item that appears in a reduction clause of a teams construct 10357 // must not appear in a firstprivate clause on a distribute construct if 10358 // any of the distribute regions arising from the distribute construct 10359 // ever bind to any of the teams regions arising from the teams construct. 10360 if ((isOpenMPWorksharingDirective(CurrDir) || 10361 isOpenMPDistributeDirective(CurrDir)) && 10362 !isOpenMPParallelDirective(CurrDir) && 10363 !isOpenMPTeamsDirective(CurrDir)) { 10364 DVar = DSAStack->getImplicitDSA(D, true); 10365 if (DVar.CKind != OMPC_shared && 10366 (isOpenMPParallelDirective(DVar.DKind) || 10367 isOpenMPTeamsDirective(DVar.DKind) || 10368 DVar.DKind == OMPD_unknown)) { 10369 Diag(ELoc, diag::err_omp_required_access) 10370 << getOpenMPClauseName(OMPC_firstprivate) 10371 << getOpenMPClauseName(OMPC_shared); 10372 reportOriginalDsa(*this, DSAStack, D, DVar); 10373 continue; 10374 } 10375 } 10376 // OpenMP [2.9.3.4, Restrictions, p.3] 10377 // A list item that appears in a reduction clause of a parallel construct 10378 // must not appear in a firstprivate clause on a worksharing or task 10379 // construct if any of the worksharing or task regions arising from the 10380 // worksharing or task construct ever bind to any of the parallel regions 10381 // arising from the parallel construct. 10382 // OpenMP [2.9.3.4, Restrictions, p.4] 10383 // A list item that appears in a reduction clause in worksharing 10384 // construct must not appear in a firstprivate clause in a task construct 10385 // encountered during execution of any of the worksharing regions arising 10386 // from the worksharing construct. 10387 if (isOpenMPTaskingDirective(CurrDir)) { 10388 DVar = DSAStack->hasInnermostDSA( 10389 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 10390 [](OpenMPDirectiveKind K) { 10391 return isOpenMPParallelDirective(K) || 10392 isOpenMPWorksharingDirective(K) || 10393 isOpenMPTeamsDirective(K); 10394 }, 10395 /*FromParent=*/true); 10396 if (DVar.CKind == OMPC_reduction && 10397 (isOpenMPParallelDirective(DVar.DKind) || 10398 isOpenMPWorksharingDirective(DVar.DKind) || 10399 isOpenMPTeamsDirective(DVar.DKind))) { 10400 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 10401 << getOpenMPDirectiveName(DVar.DKind); 10402 reportOriginalDsa(*this, DSAStack, D, DVar); 10403 continue; 10404 } 10405 } 10406 10407 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10408 // A list item cannot appear in both a map clause and a data-sharing 10409 // attribute clause on the same construct 10410 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10411 OpenMPClauseKind ConflictKind; 10412 if (DSAStack->checkMappableExprComponentListsForDecl( 10413 VD, /*CurrentRegionOnly=*/true, 10414 [&ConflictKind]( 10415 OMPClauseMappableExprCommon::MappableExprComponentListRef, 10416 OpenMPClauseKind WhereFoundClauseKind) { 10417 ConflictKind = WhereFoundClauseKind; 10418 return true; 10419 })) { 10420 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10421 << getOpenMPClauseName(OMPC_firstprivate) 10422 << getOpenMPClauseName(ConflictKind) 10423 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10424 reportOriginalDsa(*this, DSAStack, D, DVar); 10425 continue; 10426 } 10427 } 10428 } 10429 10430 // Variably modified types are not supported for tasks. 10431 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10432 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 10433 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10434 << getOpenMPClauseName(OMPC_firstprivate) << Type 10435 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10436 bool IsDecl = 10437 !VD || 10438 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10439 Diag(D->getLocation(), 10440 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10441 << D; 10442 continue; 10443 } 10444 10445 Type = Type.getUnqualifiedType(); 10446 VarDecl *VDPrivate = 10447 buildVarDecl(*this, ELoc, Type, D->getName(), 10448 D->hasAttrs() ? &D->getAttrs() : nullptr, 10449 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10450 // Generate helper private variable and initialize it with the value of the 10451 // original variable. The address of the original variable is replaced by 10452 // the address of the new private variable in the CodeGen. This new variable 10453 // is not added to IdResolver, so the code in the OpenMP region uses 10454 // original variable for proper diagnostics and variable capturing. 10455 Expr *VDInitRefExpr = nullptr; 10456 // For arrays generate initializer for single element and replace it by the 10457 // original array element in CodeGen. 10458 if (Type->isArrayType()) { 10459 VarDecl *VDInit = 10460 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 10461 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 10462 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 10463 ElemType = ElemType.getUnqualifiedType(); 10464 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 10465 ".firstprivate.temp"); 10466 InitializedEntity Entity = 10467 InitializedEntity::InitializeVariable(VDInitTemp); 10468 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 10469 10470 InitializationSequence InitSeq(*this, Entity, Kind, Init); 10471 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 10472 if (Result.isInvalid()) 10473 VDPrivate->setInvalidDecl(); 10474 else 10475 VDPrivate->setInit(Result.getAs<Expr>()); 10476 // Remove temp variable declaration. 10477 Context.Deallocate(VDInitTemp); 10478 } else { 10479 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 10480 ".firstprivate.temp"); 10481 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 10482 RefExpr->getExprLoc()); 10483 AddInitializerToDecl(VDPrivate, 10484 DefaultLvalueConversion(VDInitRefExpr).get(), 10485 /*DirectInit=*/false); 10486 } 10487 if (VDPrivate->isInvalidDecl()) { 10488 if (IsImplicitClause) { 10489 Diag(RefExpr->getExprLoc(), 10490 diag::note_omp_task_predetermined_firstprivate_here); 10491 } 10492 continue; 10493 } 10494 CurContext->addDecl(VDPrivate); 10495 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10496 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 10497 RefExpr->getExprLoc()); 10498 DeclRefExpr *Ref = nullptr; 10499 if (!VD && !CurContext->isDependentContext()) { 10500 if (TopDVar.CKind == OMPC_lastprivate) { 10501 Ref = TopDVar.PrivateCopy; 10502 } else { 10503 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10504 if (!isOpenMPCapturedDecl(D)) 10505 ExprCaptures.push_back(Ref->getDecl()); 10506 } 10507 } 10508 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 10509 Vars.push_back((VD || CurContext->isDependentContext()) 10510 ? RefExpr->IgnoreParens() 10511 : Ref); 10512 PrivateCopies.push_back(VDPrivateRefExpr); 10513 Inits.push_back(VDInitRefExpr); 10514 } 10515 10516 if (Vars.empty()) 10517 return nullptr; 10518 10519 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10520 Vars, PrivateCopies, Inits, 10521 buildPreInits(Context, ExprCaptures)); 10522 } 10523 10524 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 10525 SourceLocation StartLoc, 10526 SourceLocation LParenLoc, 10527 SourceLocation EndLoc) { 10528 SmallVector<Expr *, 8> Vars; 10529 SmallVector<Expr *, 8> SrcExprs; 10530 SmallVector<Expr *, 8> DstExprs; 10531 SmallVector<Expr *, 8> AssignmentOps; 10532 SmallVector<Decl *, 4> ExprCaptures; 10533 SmallVector<Expr *, 4> ExprPostUpdates; 10534 for (Expr *RefExpr : VarList) { 10535 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10536 SourceLocation ELoc; 10537 SourceRange ERange; 10538 Expr *SimpleRefExpr = RefExpr; 10539 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10540 if (Res.second) { 10541 // It will be analyzed later. 10542 Vars.push_back(RefExpr); 10543 SrcExprs.push_back(nullptr); 10544 DstExprs.push_back(nullptr); 10545 AssignmentOps.push_back(nullptr); 10546 } 10547 ValueDecl *D = Res.first; 10548 if (!D) 10549 continue; 10550 10551 QualType Type = D->getType(); 10552 auto *VD = dyn_cast<VarDecl>(D); 10553 10554 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 10555 // A variable that appears in a lastprivate clause must not have an 10556 // incomplete type or a reference type. 10557 if (RequireCompleteType(ELoc, Type, 10558 diag::err_omp_lastprivate_incomplete_type)) 10559 continue; 10560 Type = Type.getNonReferenceType(); 10561 10562 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10563 // A variable that is privatized must not have a const-qualified type 10564 // unless it is of class type with a mutable member. This restriction does 10565 // not apply to the firstprivate clause. 10566 // 10567 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 10568 // A variable that appears in a lastprivate clause must not have a 10569 // const-qualified type unless it is of class type with a mutable member. 10570 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 10571 continue; 10572 10573 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10574 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10575 // in a Construct] 10576 // Variables with the predetermined data-sharing attributes may not be 10577 // listed in data-sharing attributes clauses, except for the cases 10578 // listed below. 10579 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10580 // A list item may appear in a firstprivate or lastprivate clause but not 10581 // both. 10582 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10583 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 10584 (isOpenMPDistributeDirective(CurrDir) || 10585 DVar.CKind != OMPC_firstprivate) && 10586 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 10587 Diag(ELoc, diag::err_omp_wrong_dsa) 10588 << getOpenMPClauseName(DVar.CKind) 10589 << getOpenMPClauseName(OMPC_lastprivate); 10590 reportOriginalDsa(*this, DSAStack, D, DVar); 10591 continue; 10592 } 10593 10594 // OpenMP [2.14.3.5, Restrictions, p.2] 10595 // A list item that is private within a parallel region, or that appears in 10596 // the reduction clause of a parallel construct, must not appear in a 10597 // lastprivate clause on a worksharing construct if any of the corresponding 10598 // worksharing regions ever binds to any of the corresponding parallel 10599 // regions. 10600 DSAStackTy::DSAVarData TopDVar = DVar; 10601 if (isOpenMPWorksharingDirective(CurrDir) && 10602 !isOpenMPParallelDirective(CurrDir) && 10603 !isOpenMPTeamsDirective(CurrDir)) { 10604 DVar = DSAStack->getImplicitDSA(D, true); 10605 if (DVar.CKind != OMPC_shared) { 10606 Diag(ELoc, diag::err_omp_required_access) 10607 << getOpenMPClauseName(OMPC_lastprivate) 10608 << getOpenMPClauseName(OMPC_shared); 10609 reportOriginalDsa(*this, DSAStack, D, DVar); 10610 continue; 10611 } 10612 } 10613 10614 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 10615 // A variable of class type (or array thereof) that appears in a 10616 // lastprivate clause requires an accessible, unambiguous default 10617 // constructor for the class type, unless the list item is also specified 10618 // in a firstprivate clause. 10619 // A variable of class type (or array thereof) that appears in a 10620 // lastprivate clause requires an accessible, unambiguous copy assignment 10621 // operator for the class type. 10622 Type = Context.getBaseElementType(Type).getNonReferenceType(); 10623 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 10624 Type.getUnqualifiedType(), ".lastprivate.src", 10625 D->hasAttrs() ? &D->getAttrs() : nullptr); 10626 DeclRefExpr *PseudoSrcExpr = 10627 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 10628 VarDecl *DstVD = 10629 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 10630 D->hasAttrs() ? &D->getAttrs() : nullptr); 10631 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10632 // For arrays generate assignment operation for single element and replace 10633 // it by the original array element in CodeGen. 10634 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 10635 PseudoDstExpr, PseudoSrcExpr); 10636 if (AssignmentOp.isInvalid()) 10637 continue; 10638 AssignmentOp = 10639 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 10640 if (AssignmentOp.isInvalid()) 10641 continue; 10642 10643 DeclRefExpr *Ref = nullptr; 10644 if (!VD && !CurContext->isDependentContext()) { 10645 if (TopDVar.CKind == OMPC_firstprivate) { 10646 Ref = TopDVar.PrivateCopy; 10647 } else { 10648 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10649 if (!isOpenMPCapturedDecl(D)) 10650 ExprCaptures.push_back(Ref->getDecl()); 10651 } 10652 if (TopDVar.CKind == OMPC_firstprivate || 10653 (!isOpenMPCapturedDecl(D) && 10654 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 10655 ExprResult RefRes = DefaultLvalueConversion(Ref); 10656 if (!RefRes.isUsable()) 10657 continue; 10658 ExprResult PostUpdateRes = 10659 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10660 RefRes.get()); 10661 if (!PostUpdateRes.isUsable()) 10662 continue; 10663 ExprPostUpdates.push_back( 10664 IgnoredValueConversions(PostUpdateRes.get()).get()); 10665 } 10666 } 10667 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 10668 Vars.push_back((VD || CurContext->isDependentContext()) 10669 ? RefExpr->IgnoreParens() 10670 : Ref); 10671 SrcExprs.push_back(PseudoSrcExpr); 10672 DstExprs.push_back(PseudoDstExpr); 10673 AssignmentOps.push_back(AssignmentOp.get()); 10674 } 10675 10676 if (Vars.empty()) 10677 return nullptr; 10678 10679 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10680 Vars, SrcExprs, DstExprs, AssignmentOps, 10681 buildPreInits(Context, ExprCaptures), 10682 buildPostUpdate(*this, ExprPostUpdates)); 10683 } 10684 10685 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 10686 SourceLocation StartLoc, 10687 SourceLocation LParenLoc, 10688 SourceLocation EndLoc) { 10689 SmallVector<Expr *, 8> Vars; 10690 for (Expr *RefExpr : VarList) { 10691 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10692 SourceLocation ELoc; 10693 SourceRange ERange; 10694 Expr *SimpleRefExpr = RefExpr; 10695 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10696 if (Res.second) { 10697 // It will be analyzed later. 10698 Vars.push_back(RefExpr); 10699 } 10700 ValueDecl *D = Res.first; 10701 if (!D) 10702 continue; 10703 10704 auto *VD = dyn_cast<VarDecl>(D); 10705 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10706 // in a Construct] 10707 // Variables with the predetermined data-sharing attributes may not be 10708 // listed in data-sharing attributes clauses, except for the cases 10709 // listed below. For these exceptions only, listing a predetermined 10710 // variable in a data-sharing attribute clause is allowed and overrides 10711 // the variable's predetermined data-sharing attributes. 10712 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10713 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 10714 DVar.RefExpr) { 10715 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10716 << getOpenMPClauseName(OMPC_shared); 10717 reportOriginalDsa(*this, DSAStack, D, DVar); 10718 continue; 10719 } 10720 10721 DeclRefExpr *Ref = nullptr; 10722 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 10723 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10724 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 10725 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 10726 ? RefExpr->IgnoreParens() 10727 : Ref); 10728 } 10729 10730 if (Vars.empty()) 10731 return nullptr; 10732 10733 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 10734 } 10735 10736 namespace { 10737 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 10738 DSAStackTy *Stack; 10739 10740 public: 10741 bool VisitDeclRefExpr(DeclRefExpr *E) { 10742 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 10743 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 10744 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 10745 return false; 10746 if (DVar.CKind != OMPC_unknown) 10747 return true; 10748 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 10749 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 10750 /*FromParent=*/true); 10751 return DVarPrivate.CKind != OMPC_unknown; 10752 } 10753 return false; 10754 } 10755 bool VisitStmt(Stmt *S) { 10756 for (Stmt *Child : S->children()) { 10757 if (Child && Visit(Child)) 10758 return true; 10759 } 10760 return false; 10761 } 10762 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 10763 }; 10764 } // namespace 10765 10766 namespace { 10767 // Transform MemberExpression for specified FieldDecl of current class to 10768 // DeclRefExpr to specified OMPCapturedExprDecl. 10769 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 10770 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 10771 ValueDecl *Field = nullptr; 10772 DeclRefExpr *CapturedExpr = nullptr; 10773 10774 public: 10775 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 10776 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 10777 10778 ExprResult TransformMemberExpr(MemberExpr *E) { 10779 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 10780 E->getMemberDecl() == Field) { 10781 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 10782 return CapturedExpr; 10783 } 10784 return BaseTransform::TransformMemberExpr(E); 10785 } 10786 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 10787 }; 10788 } // namespace 10789 10790 template <typename T, typename U> 10791 static T filterLookupForUDReductionAndMapper( 10792 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 10793 for (U &Set : Lookups) { 10794 for (auto *D : Set) { 10795 if (T Res = Gen(cast<ValueDecl>(D))) 10796 return Res; 10797 } 10798 } 10799 return T(); 10800 } 10801 10802 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 10803 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 10804 10805 for (auto RD : D->redecls()) { 10806 // Don't bother with extra checks if we already know this one isn't visible. 10807 if (RD == D) 10808 continue; 10809 10810 auto ND = cast<NamedDecl>(RD); 10811 if (LookupResult::isVisible(SemaRef, ND)) 10812 return ND; 10813 } 10814 10815 return nullptr; 10816 } 10817 10818 static void 10819 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 10820 SourceLocation Loc, QualType Ty, 10821 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 10822 // Find all of the associated namespaces and classes based on the 10823 // arguments we have. 10824 Sema::AssociatedNamespaceSet AssociatedNamespaces; 10825 Sema::AssociatedClassSet AssociatedClasses; 10826 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 10827 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 10828 AssociatedClasses); 10829 10830 // C++ [basic.lookup.argdep]p3: 10831 // Let X be the lookup set produced by unqualified lookup (3.4.1) 10832 // and let Y be the lookup set produced by argument dependent 10833 // lookup (defined as follows). If X contains [...] then Y is 10834 // empty. Otherwise Y is the set of declarations found in the 10835 // namespaces associated with the argument types as described 10836 // below. The set of declarations found by the lookup of the name 10837 // is the union of X and Y. 10838 // 10839 // Here, we compute Y and add its members to the overloaded 10840 // candidate set. 10841 for (auto *NS : AssociatedNamespaces) { 10842 // When considering an associated namespace, the lookup is the 10843 // same as the lookup performed when the associated namespace is 10844 // used as a qualifier (3.4.3.2) except that: 10845 // 10846 // -- Any using-directives in the associated namespace are 10847 // ignored. 10848 // 10849 // -- Any namespace-scope friend functions declared in 10850 // associated classes are visible within their respective 10851 // namespaces even if they are not visible during an ordinary 10852 // lookup (11.4). 10853 DeclContext::lookup_result R = NS->lookup(Id.getName()); 10854 for (auto *D : R) { 10855 auto *Underlying = D; 10856 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10857 Underlying = USD->getTargetDecl(); 10858 10859 if (!isa<OMPDeclareReductionDecl>(Underlying) && 10860 !isa<OMPDeclareMapperDecl>(Underlying)) 10861 continue; 10862 10863 if (!SemaRef.isVisible(D)) { 10864 D = findAcceptableDecl(SemaRef, D); 10865 if (!D) 10866 continue; 10867 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10868 Underlying = USD->getTargetDecl(); 10869 } 10870 Lookups.emplace_back(); 10871 Lookups.back().addDecl(Underlying); 10872 } 10873 } 10874 } 10875 10876 static ExprResult 10877 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 10878 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 10879 const DeclarationNameInfo &ReductionId, QualType Ty, 10880 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 10881 if (ReductionIdScopeSpec.isInvalid()) 10882 return ExprError(); 10883 SmallVector<UnresolvedSet<8>, 4> Lookups; 10884 if (S) { 10885 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10886 Lookup.suppressDiagnostics(); 10887 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 10888 NamedDecl *D = Lookup.getRepresentativeDecl(); 10889 do { 10890 S = S->getParent(); 10891 } while (S && !S->isDeclScope(D)); 10892 if (S) 10893 S = S->getParent(); 10894 Lookups.emplace_back(); 10895 Lookups.back().append(Lookup.begin(), Lookup.end()); 10896 Lookup.clear(); 10897 } 10898 } else if (auto *ULE = 10899 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 10900 Lookups.push_back(UnresolvedSet<8>()); 10901 Decl *PrevD = nullptr; 10902 for (NamedDecl *D : ULE->decls()) { 10903 if (D == PrevD) 10904 Lookups.push_back(UnresolvedSet<8>()); 10905 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 10906 Lookups.back().addDecl(DRD); 10907 PrevD = D; 10908 } 10909 } 10910 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 10911 Ty->isInstantiationDependentType() || 10912 Ty->containsUnexpandedParameterPack() || 10913 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 10914 return !D->isInvalidDecl() && 10915 (D->getType()->isDependentType() || 10916 D->getType()->isInstantiationDependentType() || 10917 D->getType()->containsUnexpandedParameterPack()); 10918 })) { 10919 UnresolvedSet<8> ResSet; 10920 for (const UnresolvedSet<8> &Set : Lookups) { 10921 if (Set.empty()) 10922 continue; 10923 ResSet.append(Set.begin(), Set.end()); 10924 // The last item marks the end of all declarations at the specified scope. 10925 ResSet.addDecl(Set[Set.size() - 1]); 10926 } 10927 return UnresolvedLookupExpr::Create( 10928 SemaRef.Context, /*NamingClass=*/nullptr, 10929 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 10930 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 10931 } 10932 // Lookup inside the classes. 10933 // C++ [over.match.oper]p3: 10934 // For a unary operator @ with an operand of a type whose 10935 // cv-unqualified version is T1, and for a binary operator @ with 10936 // a left operand of a type whose cv-unqualified version is T1 and 10937 // a right operand of a type whose cv-unqualified version is T2, 10938 // three sets of candidate functions, designated member 10939 // candidates, non-member candidates and built-in candidates, are 10940 // constructed as follows: 10941 // -- If T1 is a complete class type or a class currently being 10942 // defined, the set of member candidates is the result of the 10943 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 10944 // the set of member candidates is empty. 10945 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10946 Lookup.suppressDiagnostics(); 10947 if (const auto *TyRec = Ty->getAs<RecordType>()) { 10948 // Complete the type if it can be completed. 10949 // If the type is neither complete nor being defined, bail out now. 10950 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 10951 TyRec->getDecl()->getDefinition()) { 10952 Lookup.clear(); 10953 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 10954 if (Lookup.empty()) { 10955 Lookups.emplace_back(); 10956 Lookups.back().append(Lookup.begin(), Lookup.end()); 10957 } 10958 } 10959 } 10960 // Perform ADL. 10961 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 10962 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 10963 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 10964 if (!D->isInvalidDecl() && 10965 SemaRef.Context.hasSameType(D->getType(), Ty)) 10966 return D; 10967 return nullptr; 10968 })) 10969 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 10970 VK_LValue, Loc); 10971 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 10972 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 10973 if (!D->isInvalidDecl() && 10974 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 10975 !Ty.isMoreQualifiedThan(D->getType())) 10976 return D; 10977 return nullptr; 10978 })) { 10979 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 10980 /*DetectVirtual=*/false); 10981 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 10982 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 10983 VD->getType().getUnqualifiedType()))) { 10984 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 10985 /*DiagID=*/0) != 10986 Sema::AR_inaccessible) { 10987 SemaRef.BuildBasePathArray(Paths, BasePath); 10988 return SemaRef.BuildDeclRefExpr( 10989 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 10990 } 10991 } 10992 } 10993 } 10994 if (ReductionIdScopeSpec.isSet()) { 10995 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 10996 return ExprError(); 10997 } 10998 return ExprEmpty(); 10999 } 11000 11001 namespace { 11002 /// Data for the reduction-based clauses. 11003 struct ReductionData { 11004 /// List of original reduction items. 11005 SmallVector<Expr *, 8> Vars; 11006 /// List of private copies of the reduction items. 11007 SmallVector<Expr *, 8> Privates; 11008 /// LHS expressions for the reduction_op expressions. 11009 SmallVector<Expr *, 8> LHSs; 11010 /// RHS expressions for the reduction_op expressions. 11011 SmallVector<Expr *, 8> RHSs; 11012 /// Reduction operation expression. 11013 SmallVector<Expr *, 8> ReductionOps; 11014 /// Taskgroup descriptors for the corresponding reduction items in 11015 /// in_reduction clauses. 11016 SmallVector<Expr *, 8> TaskgroupDescriptors; 11017 /// List of captures for clause. 11018 SmallVector<Decl *, 4> ExprCaptures; 11019 /// List of postupdate expressions. 11020 SmallVector<Expr *, 4> ExprPostUpdates; 11021 ReductionData() = delete; 11022 /// Reserves required memory for the reduction data. 11023 ReductionData(unsigned Size) { 11024 Vars.reserve(Size); 11025 Privates.reserve(Size); 11026 LHSs.reserve(Size); 11027 RHSs.reserve(Size); 11028 ReductionOps.reserve(Size); 11029 TaskgroupDescriptors.reserve(Size); 11030 ExprCaptures.reserve(Size); 11031 ExprPostUpdates.reserve(Size); 11032 } 11033 /// Stores reduction item and reduction operation only (required for dependent 11034 /// reduction item). 11035 void push(Expr *Item, Expr *ReductionOp) { 11036 Vars.emplace_back(Item); 11037 Privates.emplace_back(nullptr); 11038 LHSs.emplace_back(nullptr); 11039 RHSs.emplace_back(nullptr); 11040 ReductionOps.emplace_back(ReductionOp); 11041 TaskgroupDescriptors.emplace_back(nullptr); 11042 } 11043 /// Stores reduction data. 11044 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11045 Expr *TaskgroupDescriptor) { 11046 Vars.emplace_back(Item); 11047 Privates.emplace_back(Private); 11048 LHSs.emplace_back(LHS); 11049 RHSs.emplace_back(RHS); 11050 ReductionOps.emplace_back(ReductionOp); 11051 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11052 } 11053 }; 11054 } // namespace 11055 11056 static bool checkOMPArraySectionConstantForReduction( 11057 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11058 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11059 const Expr *Length = OASE->getLength(); 11060 if (Length == nullptr) { 11061 // For array sections of the form [1:] or [:], we would need to analyze 11062 // the lower bound... 11063 if (OASE->getColonLoc().isValid()) 11064 return false; 11065 11066 // This is an array subscript which has implicit length 1! 11067 SingleElement = true; 11068 ArraySizes.push_back(llvm::APSInt::get(1)); 11069 } else { 11070 Expr::EvalResult Result; 11071 if (!Length->EvaluateAsInt(Result, Context)) 11072 return false; 11073 11074 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11075 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11076 ArraySizes.push_back(ConstantLengthValue); 11077 } 11078 11079 // Get the base of this array section and walk up from there. 11080 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11081 11082 // We require length = 1 for all array sections except the right-most to 11083 // guarantee that the memory region is contiguous and has no holes in it. 11084 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11085 Length = TempOASE->getLength(); 11086 if (Length == nullptr) { 11087 // For array sections of the form [1:] or [:], we would need to analyze 11088 // the lower bound... 11089 if (OASE->getColonLoc().isValid()) 11090 return false; 11091 11092 // This is an array subscript which has implicit length 1! 11093 ArraySizes.push_back(llvm::APSInt::get(1)); 11094 } else { 11095 Expr::EvalResult Result; 11096 if (!Length->EvaluateAsInt(Result, Context)) 11097 return false; 11098 11099 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11100 if (ConstantLengthValue.getSExtValue() != 1) 11101 return false; 11102 11103 ArraySizes.push_back(ConstantLengthValue); 11104 } 11105 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11106 } 11107 11108 // If we have a single element, we don't need to add the implicit lengths. 11109 if (!SingleElement) { 11110 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11111 // Has implicit length 1! 11112 ArraySizes.push_back(llvm::APSInt::get(1)); 11113 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11114 } 11115 } 11116 11117 // This array section can be privatized as a single value or as a constant 11118 // sized array. 11119 return true; 11120 } 11121 11122 static bool actOnOMPReductionKindClause( 11123 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11124 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11125 SourceLocation ColonLoc, SourceLocation EndLoc, 11126 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11127 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11128 DeclarationName DN = ReductionId.getName(); 11129 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11130 BinaryOperatorKind BOK = BO_Comma; 11131 11132 ASTContext &Context = S.Context; 11133 // OpenMP [2.14.3.6, reduction clause] 11134 // C 11135 // reduction-identifier is either an identifier or one of the following 11136 // operators: +, -, *, &, |, ^, && and || 11137 // C++ 11138 // reduction-identifier is either an id-expression or one of the following 11139 // operators: +, -, *, &, |, ^, && and || 11140 switch (OOK) { 11141 case OO_Plus: 11142 case OO_Minus: 11143 BOK = BO_Add; 11144 break; 11145 case OO_Star: 11146 BOK = BO_Mul; 11147 break; 11148 case OO_Amp: 11149 BOK = BO_And; 11150 break; 11151 case OO_Pipe: 11152 BOK = BO_Or; 11153 break; 11154 case OO_Caret: 11155 BOK = BO_Xor; 11156 break; 11157 case OO_AmpAmp: 11158 BOK = BO_LAnd; 11159 break; 11160 case OO_PipePipe: 11161 BOK = BO_LOr; 11162 break; 11163 case OO_New: 11164 case OO_Delete: 11165 case OO_Array_New: 11166 case OO_Array_Delete: 11167 case OO_Slash: 11168 case OO_Percent: 11169 case OO_Tilde: 11170 case OO_Exclaim: 11171 case OO_Equal: 11172 case OO_Less: 11173 case OO_Greater: 11174 case OO_LessEqual: 11175 case OO_GreaterEqual: 11176 case OO_PlusEqual: 11177 case OO_MinusEqual: 11178 case OO_StarEqual: 11179 case OO_SlashEqual: 11180 case OO_PercentEqual: 11181 case OO_CaretEqual: 11182 case OO_AmpEqual: 11183 case OO_PipeEqual: 11184 case OO_LessLess: 11185 case OO_GreaterGreater: 11186 case OO_LessLessEqual: 11187 case OO_GreaterGreaterEqual: 11188 case OO_EqualEqual: 11189 case OO_ExclaimEqual: 11190 case OO_Spaceship: 11191 case OO_PlusPlus: 11192 case OO_MinusMinus: 11193 case OO_Comma: 11194 case OO_ArrowStar: 11195 case OO_Arrow: 11196 case OO_Call: 11197 case OO_Subscript: 11198 case OO_Conditional: 11199 case OO_Coawait: 11200 case NUM_OVERLOADED_OPERATORS: 11201 llvm_unreachable("Unexpected reduction identifier"); 11202 case OO_None: 11203 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11204 if (II->isStr("max")) 11205 BOK = BO_GT; 11206 else if (II->isStr("min")) 11207 BOK = BO_LT; 11208 } 11209 break; 11210 } 11211 SourceRange ReductionIdRange; 11212 if (ReductionIdScopeSpec.isValid()) 11213 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11214 else 11215 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11216 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11217 11218 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11219 bool FirstIter = true; 11220 for (Expr *RefExpr : VarList) { 11221 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11222 // OpenMP [2.1, C/C++] 11223 // A list item is a variable or array section, subject to the restrictions 11224 // specified in Section 2.4 on page 42 and in each of the sections 11225 // describing clauses and directives for which a list appears. 11226 // OpenMP [2.14.3.3, Restrictions, p.1] 11227 // A variable that is part of another variable (as an array or 11228 // structure element) cannot appear in a private clause. 11229 if (!FirstIter && IR != ER) 11230 ++IR; 11231 FirstIter = false; 11232 SourceLocation ELoc; 11233 SourceRange ERange; 11234 Expr *SimpleRefExpr = RefExpr; 11235 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11236 /*AllowArraySection=*/true); 11237 if (Res.second) { 11238 // Try to find 'declare reduction' corresponding construct before using 11239 // builtin/overloaded operators. 11240 QualType Type = Context.DependentTy; 11241 CXXCastPath BasePath; 11242 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11243 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11244 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11245 Expr *ReductionOp = nullptr; 11246 if (S.CurContext->isDependentContext() && 11247 (DeclareReductionRef.isUnset() || 11248 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11249 ReductionOp = DeclareReductionRef.get(); 11250 // It will be analyzed later. 11251 RD.push(RefExpr, ReductionOp); 11252 } 11253 ValueDecl *D = Res.first; 11254 if (!D) 11255 continue; 11256 11257 Expr *TaskgroupDescriptor = nullptr; 11258 QualType Type; 11259 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11260 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11261 if (ASE) { 11262 Type = ASE->getType().getNonReferenceType(); 11263 } else if (OASE) { 11264 QualType BaseType = 11265 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11266 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11267 Type = ATy->getElementType(); 11268 else 11269 Type = BaseType->getPointeeType(); 11270 Type = Type.getNonReferenceType(); 11271 } else { 11272 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11273 } 11274 auto *VD = dyn_cast<VarDecl>(D); 11275 11276 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11277 // A variable that appears in a private clause must not have an incomplete 11278 // type or a reference type. 11279 if (S.RequireCompleteType(ELoc, D->getType(), 11280 diag::err_omp_reduction_incomplete_type)) 11281 continue; 11282 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11283 // A list item that appears in a reduction clause must not be 11284 // const-qualified. 11285 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11286 /*AcceptIfMutable*/ false, ASE || OASE)) 11287 continue; 11288 11289 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11290 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11291 // If a list-item is a reference type then it must bind to the same object 11292 // for all threads of the team. 11293 if (!ASE && !OASE) { 11294 if (VD) { 11295 VarDecl *VDDef = VD->getDefinition(); 11296 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11297 DSARefChecker Check(Stack); 11298 if (Check.Visit(VDDef->getInit())) { 11299 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11300 << getOpenMPClauseName(ClauseKind) << ERange; 11301 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11302 continue; 11303 } 11304 } 11305 } 11306 11307 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11308 // in a Construct] 11309 // Variables with the predetermined data-sharing attributes may not be 11310 // listed in data-sharing attributes clauses, except for the cases 11311 // listed below. For these exceptions only, listing a predetermined 11312 // variable in a data-sharing attribute clause is allowed and overrides 11313 // the variable's predetermined data-sharing attributes. 11314 // OpenMP [2.14.3.6, Restrictions, p.3] 11315 // Any number of reduction clauses can be specified on the directive, 11316 // but a list item can appear only once in the reduction clauses for that 11317 // directive. 11318 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11319 if (DVar.CKind == OMPC_reduction) { 11320 S.Diag(ELoc, diag::err_omp_once_referenced) 11321 << getOpenMPClauseName(ClauseKind); 11322 if (DVar.RefExpr) 11323 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 11324 continue; 11325 } 11326 if (DVar.CKind != OMPC_unknown) { 11327 S.Diag(ELoc, diag::err_omp_wrong_dsa) 11328 << getOpenMPClauseName(DVar.CKind) 11329 << getOpenMPClauseName(OMPC_reduction); 11330 reportOriginalDsa(S, Stack, D, DVar); 11331 continue; 11332 } 11333 11334 // OpenMP [2.14.3.6, Restrictions, p.1] 11335 // A list item that appears in a reduction clause of a worksharing 11336 // construct must be shared in the parallel regions to which any of the 11337 // worksharing regions arising from the worksharing construct bind. 11338 if (isOpenMPWorksharingDirective(CurrDir) && 11339 !isOpenMPParallelDirective(CurrDir) && 11340 !isOpenMPTeamsDirective(CurrDir)) { 11341 DVar = Stack->getImplicitDSA(D, true); 11342 if (DVar.CKind != OMPC_shared) { 11343 S.Diag(ELoc, diag::err_omp_required_access) 11344 << getOpenMPClauseName(OMPC_reduction) 11345 << getOpenMPClauseName(OMPC_shared); 11346 reportOriginalDsa(S, Stack, D, DVar); 11347 continue; 11348 } 11349 } 11350 } 11351 11352 // Try to find 'declare reduction' corresponding construct before using 11353 // builtin/overloaded operators. 11354 CXXCastPath BasePath; 11355 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11356 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11357 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11358 if (DeclareReductionRef.isInvalid()) 11359 continue; 11360 if (S.CurContext->isDependentContext() && 11361 (DeclareReductionRef.isUnset() || 11362 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 11363 RD.push(RefExpr, DeclareReductionRef.get()); 11364 continue; 11365 } 11366 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 11367 // Not allowed reduction identifier is found. 11368 S.Diag(ReductionId.getBeginLoc(), 11369 diag::err_omp_unknown_reduction_identifier) 11370 << Type << ReductionIdRange; 11371 continue; 11372 } 11373 11374 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11375 // The type of a list item that appears in a reduction clause must be valid 11376 // for the reduction-identifier. For a max or min reduction in C, the type 11377 // of the list item must be an allowed arithmetic data type: char, int, 11378 // float, double, or _Bool, possibly modified with long, short, signed, or 11379 // unsigned. For a max or min reduction in C++, the type of the list item 11380 // must be an allowed arithmetic data type: char, wchar_t, int, float, 11381 // double, or bool, possibly modified with long, short, signed, or unsigned. 11382 if (DeclareReductionRef.isUnset()) { 11383 if ((BOK == BO_GT || BOK == BO_LT) && 11384 !(Type->isScalarType() || 11385 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 11386 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 11387 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 11388 if (!ASE && !OASE) { 11389 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11390 VarDecl::DeclarationOnly; 11391 S.Diag(D->getLocation(), 11392 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11393 << D; 11394 } 11395 continue; 11396 } 11397 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 11398 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 11399 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 11400 << getOpenMPClauseName(ClauseKind); 11401 if (!ASE && !OASE) { 11402 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11403 VarDecl::DeclarationOnly; 11404 S.Diag(D->getLocation(), 11405 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11406 << D; 11407 } 11408 continue; 11409 } 11410 } 11411 11412 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 11413 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 11414 D->hasAttrs() ? &D->getAttrs() : nullptr); 11415 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 11416 D->hasAttrs() ? &D->getAttrs() : nullptr); 11417 QualType PrivateTy = Type; 11418 11419 // Try if we can determine constant lengths for all array sections and avoid 11420 // the VLA. 11421 bool ConstantLengthOASE = false; 11422 if (OASE) { 11423 bool SingleElement; 11424 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 11425 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 11426 Context, OASE, SingleElement, ArraySizes); 11427 11428 // If we don't have a single element, we must emit a constant array type. 11429 if (ConstantLengthOASE && !SingleElement) { 11430 for (llvm::APSInt &Size : ArraySizes) 11431 PrivateTy = Context.getConstantArrayType( 11432 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 11433 } 11434 } 11435 11436 if ((OASE && !ConstantLengthOASE) || 11437 (!OASE && !ASE && 11438 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 11439 if (!Context.getTargetInfo().isVLASupported() && 11440 S.shouldDiagnoseTargetSupportFromOpenMP()) { 11441 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 11442 S.Diag(ELoc, diag::note_vla_unsupported); 11443 continue; 11444 } 11445 // For arrays/array sections only: 11446 // Create pseudo array type for private copy. The size for this array will 11447 // be generated during codegen. 11448 // For array subscripts or single variables Private Ty is the same as Type 11449 // (type of the variable or single array element). 11450 PrivateTy = Context.getVariableArrayType( 11451 Type, 11452 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 11453 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 11454 } else if (!ASE && !OASE && 11455 Context.getAsArrayType(D->getType().getNonReferenceType())) { 11456 PrivateTy = D->getType().getNonReferenceType(); 11457 } 11458 // Private copy. 11459 VarDecl *PrivateVD = 11460 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 11461 D->hasAttrs() ? &D->getAttrs() : nullptr, 11462 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11463 // Add initializer for private variable. 11464 Expr *Init = nullptr; 11465 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 11466 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 11467 if (DeclareReductionRef.isUsable()) { 11468 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 11469 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 11470 if (DRD->getInitializer()) { 11471 Init = DRDRef; 11472 RHSVD->setInit(DRDRef); 11473 RHSVD->setInitStyle(VarDecl::CallInit); 11474 } 11475 } else { 11476 switch (BOK) { 11477 case BO_Add: 11478 case BO_Xor: 11479 case BO_Or: 11480 case BO_LOr: 11481 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 11482 if (Type->isScalarType() || Type->isAnyComplexType()) 11483 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 11484 break; 11485 case BO_Mul: 11486 case BO_LAnd: 11487 if (Type->isScalarType() || Type->isAnyComplexType()) { 11488 // '*' and '&&' reduction ops - initializer is '1'. 11489 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 11490 } 11491 break; 11492 case BO_And: { 11493 // '&' reduction op - initializer is '~0'. 11494 QualType OrigType = Type; 11495 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 11496 Type = ComplexTy->getElementType(); 11497 if (Type->isRealFloatingType()) { 11498 llvm::APFloat InitValue = 11499 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 11500 /*isIEEE=*/true); 11501 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11502 Type, ELoc); 11503 } else if (Type->isScalarType()) { 11504 uint64_t Size = Context.getTypeSize(Type); 11505 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 11506 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 11507 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11508 } 11509 if (Init && OrigType->isAnyComplexType()) { 11510 // Init = 0xFFFF + 0xFFFFi; 11511 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 11512 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 11513 } 11514 Type = OrigType; 11515 break; 11516 } 11517 case BO_LT: 11518 case BO_GT: { 11519 // 'min' reduction op - initializer is 'Largest representable number in 11520 // the reduction list item type'. 11521 // 'max' reduction op - initializer is 'Least representable number in 11522 // the reduction list item type'. 11523 if (Type->isIntegerType() || Type->isPointerType()) { 11524 bool IsSigned = Type->hasSignedIntegerRepresentation(); 11525 uint64_t Size = Context.getTypeSize(Type); 11526 QualType IntTy = 11527 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 11528 llvm::APInt InitValue = 11529 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 11530 : llvm::APInt::getMinValue(Size) 11531 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 11532 : llvm::APInt::getMaxValue(Size); 11533 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11534 if (Type->isPointerType()) { 11535 // Cast to pointer type. 11536 ExprResult CastExpr = S.BuildCStyleCastExpr( 11537 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 11538 if (CastExpr.isInvalid()) 11539 continue; 11540 Init = CastExpr.get(); 11541 } 11542 } else if (Type->isRealFloatingType()) { 11543 llvm::APFloat InitValue = llvm::APFloat::getLargest( 11544 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 11545 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11546 Type, ELoc); 11547 } 11548 break; 11549 } 11550 case BO_PtrMemD: 11551 case BO_PtrMemI: 11552 case BO_MulAssign: 11553 case BO_Div: 11554 case BO_Rem: 11555 case BO_Sub: 11556 case BO_Shl: 11557 case BO_Shr: 11558 case BO_LE: 11559 case BO_GE: 11560 case BO_EQ: 11561 case BO_NE: 11562 case BO_Cmp: 11563 case BO_AndAssign: 11564 case BO_XorAssign: 11565 case BO_OrAssign: 11566 case BO_Assign: 11567 case BO_AddAssign: 11568 case BO_SubAssign: 11569 case BO_DivAssign: 11570 case BO_RemAssign: 11571 case BO_ShlAssign: 11572 case BO_ShrAssign: 11573 case BO_Comma: 11574 llvm_unreachable("Unexpected reduction operation"); 11575 } 11576 } 11577 if (Init && DeclareReductionRef.isUnset()) 11578 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 11579 else if (!Init) 11580 S.ActOnUninitializedDecl(RHSVD); 11581 if (RHSVD->isInvalidDecl()) 11582 continue; 11583 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 11584 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 11585 << Type << ReductionIdRange; 11586 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11587 VarDecl::DeclarationOnly; 11588 S.Diag(D->getLocation(), 11589 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11590 << D; 11591 continue; 11592 } 11593 // Store initializer for single element in private copy. Will be used during 11594 // codegen. 11595 PrivateVD->setInit(RHSVD->getInit()); 11596 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 11597 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 11598 ExprResult ReductionOp; 11599 if (DeclareReductionRef.isUsable()) { 11600 QualType RedTy = DeclareReductionRef.get()->getType(); 11601 QualType PtrRedTy = Context.getPointerType(RedTy); 11602 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 11603 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 11604 if (!BasePath.empty()) { 11605 LHS = S.DefaultLvalueConversion(LHS.get()); 11606 RHS = S.DefaultLvalueConversion(RHS.get()); 11607 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11608 CK_UncheckedDerivedToBase, LHS.get(), 11609 &BasePath, LHS.get()->getValueKind()); 11610 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11611 CK_UncheckedDerivedToBase, RHS.get(), 11612 &BasePath, RHS.get()->getValueKind()); 11613 } 11614 FunctionProtoType::ExtProtoInfo EPI; 11615 QualType Params[] = {PtrRedTy, PtrRedTy}; 11616 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 11617 auto *OVE = new (Context) OpaqueValueExpr( 11618 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 11619 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 11620 Expr *Args[] = {LHS.get(), RHS.get()}; 11621 ReductionOp = 11622 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 11623 } else { 11624 ReductionOp = S.BuildBinOp( 11625 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 11626 if (ReductionOp.isUsable()) { 11627 if (BOK != BO_LT && BOK != BO_GT) { 11628 ReductionOp = 11629 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11630 BO_Assign, LHSDRE, ReductionOp.get()); 11631 } else { 11632 auto *ConditionalOp = new (Context) 11633 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 11634 Type, VK_LValue, OK_Ordinary); 11635 ReductionOp = 11636 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11637 BO_Assign, LHSDRE, ConditionalOp); 11638 } 11639 if (ReductionOp.isUsable()) 11640 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 11641 /*DiscardedValue*/ false); 11642 } 11643 if (!ReductionOp.isUsable()) 11644 continue; 11645 } 11646 11647 // OpenMP [2.15.4.6, Restrictions, p.2] 11648 // A list item that appears in an in_reduction clause of a task construct 11649 // must appear in a task_reduction clause of a construct associated with a 11650 // taskgroup region that includes the participating task in its taskgroup 11651 // set. The construct associated with the innermost region that meets this 11652 // condition must specify the same reduction-identifier as the in_reduction 11653 // clause. 11654 if (ClauseKind == OMPC_in_reduction) { 11655 SourceRange ParentSR; 11656 BinaryOperatorKind ParentBOK; 11657 const Expr *ParentReductionOp; 11658 Expr *ParentBOKTD, *ParentReductionOpTD; 11659 DSAStackTy::DSAVarData ParentBOKDSA = 11660 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 11661 ParentBOKTD); 11662 DSAStackTy::DSAVarData ParentReductionOpDSA = 11663 Stack->getTopMostTaskgroupReductionData( 11664 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 11665 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 11666 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 11667 if (!IsParentBOK && !IsParentReductionOp) { 11668 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 11669 continue; 11670 } 11671 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 11672 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 11673 IsParentReductionOp) { 11674 bool EmitError = true; 11675 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 11676 llvm::FoldingSetNodeID RedId, ParentRedId; 11677 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 11678 DeclareReductionRef.get()->Profile(RedId, Context, 11679 /*Canonical=*/true); 11680 EmitError = RedId != ParentRedId; 11681 } 11682 if (EmitError) { 11683 S.Diag(ReductionId.getBeginLoc(), 11684 diag::err_omp_reduction_identifier_mismatch) 11685 << ReductionIdRange << RefExpr->getSourceRange(); 11686 S.Diag(ParentSR.getBegin(), 11687 diag::note_omp_previous_reduction_identifier) 11688 << ParentSR 11689 << (IsParentBOK ? ParentBOKDSA.RefExpr 11690 : ParentReductionOpDSA.RefExpr) 11691 ->getSourceRange(); 11692 continue; 11693 } 11694 } 11695 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 11696 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 11697 } 11698 11699 DeclRefExpr *Ref = nullptr; 11700 Expr *VarsExpr = RefExpr->IgnoreParens(); 11701 if (!VD && !S.CurContext->isDependentContext()) { 11702 if (ASE || OASE) { 11703 TransformExprToCaptures RebuildToCapture(S, D); 11704 VarsExpr = 11705 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 11706 Ref = RebuildToCapture.getCapturedExpr(); 11707 } else { 11708 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 11709 } 11710 if (!S.isOpenMPCapturedDecl(D)) { 11711 RD.ExprCaptures.emplace_back(Ref->getDecl()); 11712 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11713 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 11714 if (!RefRes.isUsable()) 11715 continue; 11716 ExprResult PostUpdateRes = 11717 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11718 RefRes.get()); 11719 if (!PostUpdateRes.isUsable()) 11720 continue; 11721 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 11722 Stack->getCurrentDirective() == OMPD_taskgroup) { 11723 S.Diag(RefExpr->getExprLoc(), 11724 diag::err_omp_reduction_non_addressable_expression) 11725 << RefExpr->getSourceRange(); 11726 continue; 11727 } 11728 RD.ExprPostUpdates.emplace_back( 11729 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 11730 } 11731 } 11732 } 11733 // All reduction items are still marked as reduction (to do not increase 11734 // code base size). 11735 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 11736 if (CurrDir == OMPD_taskgroup) { 11737 if (DeclareReductionRef.isUsable()) 11738 Stack->addTaskgroupReductionData(D, ReductionIdRange, 11739 DeclareReductionRef.get()); 11740 else 11741 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 11742 } 11743 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 11744 TaskgroupDescriptor); 11745 } 11746 return RD.Vars.empty(); 11747 } 11748 11749 OMPClause *Sema::ActOnOpenMPReductionClause( 11750 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11751 SourceLocation ColonLoc, SourceLocation EndLoc, 11752 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11753 ArrayRef<Expr *> UnresolvedReductions) { 11754 ReductionData RD(VarList.size()); 11755 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 11756 StartLoc, LParenLoc, ColonLoc, EndLoc, 11757 ReductionIdScopeSpec, ReductionId, 11758 UnresolvedReductions, RD)) 11759 return nullptr; 11760 11761 return OMPReductionClause::Create( 11762 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11763 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11764 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11765 buildPreInits(Context, RD.ExprCaptures), 11766 buildPostUpdate(*this, RD.ExprPostUpdates)); 11767 } 11768 11769 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 11770 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11771 SourceLocation ColonLoc, SourceLocation EndLoc, 11772 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11773 ArrayRef<Expr *> UnresolvedReductions) { 11774 ReductionData RD(VarList.size()); 11775 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 11776 StartLoc, LParenLoc, ColonLoc, EndLoc, 11777 ReductionIdScopeSpec, ReductionId, 11778 UnresolvedReductions, RD)) 11779 return nullptr; 11780 11781 return OMPTaskReductionClause::Create( 11782 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11783 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11784 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11785 buildPreInits(Context, RD.ExprCaptures), 11786 buildPostUpdate(*this, RD.ExprPostUpdates)); 11787 } 11788 11789 OMPClause *Sema::ActOnOpenMPInReductionClause( 11790 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11791 SourceLocation ColonLoc, SourceLocation EndLoc, 11792 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11793 ArrayRef<Expr *> UnresolvedReductions) { 11794 ReductionData RD(VarList.size()); 11795 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 11796 StartLoc, LParenLoc, ColonLoc, EndLoc, 11797 ReductionIdScopeSpec, ReductionId, 11798 UnresolvedReductions, RD)) 11799 return nullptr; 11800 11801 return OMPInReductionClause::Create( 11802 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11803 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11804 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 11805 buildPreInits(Context, RD.ExprCaptures), 11806 buildPostUpdate(*this, RD.ExprPostUpdates)); 11807 } 11808 11809 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 11810 SourceLocation LinLoc) { 11811 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 11812 LinKind == OMPC_LINEAR_unknown) { 11813 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 11814 return true; 11815 } 11816 return false; 11817 } 11818 11819 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 11820 OpenMPLinearClauseKind LinKind, 11821 QualType Type) { 11822 const auto *VD = dyn_cast_or_null<VarDecl>(D); 11823 // A variable must not have an incomplete type or a reference type. 11824 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 11825 return true; 11826 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 11827 !Type->isReferenceType()) { 11828 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 11829 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 11830 return true; 11831 } 11832 Type = Type.getNonReferenceType(); 11833 11834 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11835 // A variable that is privatized must not have a const-qualified type 11836 // unless it is of class type with a mutable member. This restriction does 11837 // not apply to the firstprivate clause. 11838 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 11839 return true; 11840 11841 // A list item must be of integral or pointer type. 11842 Type = Type.getUnqualifiedType().getCanonicalType(); 11843 const auto *Ty = Type.getTypePtrOrNull(); 11844 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 11845 !Ty->isPointerType())) { 11846 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 11847 if (D) { 11848 bool IsDecl = 11849 !VD || 11850 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11851 Diag(D->getLocation(), 11852 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11853 << D; 11854 } 11855 return true; 11856 } 11857 return false; 11858 } 11859 11860 OMPClause *Sema::ActOnOpenMPLinearClause( 11861 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 11862 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 11863 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11864 SmallVector<Expr *, 8> Vars; 11865 SmallVector<Expr *, 8> Privates; 11866 SmallVector<Expr *, 8> Inits; 11867 SmallVector<Decl *, 4> ExprCaptures; 11868 SmallVector<Expr *, 4> ExprPostUpdates; 11869 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 11870 LinKind = OMPC_LINEAR_val; 11871 for (Expr *RefExpr : VarList) { 11872 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11873 SourceLocation ELoc; 11874 SourceRange ERange; 11875 Expr *SimpleRefExpr = RefExpr; 11876 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11877 if (Res.second) { 11878 // It will be analyzed later. 11879 Vars.push_back(RefExpr); 11880 Privates.push_back(nullptr); 11881 Inits.push_back(nullptr); 11882 } 11883 ValueDecl *D = Res.first; 11884 if (!D) 11885 continue; 11886 11887 QualType Type = D->getType(); 11888 auto *VD = dyn_cast<VarDecl>(D); 11889 11890 // OpenMP [2.14.3.7, linear clause] 11891 // A list-item cannot appear in more than one linear clause. 11892 // A list-item that appears in a linear clause cannot appear in any 11893 // other data-sharing attribute clause. 11894 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11895 if (DVar.RefExpr) { 11896 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11897 << getOpenMPClauseName(OMPC_linear); 11898 reportOriginalDsa(*this, DSAStack, D, DVar); 11899 continue; 11900 } 11901 11902 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 11903 continue; 11904 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11905 11906 // Build private copy of original var. 11907 VarDecl *Private = 11908 buildVarDecl(*this, ELoc, Type, D->getName(), 11909 D->hasAttrs() ? &D->getAttrs() : nullptr, 11910 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11911 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 11912 // Build var to save initial value. 11913 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 11914 Expr *InitExpr; 11915 DeclRefExpr *Ref = nullptr; 11916 if (!VD && !CurContext->isDependentContext()) { 11917 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11918 if (!isOpenMPCapturedDecl(D)) { 11919 ExprCaptures.push_back(Ref->getDecl()); 11920 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11921 ExprResult RefRes = DefaultLvalueConversion(Ref); 11922 if (!RefRes.isUsable()) 11923 continue; 11924 ExprResult PostUpdateRes = 11925 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 11926 SimpleRefExpr, RefRes.get()); 11927 if (!PostUpdateRes.isUsable()) 11928 continue; 11929 ExprPostUpdates.push_back( 11930 IgnoredValueConversions(PostUpdateRes.get()).get()); 11931 } 11932 } 11933 } 11934 if (LinKind == OMPC_LINEAR_uval) 11935 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 11936 else 11937 InitExpr = VD ? SimpleRefExpr : Ref; 11938 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 11939 /*DirectInit=*/false); 11940 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 11941 11942 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 11943 Vars.push_back((VD || CurContext->isDependentContext()) 11944 ? RefExpr->IgnoreParens() 11945 : Ref); 11946 Privates.push_back(PrivateRef); 11947 Inits.push_back(InitRef); 11948 } 11949 11950 if (Vars.empty()) 11951 return nullptr; 11952 11953 Expr *StepExpr = Step; 11954 Expr *CalcStepExpr = nullptr; 11955 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 11956 !Step->isInstantiationDependent() && 11957 !Step->containsUnexpandedParameterPack()) { 11958 SourceLocation StepLoc = Step->getBeginLoc(); 11959 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 11960 if (Val.isInvalid()) 11961 return nullptr; 11962 StepExpr = Val.get(); 11963 11964 // Build var to save the step value. 11965 VarDecl *SaveVar = 11966 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 11967 ExprResult SaveRef = 11968 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 11969 ExprResult CalcStep = 11970 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 11971 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 11972 11973 // Warn about zero linear step (it would be probably better specified as 11974 // making corresponding variables 'const'). 11975 llvm::APSInt Result; 11976 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 11977 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 11978 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 11979 << (Vars.size() > 1); 11980 if (!IsConstant && CalcStep.isUsable()) { 11981 // Calculate the step beforehand instead of doing this on each iteration. 11982 // (This is not used if the number of iterations may be kfold-ed). 11983 CalcStepExpr = CalcStep.get(); 11984 } 11985 } 11986 11987 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 11988 ColonLoc, EndLoc, Vars, Privates, Inits, 11989 StepExpr, CalcStepExpr, 11990 buildPreInits(Context, ExprCaptures), 11991 buildPostUpdate(*this, ExprPostUpdates)); 11992 } 11993 11994 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 11995 Expr *NumIterations, Sema &SemaRef, 11996 Scope *S, DSAStackTy *Stack) { 11997 // Walk the vars and build update/final expressions for the CodeGen. 11998 SmallVector<Expr *, 8> Updates; 11999 SmallVector<Expr *, 8> Finals; 12000 Expr *Step = Clause.getStep(); 12001 Expr *CalcStep = Clause.getCalcStep(); 12002 // OpenMP [2.14.3.7, linear clause] 12003 // If linear-step is not specified it is assumed to be 1. 12004 if (!Step) 12005 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12006 else if (CalcStep) 12007 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12008 bool HasErrors = false; 12009 auto CurInit = Clause.inits().begin(); 12010 auto CurPrivate = Clause.privates().begin(); 12011 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12012 for (Expr *RefExpr : Clause.varlists()) { 12013 SourceLocation ELoc; 12014 SourceRange ERange; 12015 Expr *SimpleRefExpr = RefExpr; 12016 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12017 ValueDecl *D = Res.first; 12018 if (Res.second || !D) { 12019 Updates.push_back(nullptr); 12020 Finals.push_back(nullptr); 12021 HasErrors = true; 12022 continue; 12023 } 12024 auto &&Info = Stack->isLoopControlVariable(D); 12025 // OpenMP [2.15.11, distribute simd Construct] 12026 // A list item may not appear in a linear clause, unless it is the loop 12027 // iteration variable. 12028 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12029 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12030 SemaRef.Diag(ELoc, 12031 diag::err_omp_linear_distribute_var_non_loop_iteration); 12032 Updates.push_back(nullptr); 12033 Finals.push_back(nullptr); 12034 HasErrors = true; 12035 continue; 12036 } 12037 Expr *InitExpr = *CurInit; 12038 12039 // Build privatized reference to the current linear var. 12040 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12041 Expr *CapturedRef; 12042 if (LinKind == OMPC_LINEAR_uval) 12043 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12044 else 12045 CapturedRef = 12046 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12047 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12048 /*RefersToCapture=*/true); 12049 12050 // Build update: Var = InitExpr + IV * Step 12051 ExprResult Update; 12052 if (!Info.first) 12053 Update = 12054 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12055 InitExpr, IV, Step, /* Subtract */ false); 12056 else 12057 Update = *CurPrivate; 12058 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12059 /*DiscardedValue*/ false); 12060 12061 // Build final: Var = InitExpr + NumIterations * Step 12062 ExprResult Final; 12063 if (!Info.first) 12064 Final = 12065 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12066 InitExpr, NumIterations, Step, /*Subtract=*/false); 12067 else 12068 Final = *CurPrivate; 12069 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12070 /*DiscardedValue*/ false); 12071 12072 if (!Update.isUsable() || !Final.isUsable()) { 12073 Updates.push_back(nullptr); 12074 Finals.push_back(nullptr); 12075 HasErrors = true; 12076 } else { 12077 Updates.push_back(Update.get()); 12078 Finals.push_back(Final.get()); 12079 } 12080 ++CurInit; 12081 ++CurPrivate; 12082 } 12083 Clause.setUpdates(Updates); 12084 Clause.setFinals(Finals); 12085 return HasErrors; 12086 } 12087 12088 OMPClause *Sema::ActOnOpenMPAlignedClause( 12089 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12090 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12091 SmallVector<Expr *, 8> Vars; 12092 for (Expr *RefExpr : VarList) { 12093 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12094 SourceLocation ELoc; 12095 SourceRange ERange; 12096 Expr *SimpleRefExpr = RefExpr; 12097 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12098 if (Res.second) { 12099 // It will be analyzed later. 12100 Vars.push_back(RefExpr); 12101 } 12102 ValueDecl *D = Res.first; 12103 if (!D) 12104 continue; 12105 12106 QualType QType = D->getType(); 12107 auto *VD = dyn_cast<VarDecl>(D); 12108 12109 // OpenMP [2.8.1, simd construct, Restrictions] 12110 // The type of list items appearing in the aligned clause must be 12111 // array, pointer, reference to array, or reference to pointer. 12112 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12113 const Type *Ty = QType.getTypePtrOrNull(); 12114 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12115 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12116 << QType << getLangOpts().CPlusPlus << ERange; 12117 bool IsDecl = 12118 !VD || 12119 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12120 Diag(D->getLocation(), 12121 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12122 << D; 12123 continue; 12124 } 12125 12126 // OpenMP [2.8.1, simd construct, Restrictions] 12127 // A list-item cannot appear in more than one aligned clause. 12128 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12129 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12130 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12131 << getOpenMPClauseName(OMPC_aligned); 12132 continue; 12133 } 12134 12135 DeclRefExpr *Ref = nullptr; 12136 if (!VD && isOpenMPCapturedDecl(D)) 12137 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12138 Vars.push_back(DefaultFunctionArrayConversion( 12139 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12140 .get()); 12141 } 12142 12143 // OpenMP [2.8.1, simd construct, Description] 12144 // The parameter of the aligned clause, alignment, must be a constant 12145 // positive integer expression. 12146 // If no optional parameter is specified, implementation-defined default 12147 // alignments for SIMD instructions on the target platforms are assumed. 12148 if (Alignment != nullptr) { 12149 ExprResult AlignResult = 12150 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12151 if (AlignResult.isInvalid()) 12152 return nullptr; 12153 Alignment = AlignResult.get(); 12154 } 12155 if (Vars.empty()) 12156 return nullptr; 12157 12158 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12159 EndLoc, Vars, Alignment); 12160 } 12161 12162 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12163 SourceLocation StartLoc, 12164 SourceLocation LParenLoc, 12165 SourceLocation EndLoc) { 12166 SmallVector<Expr *, 8> Vars; 12167 SmallVector<Expr *, 8> SrcExprs; 12168 SmallVector<Expr *, 8> DstExprs; 12169 SmallVector<Expr *, 8> AssignmentOps; 12170 for (Expr *RefExpr : VarList) { 12171 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12172 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12173 // It will be analyzed later. 12174 Vars.push_back(RefExpr); 12175 SrcExprs.push_back(nullptr); 12176 DstExprs.push_back(nullptr); 12177 AssignmentOps.push_back(nullptr); 12178 continue; 12179 } 12180 12181 SourceLocation ELoc = RefExpr->getExprLoc(); 12182 // OpenMP [2.1, C/C++] 12183 // A list item is a variable name. 12184 // OpenMP [2.14.4.1, Restrictions, p.1] 12185 // A list item that appears in a copyin clause must be threadprivate. 12186 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12187 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12188 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12189 << 0 << RefExpr->getSourceRange(); 12190 continue; 12191 } 12192 12193 Decl *D = DE->getDecl(); 12194 auto *VD = cast<VarDecl>(D); 12195 12196 QualType Type = VD->getType(); 12197 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12198 // It will be analyzed later. 12199 Vars.push_back(DE); 12200 SrcExprs.push_back(nullptr); 12201 DstExprs.push_back(nullptr); 12202 AssignmentOps.push_back(nullptr); 12203 continue; 12204 } 12205 12206 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12207 // A list item that appears in a copyin clause must be threadprivate. 12208 if (!DSAStack->isThreadPrivate(VD)) { 12209 Diag(ELoc, diag::err_omp_required_access) 12210 << getOpenMPClauseName(OMPC_copyin) 12211 << getOpenMPDirectiveName(OMPD_threadprivate); 12212 continue; 12213 } 12214 12215 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12216 // A variable of class type (or array thereof) that appears in a 12217 // copyin clause requires an accessible, unambiguous copy assignment 12218 // operator for the class type. 12219 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12220 VarDecl *SrcVD = 12221 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12222 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12223 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12224 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12225 VarDecl *DstVD = 12226 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12227 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12228 DeclRefExpr *PseudoDstExpr = 12229 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12230 // For arrays generate assignment operation for single element and replace 12231 // it by the original array element in CodeGen. 12232 ExprResult AssignmentOp = 12233 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12234 PseudoSrcExpr); 12235 if (AssignmentOp.isInvalid()) 12236 continue; 12237 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12238 /*DiscardedValue*/ false); 12239 if (AssignmentOp.isInvalid()) 12240 continue; 12241 12242 DSAStack->addDSA(VD, DE, OMPC_copyin); 12243 Vars.push_back(DE); 12244 SrcExprs.push_back(PseudoSrcExpr); 12245 DstExprs.push_back(PseudoDstExpr); 12246 AssignmentOps.push_back(AssignmentOp.get()); 12247 } 12248 12249 if (Vars.empty()) 12250 return nullptr; 12251 12252 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12253 SrcExprs, DstExprs, AssignmentOps); 12254 } 12255 12256 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12257 SourceLocation StartLoc, 12258 SourceLocation LParenLoc, 12259 SourceLocation EndLoc) { 12260 SmallVector<Expr *, 8> Vars; 12261 SmallVector<Expr *, 8> SrcExprs; 12262 SmallVector<Expr *, 8> DstExprs; 12263 SmallVector<Expr *, 8> AssignmentOps; 12264 for (Expr *RefExpr : VarList) { 12265 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12266 SourceLocation ELoc; 12267 SourceRange ERange; 12268 Expr *SimpleRefExpr = RefExpr; 12269 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12270 if (Res.second) { 12271 // It will be analyzed later. 12272 Vars.push_back(RefExpr); 12273 SrcExprs.push_back(nullptr); 12274 DstExprs.push_back(nullptr); 12275 AssignmentOps.push_back(nullptr); 12276 } 12277 ValueDecl *D = Res.first; 12278 if (!D) 12279 continue; 12280 12281 QualType Type = D->getType(); 12282 auto *VD = dyn_cast<VarDecl>(D); 12283 12284 // OpenMP [2.14.4.2, Restrictions, p.2] 12285 // A list item that appears in a copyprivate clause may not appear in a 12286 // private or firstprivate clause on the single construct. 12287 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12288 DSAStackTy::DSAVarData DVar = 12289 DSAStack->getTopDSA(D, /*FromParent=*/false); 12290 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12291 DVar.RefExpr) { 12292 Diag(ELoc, diag::err_omp_wrong_dsa) 12293 << getOpenMPClauseName(DVar.CKind) 12294 << getOpenMPClauseName(OMPC_copyprivate); 12295 reportOriginalDsa(*this, DSAStack, D, DVar); 12296 continue; 12297 } 12298 12299 // OpenMP [2.11.4.2, Restrictions, p.1] 12300 // All list items that appear in a copyprivate clause must be either 12301 // threadprivate or private in the enclosing context. 12302 if (DVar.CKind == OMPC_unknown) { 12303 DVar = DSAStack->getImplicitDSA(D, false); 12304 if (DVar.CKind == OMPC_shared) { 12305 Diag(ELoc, diag::err_omp_required_access) 12306 << getOpenMPClauseName(OMPC_copyprivate) 12307 << "threadprivate or private in the enclosing context"; 12308 reportOriginalDsa(*this, DSAStack, D, DVar); 12309 continue; 12310 } 12311 } 12312 } 12313 12314 // Variably modified types are not supported. 12315 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12316 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12317 << getOpenMPClauseName(OMPC_copyprivate) << Type 12318 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12319 bool IsDecl = 12320 !VD || 12321 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12322 Diag(D->getLocation(), 12323 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12324 << D; 12325 continue; 12326 } 12327 12328 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12329 // A variable of class type (or array thereof) that appears in a 12330 // copyin clause requires an accessible, unambiguous copy assignment 12331 // operator for the class type. 12332 Type = Context.getBaseElementType(Type.getNonReferenceType()) 12333 .getUnqualifiedType(); 12334 VarDecl *SrcVD = 12335 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 12336 D->hasAttrs() ? &D->getAttrs() : nullptr); 12337 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 12338 VarDecl *DstVD = 12339 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 12340 D->hasAttrs() ? &D->getAttrs() : nullptr); 12341 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12342 ExprResult AssignmentOp = BuildBinOp( 12343 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 12344 if (AssignmentOp.isInvalid()) 12345 continue; 12346 AssignmentOp = 12347 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12348 if (AssignmentOp.isInvalid()) 12349 continue; 12350 12351 // No need to mark vars as copyprivate, they are already threadprivate or 12352 // implicitly private. 12353 assert(VD || isOpenMPCapturedDecl(D)); 12354 Vars.push_back( 12355 VD ? RefExpr->IgnoreParens() 12356 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 12357 SrcExprs.push_back(PseudoSrcExpr); 12358 DstExprs.push_back(PseudoDstExpr); 12359 AssignmentOps.push_back(AssignmentOp.get()); 12360 } 12361 12362 if (Vars.empty()) 12363 return nullptr; 12364 12365 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12366 Vars, SrcExprs, DstExprs, AssignmentOps); 12367 } 12368 12369 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 12370 SourceLocation StartLoc, 12371 SourceLocation LParenLoc, 12372 SourceLocation EndLoc) { 12373 if (VarList.empty()) 12374 return nullptr; 12375 12376 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 12377 } 12378 12379 OMPClause * 12380 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 12381 SourceLocation DepLoc, SourceLocation ColonLoc, 12382 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12383 SourceLocation LParenLoc, SourceLocation EndLoc) { 12384 if (DSAStack->getCurrentDirective() == OMPD_ordered && 12385 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 12386 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12387 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 12388 return nullptr; 12389 } 12390 if (DSAStack->getCurrentDirective() != OMPD_ordered && 12391 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 12392 DepKind == OMPC_DEPEND_sink)) { 12393 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 12394 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12395 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12396 /*Last=*/OMPC_DEPEND_unknown, Except) 12397 << getOpenMPClauseName(OMPC_depend); 12398 return nullptr; 12399 } 12400 SmallVector<Expr *, 8> Vars; 12401 DSAStackTy::OperatorOffsetTy OpsOffs; 12402 llvm::APSInt DepCounter(/*BitWidth=*/32); 12403 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 12404 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 12405 if (const Expr *OrderedCountExpr = 12406 DSAStack->getParentOrderedRegionParam().first) { 12407 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 12408 TotalDepCount.setIsUnsigned(/*Val=*/true); 12409 } 12410 } 12411 for (Expr *RefExpr : VarList) { 12412 assert(RefExpr && "NULL expr in OpenMP shared clause."); 12413 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12414 // It will be analyzed later. 12415 Vars.push_back(RefExpr); 12416 continue; 12417 } 12418 12419 SourceLocation ELoc = RefExpr->getExprLoc(); 12420 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 12421 if (DepKind == OMPC_DEPEND_sink) { 12422 if (DSAStack->getParentOrderedRegionParam().first && 12423 DepCounter >= TotalDepCount) { 12424 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 12425 continue; 12426 } 12427 ++DepCounter; 12428 // OpenMP [2.13.9, Summary] 12429 // depend(dependence-type : vec), where dependence-type is: 12430 // 'sink' and where vec is the iteration vector, which has the form: 12431 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 12432 // where n is the value specified by the ordered clause in the loop 12433 // directive, xi denotes the loop iteration variable of the i-th nested 12434 // loop associated with the loop directive, and di is a constant 12435 // non-negative integer. 12436 if (CurContext->isDependentContext()) { 12437 // It will be analyzed later. 12438 Vars.push_back(RefExpr); 12439 continue; 12440 } 12441 SimpleExpr = SimpleExpr->IgnoreImplicit(); 12442 OverloadedOperatorKind OOK = OO_None; 12443 SourceLocation OOLoc; 12444 Expr *LHS = SimpleExpr; 12445 Expr *RHS = nullptr; 12446 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 12447 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 12448 OOLoc = BO->getOperatorLoc(); 12449 LHS = BO->getLHS()->IgnoreParenImpCasts(); 12450 RHS = BO->getRHS()->IgnoreParenImpCasts(); 12451 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 12452 OOK = OCE->getOperator(); 12453 OOLoc = OCE->getOperatorLoc(); 12454 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12455 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 12456 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 12457 OOK = MCE->getMethodDecl() 12458 ->getNameInfo() 12459 .getName() 12460 .getCXXOverloadedOperator(); 12461 OOLoc = MCE->getCallee()->getExprLoc(); 12462 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 12463 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12464 } 12465 SourceLocation ELoc; 12466 SourceRange ERange; 12467 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 12468 if (Res.second) { 12469 // It will be analyzed later. 12470 Vars.push_back(RefExpr); 12471 } 12472 ValueDecl *D = Res.first; 12473 if (!D) 12474 continue; 12475 12476 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 12477 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 12478 continue; 12479 } 12480 if (RHS) { 12481 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 12482 RHS, OMPC_depend, /*StrictlyPositive=*/false); 12483 if (RHSRes.isInvalid()) 12484 continue; 12485 } 12486 if (!CurContext->isDependentContext() && 12487 DSAStack->getParentOrderedRegionParam().first && 12488 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 12489 const ValueDecl *VD = 12490 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 12491 if (VD) 12492 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 12493 << 1 << VD; 12494 else 12495 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 12496 continue; 12497 } 12498 OpsOffs.emplace_back(RHS, OOK); 12499 } else { 12500 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 12501 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 12502 (ASE && 12503 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 12504 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 12505 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12506 << RefExpr->getSourceRange(); 12507 continue; 12508 } 12509 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 12510 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 12511 ExprResult Res = 12512 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 12513 getDiagnostics().setSuppressAllDiagnostics(Suppress); 12514 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 12515 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12516 << RefExpr->getSourceRange(); 12517 continue; 12518 } 12519 } 12520 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 12521 } 12522 12523 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 12524 TotalDepCount > VarList.size() && 12525 DSAStack->getParentOrderedRegionParam().first && 12526 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 12527 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 12528 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 12529 } 12530 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 12531 Vars.empty()) 12532 return nullptr; 12533 12534 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12535 DepKind, DepLoc, ColonLoc, Vars, 12536 TotalDepCount.getZExtValue()); 12537 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 12538 DSAStack->isParentOrderedRegion()) 12539 DSAStack->addDoacrossDependClause(C, OpsOffs); 12540 return C; 12541 } 12542 12543 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 12544 SourceLocation LParenLoc, 12545 SourceLocation EndLoc) { 12546 Expr *ValExpr = Device; 12547 Stmt *HelperValStmt = nullptr; 12548 12549 // OpenMP [2.9.1, Restrictions] 12550 // The device expression must evaluate to a non-negative integer value. 12551 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 12552 /*StrictlyPositive=*/false)) 12553 return nullptr; 12554 12555 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12556 OpenMPDirectiveKind CaptureRegion = 12557 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 12558 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12559 ValExpr = MakeFullExpr(ValExpr).get(); 12560 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12561 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12562 HelperValStmt = buildPreInits(Context, Captures); 12563 } 12564 12565 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 12566 StartLoc, LParenLoc, EndLoc); 12567 } 12568 12569 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 12570 DSAStackTy *Stack, QualType QTy, 12571 bool FullCheck = true) { 12572 NamedDecl *ND; 12573 if (QTy->isIncompleteType(&ND)) { 12574 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 12575 return false; 12576 } 12577 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 12578 !QTy.isTrivialType(SemaRef.Context)) 12579 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 12580 return true; 12581 } 12582 12583 /// Return true if it can be proven that the provided array expression 12584 /// (array section or array subscript) does NOT specify the whole size of the 12585 /// array whose base type is \a BaseQTy. 12586 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 12587 const Expr *E, 12588 QualType BaseQTy) { 12589 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12590 12591 // If this is an array subscript, it refers to the whole size if the size of 12592 // the dimension is constant and equals 1. Also, an array section assumes the 12593 // format of an array subscript if no colon is used. 12594 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 12595 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12596 return ATy->getSize().getSExtValue() != 1; 12597 // Size can't be evaluated statically. 12598 return false; 12599 } 12600 12601 assert(OASE && "Expecting array section if not an array subscript."); 12602 const Expr *LowerBound = OASE->getLowerBound(); 12603 const Expr *Length = OASE->getLength(); 12604 12605 // If there is a lower bound that does not evaluates to zero, we are not 12606 // covering the whole dimension. 12607 if (LowerBound) { 12608 Expr::EvalResult Result; 12609 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 12610 return false; // Can't get the integer value as a constant. 12611 12612 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 12613 if (ConstLowerBound.getSExtValue()) 12614 return true; 12615 } 12616 12617 // If we don't have a length we covering the whole dimension. 12618 if (!Length) 12619 return false; 12620 12621 // If the base is a pointer, we don't have a way to get the size of the 12622 // pointee. 12623 if (BaseQTy->isPointerType()) 12624 return false; 12625 12626 // We can only check if the length is the same as the size of the dimension 12627 // if we have a constant array. 12628 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 12629 if (!CATy) 12630 return false; 12631 12632 Expr::EvalResult Result; 12633 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12634 return false; // Can't get the integer value as a constant. 12635 12636 llvm::APSInt ConstLength = Result.Val.getInt(); 12637 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 12638 } 12639 12640 // Return true if it can be proven that the provided array expression (array 12641 // section or array subscript) does NOT specify a single element of the array 12642 // whose base type is \a BaseQTy. 12643 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 12644 const Expr *E, 12645 QualType BaseQTy) { 12646 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12647 12648 // An array subscript always refer to a single element. Also, an array section 12649 // assumes the format of an array subscript if no colon is used. 12650 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 12651 return false; 12652 12653 assert(OASE && "Expecting array section if not an array subscript."); 12654 const Expr *Length = OASE->getLength(); 12655 12656 // If we don't have a length we have to check if the array has unitary size 12657 // for this dimension. Also, we should always expect a length if the base type 12658 // is pointer. 12659 if (!Length) { 12660 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12661 return ATy->getSize().getSExtValue() != 1; 12662 // We cannot assume anything. 12663 return false; 12664 } 12665 12666 // Check if the length evaluates to 1. 12667 Expr::EvalResult Result; 12668 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12669 return false; // Can't get the integer value as a constant. 12670 12671 llvm::APSInt ConstLength = Result.Val.getInt(); 12672 return ConstLength.getSExtValue() != 1; 12673 } 12674 12675 // Return the expression of the base of the mappable expression or null if it 12676 // cannot be determined and do all the necessary checks to see if the expression 12677 // is valid as a standalone mappable expression. In the process, record all the 12678 // components of the expression. 12679 static const Expr *checkMapClauseExpressionBase( 12680 Sema &SemaRef, Expr *E, 12681 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 12682 OpenMPClauseKind CKind, bool NoDiagnose) { 12683 SourceLocation ELoc = E->getExprLoc(); 12684 SourceRange ERange = E->getSourceRange(); 12685 12686 // The base of elements of list in a map clause have to be either: 12687 // - a reference to variable or field. 12688 // - a member expression. 12689 // - an array expression. 12690 // 12691 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 12692 // reference to 'r'. 12693 // 12694 // If we have: 12695 // 12696 // struct SS { 12697 // Bla S; 12698 // foo() { 12699 // #pragma omp target map (S.Arr[:12]); 12700 // } 12701 // } 12702 // 12703 // We want to retrieve the member expression 'this->S'; 12704 12705 const Expr *RelevantExpr = nullptr; 12706 12707 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 12708 // If a list item is an array section, it must specify contiguous storage. 12709 // 12710 // For this restriction it is sufficient that we make sure only references 12711 // to variables or fields and array expressions, and that no array sections 12712 // exist except in the rightmost expression (unless they cover the whole 12713 // dimension of the array). E.g. these would be invalid: 12714 // 12715 // r.ArrS[3:5].Arr[6:7] 12716 // 12717 // r.ArrS[3:5].x 12718 // 12719 // but these would be valid: 12720 // r.ArrS[3].Arr[6:7] 12721 // 12722 // r.ArrS[3].x 12723 12724 bool AllowUnitySizeArraySection = true; 12725 bool AllowWholeSizeArraySection = true; 12726 12727 while (!RelevantExpr) { 12728 E = E->IgnoreParenImpCasts(); 12729 12730 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 12731 if (!isa<VarDecl>(CurE->getDecl())) 12732 return nullptr; 12733 12734 RelevantExpr = CurE; 12735 12736 // If we got a reference to a declaration, we should not expect any array 12737 // section before that. 12738 AllowUnitySizeArraySection = false; 12739 AllowWholeSizeArraySection = false; 12740 12741 // Record the component. 12742 CurComponents.emplace_back(CurE, CurE->getDecl()); 12743 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 12744 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 12745 12746 if (isa<CXXThisExpr>(BaseE)) 12747 // We found a base expression: this->Val. 12748 RelevantExpr = CurE; 12749 else 12750 E = BaseE; 12751 12752 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 12753 if (!NoDiagnose) { 12754 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 12755 << CurE->getSourceRange(); 12756 return nullptr; 12757 } 12758 if (RelevantExpr) 12759 return nullptr; 12760 continue; 12761 } 12762 12763 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 12764 12765 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 12766 // A bit-field cannot appear in a map clause. 12767 // 12768 if (FD->isBitField()) { 12769 if (!NoDiagnose) { 12770 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 12771 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 12772 return nullptr; 12773 } 12774 if (RelevantExpr) 12775 return nullptr; 12776 continue; 12777 } 12778 12779 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12780 // If the type of a list item is a reference to a type T then the type 12781 // will be considered to be T for all purposes of this clause. 12782 QualType CurType = BaseE->getType().getNonReferenceType(); 12783 12784 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 12785 // A list item cannot be a variable that is a member of a structure with 12786 // a union type. 12787 // 12788 if (CurType->isUnionType()) { 12789 if (!NoDiagnose) { 12790 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 12791 << CurE->getSourceRange(); 12792 return nullptr; 12793 } 12794 continue; 12795 } 12796 12797 // If we got a member expression, we should not expect any array section 12798 // before that: 12799 // 12800 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 12801 // If a list item is an element of a structure, only the rightmost symbol 12802 // of the variable reference can be an array section. 12803 // 12804 AllowUnitySizeArraySection = false; 12805 AllowWholeSizeArraySection = false; 12806 12807 // Record the component. 12808 CurComponents.emplace_back(CurE, FD); 12809 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 12810 E = CurE->getBase()->IgnoreParenImpCasts(); 12811 12812 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 12813 if (!NoDiagnose) { 12814 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12815 << 0 << CurE->getSourceRange(); 12816 return nullptr; 12817 } 12818 continue; 12819 } 12820 12821 // If we got an array subscript that express the whole dimension we 12822 // can have any array expressions before. If it only expressing part of 12823 // the dimension, we can only have unitary-size array expressions. 12824 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 12825 E->getType())) 12826 AllowWholeSizeArraySection = false; 12827 12828 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 12829 Expr::EvalResult Result; 12830 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 12831 if (!Result.Val.getInt().isNullValue()) { 12832 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 12833 diag::err_omp_invalid_map_this_expr); 12834 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 12835 diag::note_omp_invalid_subscript_on_this_ptr_map); 12836 } 12837 } 12838 RelevantExpr = TE; 12839 } 12840 12841 // Record the component - we don't have any declaration associated. 12842 CurComponents.emplace_back(CurE, nullptr); 12843 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 12844 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 12845 E = CurE->getBase()->IgnoreParenImpCasts(); 12846 12847 QualType CurType = 12848 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12849 12850 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12851 // If the type of a list item is a reference to a type T then the type 12852 // will be considered to be T for all purposes of this clause. 12853 if (CurType->isReferenceType()) 12854 CurType = CurType->getPointeeType(); 12855 12856 bool IsPointer = CurType->isAnyPointerType(); 12857 12858 if (!IsPointer && !CurType->isArrayType()) { 12859 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12860 << 0 << CurE->getSourceRange(); 12861 return nullptr; 12862 } 12863 12864 bool NotWhole = 12865 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 12866 bool NotUnity = 12867 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 12868 12869 if (AllowWholeSizeArraySection) { 12870 // Any array section is currently allowed. Allowing a whole size array 12871 // section implies allowing a unity array section as well. 12872 // 12873 // If this array section refers to the whole dimension we can still 12874 // accept other array sections before this one, except if the base is a 12875 // pointer. Otherwise, only unitary sections are accepted. 12876 if (NotWhole || IsPointer) 12877 AllowWholeSizeArraySection = false; 12878 } else if (AllowUnitySizeArraySection && NotUnity) { 12879 // A unity or whole array section is not allowed and that is not 12880 // compatible with the properties of the current array section. 12881 SemaRef.Diag( 12882 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 12883 << CurE->getSourceRange(); 12884 return nullptr; 12885 } 12886 12887 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 12888 Expr::EvalResult ResultR; 12889 Expr::EvalResult ResultL; 12890 if (CurE->getLength()->EvaluateAsInt(ResultR, 12891 SemaRef.getASTContext())) { 12892 if (!ResultR.Val.getInt().isOneValue()) { 12893 SemaRef.Diag(CurE->getLength()->getExprLoc(), 12894 diag::err_omp_invalid_map_this_expr); 12895 SemaRef.Diag(CurE->getLength()->getExprLoc(), 12896 diag::note_omp_invalid_length_on_this_ptr_mapping); 12897 } 12898 } 12899 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 12900 ResultL, SemaRef.getASTContext())) { 12901 if (!ResultL.Val.getInt().isNullValue()) { 12902 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 12903 diag::err_omp_invalid_map_this_expr); 12904 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 12905 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 12906 } 12907 } 12908 RelevantExpr = TE; 12909 } 12910 12911 // Record the component - we don't have any declaration associated. 12912 CurComponents.emplace_back(CurE, nullptr); 12913 } else { 12914 if (!NoDiagnose) { 12915 // If nothing else worked, this is not a valid map clause expression. 12916 SemaRef.Diag( 12917 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 12918 << ERange; 12919 } 12920 return nullptr; 12921 } 12922 } 12923 12924 return RelevantExpr; 12925 } 12926 12927 // Return true if expression E associated with value VD has conflicts with other 12928 // map information. 12929 static bool checkMapConflicts( 12930 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 12931 bool CurrentRegionOnly, 12932 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 12933 OpenMPClauseKind CKind) { 12934 assert(VD && E); 12935 SourceLocation ELoc = E->getExprLoc(); 12936 SourceRange ERange = E->getSourceRange(); 12937 12938 // In order to easily check the conflicts we need to match each component of 12939 // the expression under test with the components of the expressions that are 12940 // already in the stack. 12941 12942 assert(!CurComponents.empty() && "Map clause expression with no components!"); 12943 assert(CurComponents.back().getAssociatedDeclaration() == VD && 12944 "Map clause expression with unexpected base!"); 12945 12946 // Variables to help detecting enclosing problems in data environment nests. 12947 bool IsEnclosedByDataEnvironmentExpr = false; 12948 const Expr *EnclosingExpr = nullptr; 12949 12950 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 12951 VD, CurrentRegionOnly, 12952 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 12953 ERange, CKind, &EnclosingExpr, 12954 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 12955 StackComponents, 12956 OpenMPClauseKind) { 12957 assert(!StackComponents.empty() && 12958 "Map clause expression with no components!"); 12959 assert(StackComponents.back().getAssociatedDeclaration() == VD && 12960 "Map clause expression with unexpected base!"); 12961 (void)VD; 12962 12963 // The whole expression in the stack. 12964 const Expr *RE = StackComponents.front().getAssociatedExpression(); 12965 12966 // Expressions must start from the same base. Here we detect at which 12967 // point both expressions diverge from each other and see if we can 12968 // detect if the memory referred to both expressions is contiguous and 12969 // do not overlap. 12970 auto CI = CurComponents.rbegin(); 12971 auto CE = CurComponents.rend(); 12972 auto SI = StackComponents.rbegin(); 12973 auto SE = StackComponents.rend(); 12974 for (; CI != CE && SI != SE; ++CI, ++SI) { 12975 12976 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 12977 // At most one list item can be an array item derived from a given 12978 // variable in map clauses of the same construct. 12979 if (CurrentRegionOnly && 12980 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 12981 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 12982 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 12983 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 12984 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 12985 diag::err_omp_multiple_array_items_in_map_clause) 12986 << CI->getAssociatedExpression()->getSourceRange(); 12987 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 12988 diag::note_used_here) 12989 << SI->getAssociatedExpression()->getSourceRange(); 12990 return true; 12991 } 12992 12993 // Do both expressions have the same kind? 12994 if (CI->getAssociatedExpression()->getStmtClass() != 12995 SI->getAssociatedExpression()->getStmtClass()) 12996 break; 12997 12998 // Are we dealing with different variables/fields? 12999 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13000 break; 13001 } 13002 // Check if the extra components of the expressions in the enclosing 13003 // data environment are redundant for the current base declaration. 13004 // If they are, the maps completely overlap, which is legal. 13005 for (; SI != SE; ++SI) { 13006 QualType Type; 13007 if (const auto *ASE = 13008 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13009 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13010 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13011 SI->getAssociatedExpression())) { 13012 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13013 Type = 13014 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13015 } 13016 if (Type.isNull() || Type->isAnyPointerType() || 13017 checkArrayExpressionDoesNotReferToWholeSize( 13018 SemaRef, SI->getAssociatedExpression(), Type)) 13019 break; 13020 } 13021 13022 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13023 // List items of map clauses in the same construct must not share 13024 // original storage. 13025 // 13026 // If the expressions are exactly the same or one is a subset of the 13027 // other, it means they are sharing storage. 13028 if (CI == CE && SI == SE) { 13029 if (CurrentRegionOnly) { 13030 if (CKind == OMPC_map) { 13031 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13032 } else { 13033 assert(CKind == OMPC_to || CKind == OMPC_from); 13034 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13035 << ERange; 13036 } 13037 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13038 << RE->getSourceRange(); 13039 return true; 13040 } 13041 // If we find the same expression in the enclosing data environment, 13042 // that is legal. 13043 IsEnclosedByDataEnvironmentExpr = true; 13044 return false; 13045 } 13046 13047 QualType DerivedType = 13048 std::prev(CI)->getAssociatedDeclaration()->getType(); 13049 SourceLocation DerivedLoc = 13050 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13051 13052 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13053 // If the type of a list item is a reference to a type T then the type 13054 // will be considered to be T for all purposes of this clause. 13055 DerivedType = DerivedType.getNonReferenceType(); 13056 13057 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13058 // A variable for which the type is pointer and an array section 13059 // derived from that variable must not appear as list items of map 13060 // clauses of the same construct. 13061 // 13062 // Also, cover one of the cases in: 13063 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13064 // If any part of the original storage of a list item has corresponding 13065 // storage in the device data environment, all of the original storage 13066 // must have corresponding storage in the device data environment. 13067 // 13068 if (DerivedType->isAnyPointerType()) { 13069 if (CI == CE || SI == SE) { 13070 SemaRef.Diag( 13071 DerivedLoc, 13072 diag::err_omp_pointer_mapped_along_with_derived_section) 13073 << DerivedLoc; 13074 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13075 << RE->getSourceRange(); 13076 return true; 13077 } 13078 if (CI->getAssociatedExpression()->getStmtClass() != 13079 SI->getAssociatedExpression()->getStmtClass() || 13080 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13081 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13082 assert(CI != CE && SI != SE); 13083 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13084 << DerivedLoc; 13085 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13086 << RE->getSourceRange(); 13087 return true; 13088 } 13089 } 13090 13091 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13092 // List items of map clauses in the same construct must not share 13093 // original storage. 13094 // 13095 // An expression is a subset of the other. 13096 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13097 if (CKind == OMPC_map) { 13098 if (CI != CE || SI != SE) { 13099 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13100 // a pointer. 13101 auto Begin = 13102 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13103 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13104 auto It = Begin; 13105 while (It != End && !It->getAssociatedDeclaration()) 13106 std::advance(It, 1); 13107 assert(It != End && 13108 "Expected at least one component with the declaration."); 13109 if (It != Begin && It->getAssociatedDeclaration() 13110 ->getType() 13111 .getCanonicalType() 13112 ->isAnyPointerType()) { 13113 IsEnclosedByDataEnvironmentExpr = false; 13114 EnclosingExpr = nullptr; 13115 return false; 13116 } 13117 } 13118 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13119 } else { 13120 assert(CKind == OMPC_to || CKind == OMPC_from); 13121 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13122 << ERange; 13123 } 13124 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13125 << RE->getSourceRange(); 13126 return true; 13127 } 13128 13129 // The current expression uses the same base as other expression in the 13130 // data environment but does not contain it completely. 13131 if (!CurrentRegionOnly && SI != SE) 13132 EnclosingExpr = RE; 13133 13134 // The current expression is a subset of the expression in the data 13135 // environment. 13136 IsEnclosedByDataEnvironmentExpr |= 13137 (!CurrentRegionOnly && CI != CE && SI == SE); 13138 13139 return false; 13140 }); 13141 13142 if (CurrentRegionOnly) 13143 return FoundError; 13144 13145 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13146 // If any part of the original storage of a list item has corresponding 13147 // storage in the device data environment, all of the original storage must 13148 // have corresponding storage in the device data environment. 13149 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13150 // If a list item is an element of a structure, and a different element of 13151 // the structure has a corresponding list item in the device data environment 13152 // prior to a task encountering the construct associated with the map clause, 13153 // then the list item must also have a corresponding list item in the device 13154 // data environment prior to the task encountering the construct. 13155 // 13156 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13157 SemaRef.Diag(ELoc, 13158 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13159 << ERange; 13160 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13161 << EnclosingExpr->getSourceRange(); 13162 return true; 13163 } 13164 13165 return FoundError; 13166 } 13167 13168 // Look up the user-defined mapper given the mapper name and mapped type, and 13169 // build a reference to it. 13170 ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13171 CXXScopeSpec &MapperIdScopeSpec, 13172 const DeclarationNameInfo &MapperId, 13173 QualType Type, Expr *UnresolvedMapper) { 13174 if (MapperIdScopeSpec.isInvalid()) 13175 return ExprError(); 13176 // Find all user-defined mappers with the given MapperId. 13177 SmallVector<UnresolvedSet<8>, 4> Lookups; 13178 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13179 Lookup.suppressDiagnostics(); 13180 if (S) { 13181 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13182 NamedDecl *D = Lookup.getRepresentativeDecl(); 13183 while (S && !S->isDeclScope(D)) 13184 S = S->getParent(); 13185 if (S) 13186 S = S->getParent(); 13187 Lookups.emplace_back(); 13188 Lookups.back().append(Lookup.begin(), Lookup.end()); 13189 Lookup.clear(); 13190 } 13191 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13192 // Extract the user-defined mappers with the given MapperId. 13193 Lookups.push_back(UnresolvedSet<8>()); 13194 for (NamedDecl *D : ULE->decls()) { 13195 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13196 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13197 Lookups.back().addDecl(DMD); 13198 } 13199 } 13200 // Defer the lookup for dependent types. The results will be passed through 13201 // UnresolvedMapper on instantiation. 13202 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13203 Type->isInstantiationDependentType() || 13204 Type->containsUnexpandedParameterPack() || 13205 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13206 return !D->isInvalidDecl() && 13207 (D->getType()->isDependentType() || 13208 D->getType()->isInstantiationDependentType() || 13209 D->getType()->containsUnexpandedParameterPack()); 13210 })) { 13211 UnresolvedSet<8> URS; 13212 for (const UnresolvedSet<8> &Set : Lookups) { 13213 if (Set.empty()) 13214 continue; 13215 URS.append(Set.begin(), Set.end()); 13216 } 13217 return UnresolvedLookupExpr::Create( 13218 SemaRef.Context, /*NamingClass=*/nullptr, 13219 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13220 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13221 } 13222 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13223 // The type must be of struct, union or class type in C and C++ 13224 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13225 return ExprEmpty(); 13226 SourceLocation Loc = MapperId.getLoc(); 13227 // Perform argument dependent lookup. 13228 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13229 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13230 // Return the first user-defined mapper with the desired type. 13231 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13232 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13233 if (!D->isInvalidDecl() && 13234 SemaRef.Context.hasSameType(D->getType(), Type)) 13235 return D; 13236 return nullptr; 13237 })) 13238 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13239 // Find the first user-defined mapper with a type derived from the desired 13240 // type. 13241 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13242 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13243 if (!D->isInvalidDecl() && 13244 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13245 !Type.isMoreQualifiedThan(D->getType())) 13246 return D; 13247 return nullptr; 13248 })) { 13249 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13250 /*DetectVirtual=*/false); 13251 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13252 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13253 VD->getType().getUnqualifiedType()))) { 13254 if (SemaRef.CheckBaseClassAccess( 13255 Loc, VD->getType(), Type, Paths.front(), 13256 /*DiagID=*/0) != Sema::AR_inaccessible) { 13257 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13258 } 13259 } 13260 } 13261 } 13262 // Report error if a mapper is specified, but cannot be found. 13263 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13264 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13265 << Type << MapperId.getName(); 13266 return ExprError(); 13267 } 13268 return ExprEmpty(); 13269 } 13270 13271 namespace { 13272 // Utility struct that gathers all the related lists associated with a mappable 13273 // expression. 13274 struct MappableVarListInfo { 13275 // The list of expressions. 13276 ArrayRef<Expr *> VarList; 13277 // The list of processed expressions. 13278 SmallVector<Expr *, 16> ProcessedVarList; 13279 // The mappble components for each expression. 13280 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13281 // The base declaration of the variable. 13282 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13283 // The reference to the user-defined mapper associated with every expression. 13284 SmallVector<Expr *, 16> UDMapperList; 13285 13286 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13287 // We have a list of components and base declarations for each entry in the 13288 // variable list. 13289 VarComponents.reserve(VarList.size()); 13290 VarBaseDeclarations.reserve(VarList.size()); 13291 } 13292 }; 13293 } 13294 13295 // Check the validity of the provided variable list for the provided clause kind 13296 // \a CKind. In the check process the valid expressions, mappable expression 13297 // components, variables, and user-defined mappers are extracted and used to 13298 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13299 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13300 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13301 static void checkMappableExpressionList( 13302 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13303 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13304 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13305 ArrayRef<Expr *> UnresolvedMappers, 13306 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13307 bool IsMapTypeImplicit = false) { 13308 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13309 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13310 "Unexpected clause kind with mappable expressions!"); 13311 13312 // If the identifier of user-defined mapper is not specified, it is "default". 13313 // We do not change the actual name in this clause to distinguish whether a 13314 // mapper is specified explicitly, i.e., it is not explicitly specified when 13315 // MapperId.getName() is empty. 13316 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13317 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 13318 MapperId.setName(DeclNames.getIdentifier( 13319 &SemaRef.getASTContext().Idents.get("default"))); 13320 } 13321 13322 // Iterators to find the current unresolved mapper expression. 13323 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 13324 bool UpdateUMIt = false; 13325 Expr *UnresolvedMapper = nullptr; 13326 13327 // Keep track of the mappable components and base declarations in this clause. 13328 // Each entry in the list is going to have a list of components associated. We 13329 // record each set of the components so that we can build the clause later on. 13330 // In the end we should have the same amount of declarations and component 13331 // lists. 13332 13333 for (Expr *RE : MVLI.VarList) { 13334 assert(RE && "Null expr in omp to/from/map clause"); 13335 SourceLocation ELoc = RE->getExprLoc(); 13336 13337 // Find the current unresolved mapper expression. 13338 if (UpdateUMIt && UMIt != UMEnd) { 13339 UMIt++; 13340 assert( 13341 UMIt != UMEnd && 13342 "Expect the size of UnresolvedMappers to match with that of VarList"); 13343 } 13344 UpdateUMIt = true; 13345 if (UMIt != UMEnd) 13346 UnresolvedMapper = *UMIt; 13347 13348 const Expr *VE = RE->IgnoreParenLValueCasts(); 13349 13350 if (VE->isValueDependent() || VE->isTypeDependent() || 13351 VE->isInstantiationDependent() || 13352 VE->containsUnexpandedParameterPack()) { 13353 // Try to find the associated user-defined mapper. 13354 ExprResult ER = buildUserDefinedMapperRef( 13355 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13356 VE->getType().getCanonicalType(), UnresolvedMapper); 13357 if (ER.isInvalid()) 13358 continue; 13359 MVLI.UDMapperList.push_back(ER.get()); 13360 // We can only analyze this information once the missing information is 13361 // resolved. 13362 MVLI.ProcessedVarList.push_back(RE); 13363 continue; 13364 } 13365 13366 Expr *SimpleExpr = RE->IgnoreParenCasts(); 13367 13368 if (!RE->IgnoreParenImpCasts()->isLValue()) { 13369 SemaRef.Diag(ELoc, 13370 diag::err_omp_expected_named_var_member_or_array_expression) 13371 << RE->getSourceRange(); 13372 continue; 13373 } 13374 13375 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 13376 ValueDecl *CurDeclaration = nullptr; 13377 13378 // Obtain the array or member expression bases if required. Also, fill the 13379 // components array with all the components identified in the process. 13380 const Expr *BE = checkMapClauseExpressionBase( 13381 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 13382 if (!BE) 13383 continue; 13384 13385 assert(!CurComponents.empty() && 13386 "Invalid mappable expression information."); 13387 13388 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 13389 // Add store "this" pointer to class in DSAStackTy for future checking 13390 DSAS->addMappedClassesQualTypes(TE->getType()); 13391 // Try to find the associated user-defined mapper. 13392 ExprResult ER = buildUserDefinedMapperRef( 13393 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13394 VE->getType().getCanonicalType(), UnresolvedMapper); 13395 if (ER.isInvalid()) 13396 continue; 13397 MVLI.UDMapperList.push_back(ER.get()); 13398 // Skip restriction checking for variable or field declarations 13399 MVLI.ProcessedVarList.push_back(RE); 13400 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13401 MVLI.VarComponents.back().append(CurComponents.begin(), 13402 CurComponents.end()); 13403 MVLI.VarBaseDeclarations.push_back(nullptr); 13404 continue; 13405 } 13406 13407 // For the following checks, we rely on the base declaration which is 13408 // expected to be associated with the last component. The declaration is 13409 // expected to be a variable or a field (if 'this' is being mapped). 13410 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 13411 assert(CurDeclaration && "Null decl on map clause."); 13412 assert( 13413 CurDeclaration->isCanonicalDecl() && 13414 "Expecting components to have associated only canonical declarations."); 13415 13416 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 13417 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 13418 13419 assert((VD || FD) && "Only variables or fields are expected here!"); 13420 (void)FD; 13421 13422 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 13423 // threadprivate variables cannot appear in a map clause. 13424 // OpenMP 4.5 [2.10.5, target update Construct] 13425 // threadprivate variables cannot appear in a from clause. 13426 if (VD && DSAS->isThreadPrivate(VD)) { 13427 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13428 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 13429 << getOpenMPClauseName(CKind); 13430 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 13431 continue; 13432 } 13433 13434 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13435 // A list item cannot appear in both a map clause and a data-sharing 13436 // attribute clause on the same construct. 13437 13438 // Check conflicts with other map clause expressions. We check the conflicts 13439 // with the current construct separately from the enclosing data 13440 // environment, because the restrictions are different. We only have to 13441 // check conflicts across regions for the map clauses. 13442 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13443 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 13444 break; 13445 if (CKind == OMPC_map && 13446 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13447 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 13448 break; 13449 13450 // OpenMP 4.5 [2.10.5, target update Construct] 13451 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13452 // If the type of a list item is a reference to a type T then the type will 13453 // be considered to be T for all purposes of this clause. 13454 auto I = llvm::find_if( 13455 CurComponents, 13456 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 13457 return MC.getAssociatedDeclaration(); 13458 }); 13459 assert(I != CurComponents.end() && "Null decl on map clause."); 13460 QualType Type = 13461 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 13462 13463 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 13464 // A list item in a to or from clause must have a mappable type. 13465 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13466 // A list item must have a mappable type. 13467 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 13468 DSAS, Type)) 13469 continue; 13470 13471 if (CKind == OMPC_map) { 13472 // target enter data 13473 // OpenMP [2.10.2, Restrictions, p. 99] 13474 // A map-type must be specified in all map clauses and must be either 13475 // to or alloc. 13476 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 13477 if (DKind == OMPD_target_enter_data && 13478 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 13479 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13480 << (IsMapTypeImplicit ? 1 : 0) 13481 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13482 << getOpenMPDirectiveName(DKind); 13483 continue; 13484 } 13485 13486 // target exit_data 13487 // OpenMP [2.10.3, Restrictions, p. 102] 13488 // A map-type must be specified in all map clauses and must be either 13489 // from, release, or delete. 13490 if (DKind == OMPD_target_exit_data && 13491 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 13492 MapType == OMPC_MAP_delete)) { 13493 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13494 << (IsMapTypeImplicit ? 1 : 0) 13495 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13496 << getOpenMPDirectiveName(DKind); 13497 continue; 13498 } 13499 13500 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13501 // A list item cannot appear in both a map clause and a data-sharing 13502 // attribute clause on the same construct 13503 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 13504 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13505 if (isOpenMPPrivate(DVar.CKind)) { 13506 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13507 << getOpenMPClauseName(DVar.CKind) 13508 << getOpenMPClauseName(OMPC_map) 13509 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 13510 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 13511 continue; 13512 } 13513 } 13514 } 13515 13516 // Try to find the associated user-defined mapper. 13517 ExprResult ER = buildUserDefinedMapperRef( 13518 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13519 Type.getCanonicalType(), UnresolvedMapper); 13520 if (ER.isInvalid()) 13521 continue; 13522 MVLI.UDMapperList.push_back(ER.get()); 13523 13524 // Save the current expression. 13525 MVLI.ProcessedVarList.push_back(RE); 13526 13527 // Store the components in the stack so that they can be used to check 13528 // against other clauses later on. 13529 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 13530 /*WhereFoundClauseKind=*/OMPC_map); 13531 13532 // Save the components and declaration to create the clause. For purposes of 13533 // the clause creation, any component list that has has base 'this' uses 13534 // null as base declaration. 13535 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13536 MVLI.VarComponents.back().append(CurComponents.begin(), 13537 CurComponents.end()); 13538 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 13539 : CurDeclaration); 13540 } 13541 } 13542 13543 OMPClause *Sema::ActOnOpenMPMapClause( 13544 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13545 ArrayRef<SourceLocation> MapTypeModifiersLoc, 13546 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 13547 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 13548 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 13549 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 13550 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 13551 OMPC_MAP_MODIFIER_unknown, 13552 OMPC_MAP_MODIFIER_unknown}; 13553 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 13554 13555 // Process map-type-modifiers, flag errors for duplicate modifiers. 13556 unsigned Count = 0; 13557 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 13558 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 13559 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 13560 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 13561 continue; 13562 } 13563 assert(Count < OMPMapClause::NumberOfModifiers && 13564 "Modifiers exceed the allowed number of map type modifiers"); 13565 Modifiers[Count] = MapTypeModifiers[I]; 13566 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 13567 ++Count; 13568 } 13569 13570 MappableVarListInfo MVLI(VarList); 13571 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 13572 MapperIdScopeSpec, MapperId, UnresolvedMappers, 13573 MapType, IsMapTypeImplicit); 13574 13575 // We need to produce a map clause even if we don't have variables so that 13576 // other diagnostics related with non-existing map clauses are accurate. 13577 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 13578 MVLI.VarBaseDeclarations, MVLI.VarComponents, 13579 MVLI.UDMapperList, Modifiers, ModifiersLoc, 13580 MapperIdScopeSpec.getWithLocInContext(Context), 13581 MapperId, MapType, IsMapTypeImplicit, MapLoc); 13582 } 13583 13584 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 13585 TypeResult ParsedType) { 13586 assert(ParsedType.isUsable()); 13587 13588 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 13589 if (ReductionType.isNull()) 13590 return QualType(); 13591 13592 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 13593 // A type name in a declare reduction directive cannot be a function type, an 13594 // array type, a reference type, or a type qualified with const, volatile or 13595 // restrict. 13596 if (ReductionType.hasQualifiers()) { 13597 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 13598 return QualType(); 13599 } 13600 13601 if (ReductionType->isFunctionType()) { 13602 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 13603 return QualType(); 13604 } 13605 if (ReductionType->isReferenceType()) { 13606 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 13607 return QualType(); 13608 } 13609 if (ReductionType->isArrayType()) { 13610 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 13611 return QualType(); 13612 } 13613 return ReductionType; 13614 } 13615 13616 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 13617 Scope *S, DeclContext *DC, DeclarationName Name, 13618 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 13619 AccessSpecifier AS, Decl *PrevDeclInScope) { 13620 SmallVector<Decl *, 8> Decls; 13621 Decls.reserve(ReductionTypes.size()); 13622 13623 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 13624 forRedeclarationInCurContext()); 13625 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 13626 // A reduction-identifier may not be re-declared in the current scope for the 13627 // same type or for a type that is compatible according to the base language 13628 // rules. 13629 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 13630 OMPDeclareReductionDecl *PrevDRD = nullptr; 13631 bool InCompoundScope = true; 13632 if (S != nullptr) { 13633 // Find previous declaration with the same name not referenced in other 13634 // declarations. 13635 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 13636 InCompoundScope = 13637 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 13638 LookupName(Lookup, S); 13639 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 13640 /*AllowInlineNamespace=*/false); 13641 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 13642 LookupResult::Filter Filter = Lookup.makeFilter(); 13643 while (Filter.hasNext()) { 13644 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 13645 if (InCompoundScope) { 13646 auto I = UsedAsPrevious.find(PrevDecl); 13647 if (I == UsedAsPrevious.end()) 13648 UsedAsPrevious[PrevDecl] = false; 13649 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 13650 UsedAsPrevious[D] = true; 13651 } 13652 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 13653 PrevDecl->getLocation(); 13654 } 13655 Filter.done(); 13656 if (InCompoundScope) { 13657 for (const auto &PrevData : UsedAsPrevious) { 13658 if (!PrevData.second) { 13659 PrevDRD = PrevData.first; 13660 break; 13661 } 13662 } 13663 } 13664 } else if (PrevDeclInScope != nullptr) { 13665 auto *PrevDRDInScope = PrevDRD = 13666 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 13667 do { 13668 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 13669 PrevDRDInScope->getLocation(); 13670 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 13671 } while (PrevDRDInScope != nullptr); 13672 } 13673 for (const auto &TyData : ReductionTypes) { 13674 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 13675 bool Invalid = false; 13676 if (I != PreviousRedeclTypes.end()) { 13677 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 13678 << TyData.first; 13679 Diag(I->second, diag::note_previous_definition); 13680 Invalid = true; 13681 } 13682 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 13683 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 13684 Name, TyData.first, PrevDRD); 13685 DC->addDecl(DRD); 13686 DRD->setAccess(AS); 13687 Decls.push_back(DRD); 13688 if (Invalid) 13689 DRD->setInvalidDecl(); 13690 else 13691 PrevDRD = DRD; 13692 } 13693 13694 return DeclGroupPtrTy::make( 13695 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 13696 } 13697 13698 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 13699 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13700 13701 // Enter new function scope. 13702 PushFunctionScope(); 13703 setFunctionHasBranchProtectedScope(); 13704 getCurFunction()->setHasOMPDeclareReductionCombiner(); 13705 13706 if (S != nullptr) 13707 PushDeclContext(S, DRD); 13708 else 13709 CurContext = DRD; 13710 13711 PushExpressionEvaluationContext( 13712 ExpressionEvaluationContext::PotentiallyEvaluated); 13713 13714 QualType ReductionType = DRD->getType(); 13715 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 13716 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 13717 // uses semantics of argument handles by value, but it should be passed by 13718 // reference. C lang does not support references, so pass all parameters as 13719 // pointers. 13720 // Create 'T omp_in;' variable. 13721 VarDecl *OmpInParm = 13722 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 13723 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 13724 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 13725 // uses semantics of argument handles by value, but it should be passed by 13726 // reference. C lang does not support references, so pass all parameters as 13727 // pointers. 13728 // Create 'T omp_out;' variable. 13729 VarDecl *OmpOutParm = 13730 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 13731 if (S != nullptr) { 13732 PushOnScopeChains(OmpInParm, S); 13733 PushOnScopeChains(OmpOutParm, S); 13734 } else { 13735 DRD->addDecl(OmpInParm); 13736 DRD->addDecl(OmpOutParm); 13737 } 13738 Expr *InE = 13739 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 13740 Expr *OutE = 13741 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 13742 DRD->setCombinerData(InE, OutE); 13743 } 13744 13745 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 13746 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13747 DiscardCleanupsInEvaluationContext(); 13748 PopExpressionEvaluationContext(); 13749 13750 PopDeclContext(); 13751 PopFunctionScopeInfo(); 13752 13753 if (Combiner != nullptr) 13754 DRD->setCombiner(Combiner); 13755 else 13756 DRD->setInvalidDecl(); 13757 } 13758 13759 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 13760 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13761 13762 // Enter new function scope. 13763 PushFunctionScope(); 13764 setFunctionHasBranchProtectedScope(); 13765 13766 if (S != nullptr) 13767 PushDeclContext(S, DRD); 13768 else 13769 CurContext = DRD; 13770 13771 PushExpressionEvaluationContext( 13772 ExpressionEvaluationContext::PotentiallyEvaluated); 13773 13774 QualType ReductionType = DRD->getType(); 13775 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 13776 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 13777 // uses semantics of argument handles by value, but it should be passed by 13778 // reference. C lang does not support references, so pass all parameters as 13779 // pointers. 13780 // Create 'T omp_priv;' variable. 13781 VarDecl *OmpPrivParm = 13782 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 13783 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 13784 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 13785 // uses semantics of argument handles by value, but it should be passed by 13786 // reference. C lang does not support references, so pass all parameters as 13787 // pointers. 13788 // Create 'T omp_orig;' variable. 13789 VarDecl *OmpOrigParm = 13790 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 13791 if (S != nullptr) { 13792 PushOnScopeChains(OmpPrivParm, S); 13793 PushOnScopeChains(OmpOrigParm, S); 13794 } else { 13795 DRD->addDecl(OmpPrivParm); 13796 DRD->addDecl(OmpOrigParm); 13797 } 13798 Expr *OrigE = 13799 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 13800 Expr *PrivE = 13801 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 13802 DRD->setInitializerData(OrigE, PrivE); 13803 return OmpPrivParm; 13804 } 13805 13806 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 13807 VarDecl *OmpPrivParm) { 13808 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13809 DiscardCleanupsInEvaluationContext(); 13810 PopExpressionEvaluationContext(); 13811 13812 PopDeclContext(); 13813 PopFunctionScopeInfo(); 13814 13815 if (Initializer != nullptr) { 13816 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 13817 } else if (OmpPrivParm->hasInit()) { 13818 DRD->setInitializer(OmpPrivParm->getInit(), 13819 OmpPrivParm->isDirectInit() 13820 ? OMPDeclareReductionDecl::DirectInit 13821 : OMPDeclareReductionDecl::CopyInit); 13822 } else { 13823 DRD->setInvalidDecl(); 13824 } 13825 } 13826 13827 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 13828 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 13829 for (Decl *D : DeclReductions.get()) { 13830 if (IsValid) { 13831 if (S) 13832 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 13833 /*AddToContext=*/false); 13834 } else { 13835 D->setInvalidDecl(); 13836 } 13837 } 13838 return DeclReductions; 13839 } 13840 13841 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 13842 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 13843 QualType T = TInfo->getType(); 13844 if (D.isInvalidType()) 13845 return true; 13846 13847 if (getLangOpts().CPlusPlus) { 13848 // Check that there are no default arguments (C++ only). 13849 CheckExtraCXXDefaultArguments(D); 13850 } 13851 13852 return CreateParsedType(T, TInfo); 13853 } 13854 13855 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 13856 TypeResult ParsedType) { 13857 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 13858 13859 QualType MapperType = GetTypeFromParser(ParsedType.get()); 13860 assert(!MapperType.isNull() && "Expect valid mapper type"); 13861 13862 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13863 // The type must be of struct, union or class type in C and C++ 13864 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 13865 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 13866 return QualType(); 13867 } 13868 return MapperType; 13869 } 13870 13871 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 13872 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 13873 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 13874 Decl *PrevDeclInScope) { 13875 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 13876 forRedeclarationInCurContext()); 13877 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13878 // A mapper-identifier may not be redeclared in the current scope for the 13879 // same type or for a type that is compatible according to the base language 13880 // rules. 13881 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 13882 OMPDeclareMapperDecl *PrevDMD = nullptr; 13883 bool InCompoundScope = true; 13884 if (S != nullptr) { 13885 // Find previous declaration with the same name not referenced in other 13886 // declarations. 13887 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 13888 InCompoundScope = 13889 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 13890 LookupName(Lookup, S); 13891 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 13892 /*AllowInlineNamespace=*/false); 13893 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 13894 LookupResult::Filter Filter = Lookup.makeFilter(); 13895 while (Filter.hasNext()) { 13896 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 13897 if (InCompoundScope) { 13898 auto I = UsedAsPrevious.find(PrevDecl); 13899 if (I == UsedAsPrevious.end()) 13900 UsedAsPrevious[PrevDecl] = false; 13901 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 13902 UsedAsPrevious[D] = true; 13903 } 13904 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 13905 PrevDecl->getLocation(); 13906 } 13907 Filter.done(); 13908 if (InCompoundScope) { 13909 for (const auto &PrevData : UsedAsPrevious) { 13910 if (!PrevData.second) { 13911 PrevDMD = PrevData.first; 13912 break; 13913 } 13914 } 13915 } 13916 } else if (PrevDeclInScope) { 13917 auto *PrevDMDInScope = PrevDMD = 13918 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 13919 do { 13920 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 13921 PrevDMDInScope->getLocation(); 13922 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 13923 } while (PrevDMDInScope != nullptr); 13924 } 13925 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 13926 bool Invalid = false; 13927 if (I != PreviousRedeclTypes.end()) { 13928 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 13929 << MapperType << Name; 13930 Diag(I->second, diag::note_previous_definition); 13931 Invalid = true; 13932 } 13933 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 13934 MapperType, VN, PrevDMD); 13935 DC->addDecl(DMD); 13936 DMD->setAccess(AS); 13937 if (Invalid) 13938 DMD->setInvalidDecl(); 13939 13940 // Enter new function scope. 13941 PushFunctionScope(); 13942 setFunctionHasBranchProtectedScope(); 13943 13944 CurContext = DMD; 13945 13946 return DMD; 13947 } 13948 13949 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 13950 Scope *S, 13951 QualType MapperType, 13952 SourceLocation StartLoc, 13953 DeclarationName VN) { 13954 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 13955 if (S) 13956 PushOnScopeChains(VD, S); 13957 else 13958 DMD->addDecl(VD); 13959 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 13960 DMD->setMapperVarRef(MapperVarRefExpr); 13961 } 13962 13963 Sema::DeclGroupPtrTy 13964 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 13965 ArrayRef<OMPClause *> ClauseList) { 13966 PopDeclContext(); 13967 PopFunctionScopeInfo(); 13968 13969 if (D) { 13970 if (S) 13971 PushOnScopeChains(D, S, /*AddToContext=*/false); 13972 D->CreateClauses(Context, ClauseList); 13973 } 13974 13975 return DeclGroupPtrTy::make(DeclGroupRef(D)); 13976 } 13977 13978 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 13979 SourceLocation StartLoc, 13980 SourceLocation LParenLoc, 13981 SourceLocation EndLoc) { 13982 Expr *ValExpr = NumTeams; 13983 Stmt *HelperValStmt = nullptr; 13984 13985 // OpenMP [teams Constrcut, Restrictions] 13986 // The num_teams expression must evaluate to a positive integer value. 13987 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 13988 /*StrictlyPositive=*/true)) 13989 return nullptr; 13990 13991 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13992 OpenMPDirectiveKind CaptureRegion = 13993 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 13994 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13995 ValExpr = MakeFullExpr(ValExpr).get(); 13996 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13997 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13998 HelperValStmt = buildPreInits(Context, Captures); 13999 } 14000 14001 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14002 StartLoc, LParenLoc, EndLoc); 14003 } 14004 14005 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14006 SourceLocation StartLoc, 14007 SourceLocation LParenLoc, 14008 SourceLocation EndLoc) { 14009 Expr *ValExpr = ThreadLimit; 14010 Stmt *HelperValStmt = nullptr; 14011 14012 // OpenMP [teams Constrcut, Restrictions] 14013 // The thread_limit expression must evaluate to a positive integer value. 14014 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14015 /*StrictlyPositive=*/true)) 14016 return nullptr; 14017 14018 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14019 OpenMPDirectiveKind CaptureRegion = 14020 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14021 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14022 ValExpr = MakeFullExpr(ValExpr).get(); 14023 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14024 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14025 HelperValStmt = buildPreInits(Context, Captures); 14026 } 14027 14028 return new (Context) OMPThreadLimitClause( 14029 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14030 } 14031 14032 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14033 SourceLocation StartLoc, 14034 SourceLocation LParenLoc, 14035 SourceLocation EndLoc) { 14036 Expr *ValExpr = Priority; 14037 14038 // OpenMP [2.9.1, task Constrcut] 14039 // The priority-value is a non-negative numerical scalar expression. 14040 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14041 /*StrictlyPositive=*/false)) 14042 return nullptr; 14043 14044 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14045 } 14046 14047 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14048 SourceLocation StartLoc, 14049 SourceLocation LParenLoc, 14050 SourceLocation EndLoc) { 14051 Expr *ValExpr = Grainsize; 14052 14053 // OpenMP [2.9.2, taskloop Constrcut] 14054 // The parameter of the grainsize clause must be a positive integer 14055 // expression. 14056 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14057 /*StrictlyPositive=*/true)) 14058 return nullptr; 14059 14060 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14061 } 14062 14063 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14064 SourceLocation StartLoc, 14065 SourceLocation LParenLoc, 14066 SourceLocation EndLoc) { 14067 Expr *ValExpr = NumTasks; 14068 14069 // OpenMP [2.9.2, taskloop Constrcut] 14070 // The parameter of the num_tasks clause must be a positive integer 14071 // expression. 14072 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14073 /*StrictlyPositive=*/true)) 14074 return nullptr; 14075 14076 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14077 } 14078 14079 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14080 SourceLocation LParenLoc, 14081 SourceLocation EndLoc) { 14082 // OpenMP [2.13.2, critical construct, Description] 14083 // ... where hint-expression is an integer constant expression that evaluates 14084 // to a valid lock hint. 14085 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14086 if (HintExpr.isInvalid()) 14087 return nullptr; 14088 return new (Context) 14089 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14090 } 14091 14092 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14093 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14094 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14095 SourceLocation EndLoc) { 14096 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14097 std::string Values; 14098 Values += "'"; 14099 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14100 Values += "'"; 14101 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14102 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14103 return nullptr; 14104 } 14105 Expr *ValExpr = ChunkSize; 14106 Stmt *HelperValStmt = nullptr; 14107 if (ChunkSize) { 14108 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14109 !ChunkSize->isInstantiationDependent() && 14110 !ChunkSize->containsUnexpandedParameterPack()) { 14111 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14112 ExprResult Val = 14113 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14114 if (Val.isInvalid()) 14115 return nullptr; 14116 14117 ValExpr = Val.get(); 14118 14119 // OpenMP [2.7.1, Restrictions] 14120 // chunk_size must be a loop invariant integer expression with a positive 14121 // value. 14122 llvm::APSInt Result; 14123 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14124 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14125 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14126 << "dist_schedule" << ChunkSize->getSourceRange(); 14127 return nullptr; 14128 } 14129 } else if (getOpenMPCaptureRegionForClause( 14130 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14131 OMPD_unknown && 14132 !CurContext->isDependentContext()) { 14133 ValExpr = MakeFullExpr(ValExpr).get(); 14134 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14135 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14136 HelperValStmt = buildPreInits(Context, Captures); 14137 } 14138 } 14139 } 14140 14141 return new (Context) 14142 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14143 Kind, ValExpr, HelperValStmt); 14144 } 14145 14146 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14147 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14148 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14149 SourceLocation KindLoc, SourceLocation EndLoc) { 14150 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14151 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14152 std::string Value; 14153 SourceLocation Loc; 14154 Value += "'"; 14155 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14156 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14157 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14158 Loc = MLoc; 14159 } else { 14160 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14161 OMPC_DEFAULTMAP_scalar); 14162 Loc = KindLoc; 14163 } 14164 Value += "'"; 14165 Diag(Loc, diag::err_omp_unexpected_clause_value) 14166 << Value << getOpenMPClauseName(OMPC_defaultmap); 14167 return nullptr; 14168 } 14169 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14170 14171 return new (Context) 14172 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14173 } 14174 14175 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14176 DeclContext *CurLexicalContext = getCurLexicalContext(); 14177 if (!CurLexicalContext->isFileContext() && 14178 !CurLexicalContext->isExternCContext() && 14179 !CurLexicalContext->isExternCXXContext() && 14180 !isa<CXXRecordDecl>(CurLexicalContext) && 14181 !isa<ClassTemplateDecl>(CurLexicalContext) && 14182 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14183 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14184 Diag(Loc, diag::err_omp_region_not_file_context); 14185 return false; 14186 } 14187 ++DeclareTargetNestingLevel; 14188 return true; 14189 } 14190 14191 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14192 assert(DeclareTargetNestingLevel > 0 && 14193 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14194 --DeclareTargetNestingLevel; 14195 } 14196 14197 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14198 CXXScopeSpec &ScopeSpec, 14199 const DeclarationNameInfo &Id, 14200 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14201 NamedDeclSetType &SameDirectiveDecls) { 14202 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14203 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14204 14205 if (Lookup.isAmbiguous()) 14206 return; 14207 Lookup.suppressDiagnostics(); 14208 14209 if (!Lookup.isSingleResult()) { 14210 if (TypoCorrection Corrected = 14211 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 14212 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 14213 CTK_ErrorRecovery)) { 14214 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14215 << Id.getName()); 14216 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14217 return; 14218 } 14219 14220 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14221 return; 14222 } 14223 14224 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14225 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14226 isa<FunctionTemplateDecl>(ND)) { 14227 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14228 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14229 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14230 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14231 cast<ValueDecl>(ND)); 14232 if (!Res) { 14233 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14234 ND->addAttr(A); 14235 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14236 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14237 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14238 } else if (*Res != MT) { 14239 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14240 << Id.getName(); 14241 } 14242 } else { 14243 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14244 } 14245 } 14246 14247 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14248 Sema &SemaRef, Decl *D) { 14249 if (!D || !isa<VarDecl>(D)) 14250 return; 14251 auto *VD = cast<VarDecl>(D); 14252 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14253 return; 14254 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14255 SemaRef.Diag(SL, diag::note_used_here) << SR; 14256 } 14257 14258 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14259 Sema &SemaRef, DSAStackTy *Stack, 14260 ValueDecl *VD) { 14261 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14262 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14263 /*FullCheck=*/false); 14264 } 14265 14266 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14267 SourceLocation IdLoc) { 14268 if (!D || D->isInvalidDecl()) 14269 return; 14270 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14271 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14272 if (auto *VD = dyn_cast<VarDecl>(D)) { 14273 // Only global variables can be marked as declare target. 14274 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14275 !VD->isStaticDataMember()) 14276 return; 14277 // 2.10.6: threadprivate variable cannot appear in a declare target 14278 // directive. 14279 if (DSAStack->isThreadPrivate(VD)) { 14280 Diag(SL, diag::err_omp_threadprivate_in_target); 14281 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14282 return; 14283 } 14284 } 14285 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14286 D = FTD->getTemplatedDecl(); 14287 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14288 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14289 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14290 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14291 assert(IdLoc.isValid() && "Source location is expected"); 14292 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14293 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14294 return; 14295 } 14296 } 14297 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14298 // Problem if any with var declared with incomplete type will be reported 14299 // as normal, so no need to check it here. 14300 if ((E || !VD->getType()->isIncompleteType()) && 14301 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14302 return; 14303 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14304 // Checking declaration inside declare target region. 14305 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14306 isa<FunctionTemplateDecl>(D)) { 14307 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14308 Context, OMPDeclareTargetDeclAttr::MT_To); 14309 D->addAttr(A); 14310 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14311 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14312 } 14313 return; 14314 } 14315 } 14316 if (!E) 14317 return; 14318 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 14319 } 14320 14321 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 14322 CXXScopeSpec &MapperIdScopeSpec, 14323 DeclarationNameInfo &MapperId, 14324 const OMPVarListLocTy &Locs, 14325 ArrayRef<Expr *> UnresolvedMappers) { 14326 MappableVarListInfo MVLI(VarList); 14327 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 14328 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14329 if (MVLI.ProcessedVarList.empty()) 14330 return nullptr; 14331 14332 return OMPToClause::Create( 14333 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14334 MVLI.VarComponents, MVLI.UDMapperList, 14335 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14336 } 14337 14338 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 14339 CXXScopeSpec &MapperIdScopeSpec, 14340 DeclarationNameInfo &MapperId, 14341 const OMPVarListLocTy &Locs, 14342 ArrayRef<Expr *> UnresolvedMappers) { 14343 MappableVarListInfo MVLI(VarList); 14344 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 14345 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14346 if (MVLI.ProcessedVarList.empty()) 14347 return nullptr; 14348 14349 return OMPFromClause::Create( 14350 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14351 MVLI.VarComponents, MVLI.UDMapperList, 14352 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14353 } 14354 14355 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 14356 const OMPVarListLocTy &Locs) { 14357 MappableVarListInfo MVLI(VarList); 14358 SmallVector<Expr *, 8> PrivateCopies; 14359 SmallVector<Expr *, 8> Inits; 14360 14361 for (Expr *RefExpr : VarList) { 14362 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 14363 SourceLocation ELoc; 14364 SourceRange ERange; 14365 Expr *SimpleRefExpr = RefExpr; 14366 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14367 if (Res.second) { 14368 // It will be analyzed later. 14369 MVLI.ProcessedVarList.push_back(RefExpr); 14370 PrivateCopies.push_back(nullptr); 14371 Inits.push_back(nullptr); 14372 } 14373 ValueDecl *D = Res.first; 14374 if (!D) 14375 continue; 14376 14377 QualType Type = D->getType(); 14378 Type = Type.getNonReferenceType().getUnqualifiedType(); 14379 14380 auto *VD = dyn_cast<VarDecl>(D); 14381 14382 // Item should be a pointer or reference to pointer. 14383 if (!Type->isPointerType()) { 14384 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 14385 << 0 << RefExpr->getSourceRange(); 14386 continue; 14387 } 14388 14389 // Build the private variable and the expression that refers to it. 14390 auto VDPrivate = 14391 buildVarDecl(*this, ELoc, Type, D->getName(), 14392 D->hasAttrs() ? &D->getAttrs() : nullptr, 14393 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14394 if (VDPrivate->isInvalidDecl()) 14395 continue; 14396 14397 CurContext->addDecl(VDPrivate); 14398 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14399 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 14400 14401 // Add temporary variable to initialize the private copy of the pointer. 14402 VarDecl *VDInit = 14403 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 14404 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 14405 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 14406 AddInitializerToDecl(VDPrivate, 14407 DefaultLvalueConversion(VDInitRefExpr).get(), 14408 /*DirectInit=*/false); 14409 14410 // If required, build a capture to implement the privatization initialized 14411 // with the current list item value. 14412 DeclRefExpr *Ref = nullptr; 14413 if (!VD) 14414 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14415 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 14416 PrivateCopies.push_back(VDPrivateRefExpr); 14417 Inits.push_back(VDInitRefExpr); 14418 14419 // We need to add a data sharing attribute for this variable to make sure it 14420 // is correctly captured. A variable that shows up in a use_device_ptr has 14421 // similar properties of a first private variable. 14422 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14423 14424 // Create a mappable component for the list item. List items in this clause 14425 // only need a component. 14426 MVLI.VarBaseDeclarations.push_back(D); 14427 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14428 MVLI.VarComponents.back().push_back( 14429 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 14430 } 14431 14432 if (MVLI.ProcessedVarList.empty()) 14433 return nullptr; 14434 14435 return OMPUseDevicePtrClause::Create( 14436 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 14437 MVLI.VarBaseDeclarations, MVLI.VarComponents); 14438 } 14439 14440 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 14441 const OMPVarListLocTy &Locs) { 14442 MappableVarListInfo MVLI(VarList); 14443 for (Expr *RefExpr : VarList) { 14444 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 14445 SourceLocation ELoc; 14446 SourceRange ERange; 14447 Expr *SimpleRefExpr = RefExpr; 14448 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14449 if (Res.second) { 14450 // It will be analyzed later. 14451 MVLI.ProcessedVarList.push_back(RefExpr); 14452 } 14453 ValueDecl *D = Res.first; 14454 if (!D) 14455 continue; 14456 14457 QualType Type = D->getType(); 14458 // item should be a pointer or array or reference to pointer or array 14459 if (!Type.getNonReferenceType()->isPointerType() && 14460 !Type.getNonReferenceType()->isArrayType()) { 14461 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 14462 << 0 << RefExpr->getSourceRange(); 14463 continue; 14464 } 14465 14466 // Check if the declaration in the clause does not show up in any data 14467 // sharing attribute. 14468 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14469 if (isOpenMPPrivate(DVar.CKind)) { 14470 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14471 << getOpenMPClauseName(DVar.CKind) 14472 << getOpenMPClauseName(OMPC_is_device_ptr) 14473 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14474 reportOriginalDsa(*this, DSAStack, D, DVar); 14475 continue; 14476 } 14477 14478 const Expr *ConflictExpr; 14479 if (DSAStack->checkMappableExprComponentListsForDecl( 14480 D, /*CurrentRegionOnly=*/true, 14481 [&ConflictExpr]( 14482 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 14483 OpenMPClauseKind) -> bool { 14484 ConflictExpr = R.front().getAssociatedExpression(); 14485 return true; 14486 })) { 14487 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 14488 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 14489 << ConflictExpr->getSourceRange(); 14490 continue; 14491 } 14492 14493 // Store the components in the stack so that they can be used to check 14494 // against other clauses later on. 14495 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 14496 DSAStack->addMappableExpressionComponents( 14497 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 14498 14499 // Record the expression we've just processed. 14500 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 14501 14502 // Create a mappable component for the list item. List items in this clause 14503 // only need a component. We use a null declaration to signal fields in 14504 // 'this'. 14505 assert((isa<DeclRefExpr>(SimpleRefExpr) || 14506 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 14507 "Unexpected device pointer expression!"); 14508 MVLI.VarBaseDeclarations.push_back( 14509 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 14510 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14511 MVLI.VarComponents.back().push_back(MC); 14512 } 14513 14514 if (MVLI.ProcessedVarList.empty()) 14515 return nullptr; 14516 14517 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 14518 MVLI.VarBaseDeclarations, 14519 MVLI.VarComponents); 14520 } 14521