1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// This file implements semantic analysis for OpenMP directives and 11 /// clauses. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "TreeTransform.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/ASTMutationListener.h" 18 #include "clang/AST/CXXInheritance.h" 19 #include "clang/AST/Decl.h" 20 #include "clang/AST/DeclCXX.h" 21 #include "clang/AST/DeclOpenMP.h" 22 #include "clang/AST/StmtCXX.h" 23 #include "clang/AST/StmtOpenMP.h" 24 #include "clang/AST/StmtVisitor.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 bool NowaitRegion = false; 142 bool CancelRegion = false; 143 unsigned AssociatedLoops = 1; 144 SourceLocation InnerTeamsRegionLoc; 145 /// Reference to the taskgroup task_reduction reference expression. 146 Expr *TaskgroupReductionRef = nullptr; 147 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 148 Scope *CurScope, SourceLocation Loc) 149 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 150 ConstructLoc(Loc) {} 151 SharingMapTy() = default; 152 }; 153 154 using StackTy = SmallVector<SharingMapTy, 4>; 155 156 /// Stack of used declaration and their data-sharing attributes. 157 DeclSAMapTy Threadprivates; 158 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 159 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 160 /// true, if check for DSA must be from parent directive, false, if 161 /// from current directive. 162 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 163 Sema &SemaRef; 164 bool ForceCapturing = false; 165 CriticalsWithHintsTy Criticals; 166 167 using iterator = StackTy::const_reverse_iterator; 168 169 DSAVarData getDSA(iterator &Iter, ValueDecl *D) const; 170 171 /// Checks if the variable is a local for OpenMP region. 172 bool isOpenMPLocal(VarDecl *D, iterator Iter) const; 173 174 bool isStackEmpty() const { 175 return Stack.empty() || 176 Stack.back().second != CurrentNonCapturingFunctionScope || 177 Stack.back().first.empty(); 178 } 179 180 public: 181 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 182 183 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 184 OpenMPClauseKind getClauseParsingMode() const { 185 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 186 return ClauseKindMode; 187 } 188 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 189 190 bool isForceVarCapturing() const { return ForceCapturing; } 191 void setForceVarCapturing(bool V) { ForceCapturing = V; } 192 193 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 194 Scope *CurScope, SourceLocation Loc) { 195 if (Stack.empty() || 196 Stack.back().second != CurrentNonCapturingFunctionScope) 197 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 198 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 199 Stack.back().first.back().DefaultAttrLoc = Loc; 200 } 201 202 void pop() { 203 assert(!Stack.back().first.empty() && 204 "Data-sharing attributes stack is empty!"); 205 Stack.back().first.pop_back(); 206 } 207 208 /// Start new OpenMP region stack in new non-capturing function. 209 void pushFunction() { 210 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 211 assert(!isa<CapturingScopeInfo>(CurFnScope)); 212 CurrentNonCapturingFunctionScope = CurFnScope; 213 } 214 /// Pop region stack for non-capturing function. 215 void popFunction(const FunctionScopeInfo *OldFSI) { 216 if (!Stack.empty() && Stack.back().second == OldFSI) { 217 assert(Stack.back().first.empty()); 218 Stack.pop_back(); 219 } 220 CurrentNonCapturingFunctionScope = nullptr; 221 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 222 if (!isa<CapturingScopeInfo>(FSI)) { 223 CurrentNonCapturingFunctionScope = FSI; 224 break; 225 } 226 } 227 } 228 229 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 230 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 231 } 232 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 233 getCriticalWithHint(const DeclarationNameInfo &Name) const { 234 auto I = Criticals.find(Name.getAsString()); 235 if (I != Criticals.end()) 236 return I->second; 237 return std::make_pair(nullptr, llvm::APSInt()); 238 } 239 /// If 'aligned' declaration for given variable \a D was not seen yet, 240 /// add it and return NULL; otherwise return previous occurrence's expression 241 /// for diagnostics. 242 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 243 244 /// Register specified variable as loop control variable. 245 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 246 /// Check if the specified variable is a loop control variable for 247 /// current region. 248 /// \return The index of the loop control variable in the list of associated 249 /// for-loops (from outer to inner). 250 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 251 /// Check if the specified variable is a loop control variable for 252 /// parent region. 253 /// \return The index of the loop control variable in the list of associated 254 /// for-loops (from outer to inner). 255 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 256 /// Get the loop control variable for the I-th loop (or nullptr) in 257 /// parent directive. 258 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 259 260 /// Adds explicit data sharing attribute to the specified declaration. 261 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 262 DeclRefExpr *PrivateCopy = nullptr); 263 264 /// Adds additional information for the reduction items with the reduction id 265 /// represented as an operator. 266 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 267 BinaryOperatorKind BOK); 268 /// Adds additional information for the reduction items with the reduction id 269 /// represented as reduction identifier. 270 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 271 const Expr *ReductionRef); 272 /// Returns the location and reduction operation from the innermost parent 273 /// region for the given \p D. 274 const DSAVarData 275 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 276 BinaryOperatorKind &BOK, 277 Expr *&TaskgroupDescriptor) const; 278 /// Returns the location and reduction operation from the innermost parent 279 /// region for the given \p D. 280 const DSAVarData 281 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 282 const Expr *&ReductionRef, 283 Expr *&TaskgroupDescriptor) const; 284 /// Return reduction reference expression for the current taskgroup. 285 Expr *getTaskgroupReductionRef() const { 286 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 287 "taskgroup reference expression requested for non taskgroup " 288 "directive."); 289 return Stack.back().first.back().TaskgroupReductionRef; 290 } 291 /// Checks if the given \p VD declaration is actually a taskgroup reduction 292 /// descriptor variable at the \p Level of OpenMP regions. 293 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 294 return Stack.back().first[Level].TaskgroupReductionRef && 295 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 296 ->getDecl() == VD; 297 } 298 299 /// Returns data sharing attributes from top of the stack for the 300 /// specified declaration. 301 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 302 /// Returns data-sharing attributes for the specified declaration. 303 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 304 /// Checks if the specified variables has data-sharing attributes which 305 /// match specified \a CPred predicate in any directive which matches \a DPred 306 /// predicate. 307 const DSAVarData 308 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 309 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 310 bool FromParent) const; 311 /// Checks if the specified variables has data-sharing attributes which 312 /// match specified \a CPred predicate in any innermost directive which 313 /// matches \a DPred predicate. 314 const DSAVarData 315 hasInnermostDSA(ValueDecl *D, 316 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 317 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 318 bool FromParent) const; 319 /// Checks if the specified variables has explicit data-sharing 320 /// attributes which match specified \a CPred predicate at the specified 321 /// OpenMP region. 322 bool hasExplicitDSA(const ValueDecl *D, 323 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 324 unsigned Level, bool NotLastprivate = false) const; 325 326 /// Returns true if the directive at level \Level matches in the 327 /// specified \a DPred predicate. 328 bool hasExplicitDirective( 329 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 330 unsigned Level) const; 331 332 /// Finds a directive which matches specified \a DPred predicate. 333 bool hasDirective( 334 const llvm::function_ref<bool( 335 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 336 DPred, 337 bool FromParent) const; 338 339 /// Returns currently analyzed directive. 340 OpenMPDirectiveKind getCurrentDirective() const { 341 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 342 } 343 /// Returns directive kind at specified level. 344 OpenMPDirectiveKind getDirective(unsigned Level) const { 345 assert(!isStackEmpty() && "No directive at specified level."); 346 return Stack.back().first[Level].Directive; 347 } 348 /// Returns parent directive. 349 OpenMPDirectiveKind getParentDirective() const { 350 if (isStackEmpty() || Stack.back().first.size() == 1) 351 return OMPD_unknown; 352 return std::next(Stack.back().first.rbegin())->Directive; 353 } 354 355 /// Set default data sharing attribute to none. 356 void setDefaultDSANone(SourceLocation Loc) { 357 assert(!isStackEmpty()); 358 Stack.back().first.back().DefaultAttr = DSA_none; 359 Stack.back().first.back().DefaultAttrLoc = Loc; 360 } 361 /// Set default data sharing attribute to shared. 362 void setDefaultDSAShared(SourceLocation Loc) { 363 assert(!isStackEmpty()); 364 Stack.back().first.back().DefaultAttr = DSA_shared; 365 Stack.back().first.back().DefaultAttrLoc = Loc; 366 } 367 /// Set default data mapping attribute to 'tofrom:scalar'. 368 void setDefaultDMAToFromScalar(SourceLocation Loc) { 369 assert(!isStackEmpty()); 370 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 371 Stack.back().first.back().DefaultMapAttrLoc = Loc; 372 } 373 374 DefaultDataSharingAttributes getDefaultDSA() const { 375 return isStackEmpty() ? DSA_unspecified 376 : Stack.back().first.back().DefaultAttr; 377 } 378 SourceLocation getDefaultDSALocation() const { 379 return isStackEmpty() ? SourceLocation() 380 : Stack.back().first.back().DefaultAttrLoc; 381 } 382 DefaultMapAttributes getDefaultDMA() const { 383 return isStackEmpty() ? DMA_unspecified 384 : Stack.back().first.back().DefaultMapAttr; 385 } 386 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 387 return Stack.back().first[Level].DefaultMapAttr; 388 } 389 SourceLocation getDefaultDMALocation() const { 390 return isStackEmpty() ? SourceLocation() 391 : Stack.back().first.back().DefaultMapAttrLoc; 392 } 393 394 /// Checks if the specified variable is a threadprivate. 395 bool isThreadPrivate(VarDecl *D) { 396 const DSAVarData DVar = getTopDSA(D, false); 397 return isOpenMPThreadPrivate(DVar.CKind); 398 } 399 400 /// Marks current region as ordered (it has an 'ordered' clause). 401 void setOrderedRegion(bool IsOrdered, const Expr *Param, 402 OMPOrderedClause *Clause) { 403 assert(!isStackEmpty()); 404 if (IsOrdered) 405 Stack.back().first.back().OrderedRegion.emplace(Param, Clause); 406 else 407 Stack.back().first.back().OrderedRegion.reset(); 408 } 409 /// Returns true, if region is ordered (has associated 'ordered' clause), 410 /// false - otherwise. 411 bool isOrderedRegion() const { 412 if (isStackEmpty()) 413 return false; 414 return Stack.back().first.rbegin()->OrderedRegion.hasValue(); 415 } 416 /// Returns optional parameter for the ordered region. 417 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 418 if (isStackEmpty() || 419 !Stack.back().first.rbegin()->OrderedRegion.hasValue()) 420 return std::make_pair(nullptr, nullptr); 421 return Stack.back().first.rbegin()->OrderedRegion.getValue(); 422 } 423 /// Returns true, if parent region is ordered (has associated 424 /// 'ordered' clause), false - otherwise. 425 bool isParentOrderedRegion() const { 426 if (isStackEmpty() || Stack.back().first.size() == 1) 427 return false; 428 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); 429 } 430 /// Returns optional parameter for the ordered region. 431 std::pair<const Expr *, OMPOrderedClause *> 432 getParentOrderedRegionParam() const { 433 if (isStackEmpty() || Stack.back().first.size() == 1 || 434 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) 435 return std::make_pair(nullptr, nullptr); 436 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); 437 } 438 /// Marks current region as nowait (it has a 'nowait' clause). 439 void setNowaitRegion(bool IsNowait = true) { 440 assert(!isStackEmpty()); 441 Stack.back().first.back().NowaitRegion = IsNowait; 442 } 443 /// Returns true, if parent region is nowait (has associated 444 /// 'nowait' clause), false - otherwise. 445 bool isParentNowaitRegion() const { 446 if (isStackEmpty() || Stack.back().first.size() == 1) 447 return false; 448 return std::next(Stack.back().first.rbegin())->NowaitRegion; 449 } 450 /// Marks parent region as cancel region. 451 void setParentCancelRegion(bool Cancel = true) { 452 if (!isStackEmpty() && Stack.back().first.size() > 1) { 453 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 454 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 455 } 456 } 457 /// Return true if current region has inner cancel construct. 458 bool isCancelRegion() const { 459 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 460 } 461 462 /// Set collapse value for the region. 463 void setAssociatedLoops(unsigned Val) { 464 assert(!isStackEmpty()); 465 Stack.back().first.back().AssociatedLoops = Val; 466 } 467 /// Return collapse value for region. 468 unsigned getAssociatedLoops() const { 469 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 470 } 471 472 /// Marks current target region as one with closely nested teams 473 /// region. 474 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 475 if (!isStackEmpty() && Stack.back().first.size() > 1) { 476 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 477 TeamsRegionLoc; 478 } 479 } 480 /// Returns true, if current region has closely nested teams region. 481 bool hasInnerTeamsRegion() const { 482 return getInnerTeamsRegionLoc().isValid(); 483 } 484 /// Returns location of the nested teams region (if any). 485 SourceLocation getInnerTeamsRegionLoc() const { 486 return isStackEmpty() ? SourceLocation() 487 : Stack.back().first.back().InnerTeamsRegionLoc; 488 } 489 490 Scope *getCurScope() const { 491 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 492 } 493 SourceLocation getConstructLoc() const { 494 return isStackEmpty() ? SourceLocation() 495 : Stack.back().first.back().ConstructLoc; 496 } 497 498 /// Do the check specified in \a Check to all component lists and return true 499 /// if any issue is found. 500 bool checkMappableExprComponentListsForDecl( 501 const ValueDecl *VD, bool CurrentRegionOnly, 502 const llvm::function_ref< 503 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 504 OpenMPClauseKind)> 505 Check) const { 506 if (isStackEmpty()) 507 return false; 508 auto SI = Stack.back().first.rbegin(); 509 auto SE = Stack.back().first.rend(); 510 511 if (SI == SE) 512 return false; 513 514 if (CurrentRegionOnly) 515 SE = std::next(SI); 516 else 517 std::advance(SI, 1); 518 519 for (; SI != SE; ++SI) { 520 auto MI = SI->MappedExprComponents.find(VD); 521 if (MI != SI->MappedExprComponents.end()) 522 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 523 MI->second.Components) 524 if (Check(L, MI->second.Kind)) 525 return true; 526 } 527 return false; 528 } 529 530 /// Do the check specified in \a Check to all component lists at a given level 531 /// and return true if any issue is found. 532 bool checkMappableExprComponentListsForDeclAtLevel( 533 const ValueDecl *VD, unsigned Level, 534 const llvm::function_ref< 535 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 536 OpenMPClauseKind)> 537 Check) const { 538 if (isStackEmpty()) 539 return false; 540 541 auto StartI = Stack.back().first.begin(); 542 auto EndI = Stack.back().first.end(); 543 if (std::distance(StartI, EndI) <= (int)Level) 544 return false; 545 std::advance(StartI, Level); 546 547 auto MI = StartI->MappedExprComponents.find(VD); 548 if (MI != StartI->MappedExprComponents.end()) 549 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 550 MI->second.Components) 551 if (Check(L, MI->second.Kind)) 552 return true; 553 return false; 554 } 555 556 /// Create a new mappable expression component list associated with a given 557 /// declaration and initialize it with the provided list of components. 558 void addMappableExpressionComponents( 559 const ValueDecl *VD, 560 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 561 OpenMPClauseKind WhereFoundClauseKind) { 562 assert(!isStackEmpty() && 563 "Not expecting to retrieve components from a empty stack!"); 564 MappedExprComponentTy &MEC = 565 Stack.back().first.back().MappedExprComponents[VD]; 566 // Create new entry and append the new components there. 567 MEC.Components.resize(MEC.Components.size() + 1); 568 MEC.Components.back().append(Components.begin(), Components.end()); 569 MEC.Kind = WhereFoundClauseKind; 570 } 571 572 unsigned getNestingLevel() const { 573 assert(!isStackEmpty()); 574 return Stack.back().first.size() - 1; 575 } 576 void addDoacrossDependClause(OMPDependClause *C, 577 const OperatorOffsetTy &OpsOffs) { 578 assert(!isStackEmpty() && Stack.back().first.size() > 1); 579 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 580 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 581 StackElem.DoacrossDepends.try_emplace(C, OpsOffs); 582 } 583 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 584 getDoacrossDependClauses() const { 585 assert(!isStackEmpty()); 586 const SharingMapTy &StackElem = Stack.back().first.back(); 587 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 588 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 589 return llvm::make_range(Ref.begin(), Ref.end()); 590 } 591 return llvm::make_range(StackElem.DoacrossDepends.end(), 592 StackElem.DoacrossDepends.end()); 593 } 594 }; 595 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 596 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 597 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 598 } 599 600 } // namespace 601 602 static const Expr *getExprAsWritten(const Expr *E) { 603 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 604 E = ExprTemp->getSubExpr(); 605 606 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 607 E = MTE->GetTemporaryExpr(); 608 609 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 610 E = Binder->getSubExpr(); 611 612 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 613 E = ICE->getSubExprAsWritten(); 614 return E->IgnoreParens(); 615 } 616 617 static Expr *getExprAsWritten(Expr *E) { 618 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 619 } 620 621 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 622 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 623 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 624 D = ME->getMemberDecl(); 625 const auto *VD = dyn_cast<VarDecl>(D); 626 const auto *FD = dyn_cast<FieldDecl>(D); 627 if (VD != nullptr) { 628 VD = VD->getCanonicalDecl(); 629 D = VD; 630 } else { 631 assert(FD); 632 FD = FD->getCanonicalDecl(); 633 D = FD; 634 } 635 return D; 636 } 637 638 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 639 return const_cast<ValueDecl *>( 640 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 641 } 642 643 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 644 ValueDecl *D) const { 645 D = getCanonicalDecl(D); 646 auto *VD = dyn_cast<VarDecl>(D); 647 const auto *FD = dyn_cast<FieldDecl>(D); 648 DSAVarData DVar; 649 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 650 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 651 // in a region but not in construct] 652 // File-scope or namespace-scope variables referenced in called routines 653 // in the region are shared unless they appear in a threadprivate 654 // directive. 655 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 656 DVar.CKind = OMPC_shared; 657 658 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 659 // in a region but not in construct] 660 // Variables with static storage duration that are declared in called 661 // routines in the region are shared. 662 if (VD && VD->hasGlobalStorage()) 663 DVar.CKind = OMPC_shared; 664 665 // Non-static data members are shared by default. 666 if (FD) 667 DVar.CKind = OMPC_shared; 668 669 return DVar; 670 } 671 672 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 673 // in a Construct, C/C++, predetermined, p.1] 674 // Variables with automatic storage duration that are declared in a scope 675 // inside the construct are private. 676 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 677 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 678 DVar.CKind = OMPC_private; 679 return DVar; 680 } 681 682 DVar.DKind = Iter->Directive; 683 // Explicitly specified attributes and local variables with predetermined 684 // attributes. 685 if (Iter->SharingMap.count(D)) { 686 const DSAInfo &Data = Iter->SharingMap.lookup(D); 687 DVar.RefExpr = Data.RefExpr.getPointer(); 688 DVar.PrivateCopy = Data.PrivateCopy; 689 DVar.CKind = Data.Attributes; 690 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 691 return DVar; 692 } 693 694 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 695 // in a Construct, C/C++, implicitly determined, p.1] 696 // In a parallel or task construct, the data-sharing attributes of these 697 // variables are determined by the default clause, if present. 698 switch (Iter->DefaultAttr) { 699 case DSA_shared: 700 DVar.CKind = OMPC_shared; 701 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 702 return DVar; 703 case DSA_none: 704 return DVar; 705 case DSA_unspecified: 706 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 707 // in a Construct, implicitly determined, p.2] 708 // In a parallel construct, if no default clause is present, these 709 // variables are shared. 710 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 711 if (isOpenMPParallelDirective(DVar.DKind) || 712 isOpenMPTeamsDirective(DVar.DKind)) { 713 DVar.CKind = OMPC_shared; 714 return DVar; 715 } 716 717 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 718 // in a Construct, implicitly determined, p.4] 719 // In a task construct, if no default clause is present, a variable that in 720 // the enclosing context is determined to be shared by all implicit tasks 721 // bound to the current team is shared. 722 if (isOpenMPTaskingDirective(DVar.DKind)) { 723 DSAVarData DVarTemp; 724 iterator I = Iter, E = Stack.back().first.rend(); 725 do { 726 ++I; 727 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 728 // Referenced in a Construct, implicitly determined, p.6] 729 // In a task construct, if no default clause is present, a variable 730 // whose data-sharing attribute is not determined by the rules above is 731 // firstprivate. 732 DVarTemp = getDSA(I, D); 733 if (DVarTemp.CKind != OMPC_shared) { 734 DVar.RefExpr = nullptr; 735 DVar.CKind = OMPC_firstprivate; 736 return DVar; 737 } 738 } while (I != E && !isParallelOrTaskRegion(I->Directive)); 739 DVar.CKind = 740 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 741 return DVar; 742 } 743 } 744 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 745 // in a Construct, implicitly determined, p.3] 746 // For constructs other than task, if no default clause is present, these 747 // variables inherit their data-sharing attributes from the enclosing 748 // context. 749 return getDSA(++Iter, D); 750 } 751 752 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 753 const Expr *NewDE) { 754 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 755 D = getCanonicalDecl(D); 756 SharingMapTy &StackElem = Stack.back().first.back(); 757 auto It = StackElem.AlignedMap.find(D); 758 if (It == StackElem.AlignedMap.end()) { 759 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 760 StackElem.AlignedMap[D] = NewDE; 761 return nullptr; 762 } 763 assert(It->second && "Unexpected nullptr expr in the aligned map"); 764 return It->second; 765 } 766 767 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 768 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 769 D = getCanonicalDecl(D); 770 SharingMapTy &StackElem = Stack.back().first.back(); 771 StackElem.LCVMap.try_emplace( 772 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 773 } 774 775 const DSAStackTy::LCDeclInfo 776 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 777 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 778 D = getCanonicalDecl(D); 779 const SharingMapTy &StackElem = Stack.back().first.back(); 780 auto It = StackElem.LCVMap.find(D); 781 if (It != StackElem.LCVMap.end()) 782 return It->second; 783 return {0, nullptr}; 784 } 785 786 const DSAStackTy::LCDeclInfo 787 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 788 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 789 "Data-sharing attributes stack is empty"); 790 D = getCanonicalDecl(D); 791 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 792 auto It = StackElem.LCVMap.find(D); 793 if (It != StackElem.LCVMap.end()) 794 return It->second; 795 return {0, nullptr}; 796 } 797 798 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 799 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 800 "Data-sharing attributes stack is empty"); 801 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 802 if (StackElem.LCVMap.size() < I) 803 return nullptr; 804 for (const auto &Pair : StackElem.LCVMap) 805 if (Pair.second.first == I) 806 return Pair.first; 807 return nullptr; 808 } 809 810 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 811 DeclRefExpr *PrivateCopy) { 812 D = getCanonicalDecl(D); 813 if (A == OMPC_threadprivate) { 814 DSAInfo &Data = Threadprivates[D]; 815 Data.Attributes = A; 816 Data.RefExpr.setPointer(E); 817 Data.PrivateCopy = nullptr; 818 } else { 819 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 820 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 821 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 822 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 823 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 824 (isLoopControlVariable(D).first && A == OMPC_private)); 825 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 826 Data.RefExpr.setInt(/*IntVal=*/true); 827 return; 828 } 829 const bool IsLastprivate = 830 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 831 Data.Attributes = A; 832 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 833 Data.PrivateCopy = PrivateCopy; 834 if (PrivateCopy) { 835 DSAInfo &Data = 836 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 837 Data.Attributes = A; 838 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 839 Data.PrivateCopy = nullptr; 840 } 841 } 842 } 843 844 /// Build a variable declaration for OpenMP loop iteration variable. 845 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 846 StringRef Name, const AttrVec *Attrs = nullptr, 847 DeclRefExpr *OrigRef = nullptr) { 848 DeclContext *DC = SemaRef.CurContext; 849 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 850 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 851 auto *Decl = 852 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 853 if (Attrs) { 854 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 855 I != E; ++I) 856 Decl->addAttr(*I); 857 } 858 Decl->setImplicit(); 859 if (OrigRef) { 860 Decl->addAttr( 861 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 862 } 863 return Decl; 864 } 865 866 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 867 SourceLocation Loc, 868 bool RefersToCapture = false) { 869 D->setReferenced(); 870 D->markUsed(S.Context); 871 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 872 SourceLocation(), D, RefersToCapture, Loc, Ty, 873 VK_LValue); 874 } 875 876 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 877 BinaryOperatorKind BOK) { 878 D = getCanonicalDecl(D); 879 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 880 assert( 881 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 882 "Additional reduction info may be specified only for reduction items."); 883 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 884 assert(ReductionData.ReductionRange.isInvalid() && 885 Stack.back().first.back().Directive == OMPD_taskgroup && 886 "Additional reduction info may be specified only once for reduction " 887 "items."); 888 ReductionData.set(BOK, SR); 889 Expr *&TaskgroupReductionRef = 890 Stack.back().first.back().TaskgroupReductionRef; 891 if (!TaskgroupReductionRef) { 892 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 893 SemaRef.Context.VoidPtrTy, ".task_red."); 894 TaskgroupReductionRef = 895 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 896 } 897 } 898 899 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 900 const Expr *ReductionRef) { 901 D = getCanonicalDecl(D); 902 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 903 assert( 904 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 905 "Additional reduction info may be specified only for reduction items."); 906 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 907 assert(ReductionData.ReductionRange.isInvalid() && 908 Stack.back().first.back().Directive == OMPD_taskgroup && 909 "Additional reduction info may be specified only once for reduction " 910 "items."); 911 ReductionData.set(ReductionRef, SR); 912 Expr *&TaskgroupReductionRef = 913 Stack.back().first.back().TaskgroupReductionRef; 914 if (!TaskgroupReductionRef) { 915 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 916 SemaRef.Context.VoidPtrTy, ".task_red."); 917 TaskgroupReductionRef = 918 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 919 } 920 } 921 922 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 923 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 924 Expr *&TaskgroupDescriptor) const { 925 D = getCanonicalDecl(D); 926 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 927 if (Stack.back().first.empty()) 928 return DSAVarData(); 929 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 930 E = Stack.back().first.rend(); 931 I != E; std::advance(I, 1)) { 932 const DSAInfo &Data = I->SharingMap.lookup(D); 933 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 934 continue; 935 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 936 if (!ReductionData.ReductionOp || 937 ReductionData.ReductionOp.is<const Expr *>()) 938 return DSAVarData(); 939 SR = ReductionData.ReductionRange; 940 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 941 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 942 "expression for the descriptor is not " 943 "set."); 944 TaskgroupDescriptor = I->TaskgroupReductionRef; 945 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 946 Data.PrivateCopy, I->DefaultAttrLoc); 947 } 948 return DSAVarData(); 949 } 950 951 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 952 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 953 Expr *&TaskgroupDescriptor) const { 954 D = getCanonicalDecl(D); 955 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 956 if (Stack.back().first.empty()) 957 return DSAVarData(); 958 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 959 E = Stack.back().first.rend(); 960 I != E; std::advance(I, 1)) { 961 const DSAInfo &Data = I->SharingMap.lookup(D); 962 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 963 continue; 964 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 965 if (!ReductionData.ReductionOp || 966 !ReductionData.ReductionOp.is<const Expr *>()) 967 return DSAVarData(); 968 SR = ReductionData.ReductionRange; 969 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 970 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 971 "expression for the descriptor is not " 972 "set."); 973 TaskgroupDescriptor = I->TaskgroupReductionRef; 974 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 975 Data.PrivateCopy, I->DefaultAttrLoc); 976 } 977 return DSAVarData(); 978 } 979 980 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 981 D = D->getCanonicalDecl(); 982 if (!isStackEmpty()) { 983 iterator I = Iter, E = Stack.back().first.rend(); 984 Scope *TopScope = nullptr; 985 while (I != E && !isParallelOrTaskRegion(I->Directive) && 986 !isOpenMPTargetExecutionDirective(I->Directive)) 987 ++I; 988 if (I == E) 989 return false; 990 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 991 Scope *CurScope = getCurScope(); 992 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 993 CurScope = CurScope->getParent(); 994 return CurScope != TopScope; 995 } 996 return false; 997 } 998 999 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1000 bool FromParent) { 1001 D = getCanonicalDecl(D); 1002 DSAVarData DVar; 1003 1004 auto *VD = dyn_cast<VarDecl>(D); 1005 auto TI = Threadprivates.find(D); 1006 if (TI != Threadprivates.end()) { 1007 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1008 DVar.CKind = OMPC_threadprivate; 1009 return DVar; 1010 } 1011 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1012 DVar.RefExpr = buildDeclRefExpr( 1013 SemaRef, VD, D->getType().getNonReferenceType(), 1014 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1015 DVar.CKind = OMPC_threadprivate; 1016 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1017 return DVar; 1018 } 1019 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1020 // in a Construct, C/C++, predetermined, p.1] 1021 // Variables appearing in threadprivate directives are threadprivate. 1022 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1023 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1024 SemaRef.getLangOpts().OpenMPUseTLS && 1025 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1026 (VD && VD->getStorageClass() == SC_Register && 1027 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1028 DVar.RefExpr = buildDeclRefExpr( 1029 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1030 DVar.CKind = OMPC_threadprivate; 1031 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1032 return DVar; 1033 } 1034 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1035 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1036 !isLoopControlVariable(D).first) { 1037 iterator IterTarget = 1038 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1039 [](const SharingMapTy &Data) { 1040 return isOpenMPTargetExecutionDirective(Data.Directive); 1041 }); 1042 if (IterTarget != Stack.back().first.rend()) { 1043 iterator ParentIterTarget = std::next(IterTarget, 1); 1044 for (iterator Iter = Stack.back().first.rbegin(); 1045 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1046 if (isOpenMPLocal(VD, Iter)) { 1047 DVar.RefExpr = 1048 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1049 D->getLocation()); 1050 DVar.CKind = OMPC_threadprivate; 1051 return DVar; 1052 } 1053 } 1054 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1055 auto DSAIter = IterTarget->SharingMap.find(D); 1056 if (DSAIter != IterTarget->SharingMap.end() && 1057 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1058 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1059 DVar.CKind = OMPC_threadprivate; 1060 return DVar; 1061 } 1062 iterator End = Stack.back().first.rend(); 1063 if (!SemaRef.isOpenMPCapturedByRef( 1064 D, std::distance(ParentIterTarget, End))) { 1065 DVar.RefExpr = 1066 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1067 IterTarget->ConstructLoc); 1068 DVar.CKind = OMPC_threadprivate; 1069 return DVar; 1070 } 1071 } 1072 } 1073 } 1074 1075 if (isStackEmpty()) 1076 // Not in OpenMP execution region and top scope was already checked. 1077 return DVar; 1078 1079 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1080 // in a Construct, C/C++, predetermined, p.4] 1081 // Static data members are shared. 1082 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1083 // in a Construct, C/C++, predetermined, p.7] 1084 // Variables with static storage duration that are declared in a scope 1085 // inside the construct are shared. 1086 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1087 if (VD && VD->isStaticDataMember()) { 1088 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1089 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1090 return DVar; 1091 1092 DVar.CKind = OMPC_shared; 1093 return DVar; 1094 } 1095 1096 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 1097 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 1098 Type = SemaRef.getASTContext().getBaseElementType(Type); 1099 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1100 // in a Construct, C/C++, predetermined, p.6] 1101 // Variables with const qualified type having no mutable member are 1102 // shared. 1103 const CXXRecordDecl *RD = 1104 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 1105 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1106 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1107 RD = CTD->getTemplatedDecl(); 1108 if (IsConstant && 1109 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 1110 RD->hasMutableFields())) { 1111 // Variables with const-qualified type having no mutable member may be 1112 // listed in a firstprivate clause, even if they are static data members. 1113 DSAVarData DVarTemp = 1114 hasDSA(D, [](OpenMPClauseKind C) { return C == OMPC_firstprivate; }, 1115 MatchesAlways, FromParent); 1116 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 1117 return DVarTemp; 1118 1119 DVar.CKind = OMPC_shared; 1120 return DVar; 1121 } 1122 1123 // Explicitly specified attributes and local variables with predetermined 1124 // attributes. 1125 iterator I = Stack.back().first.rbegin(); 1126 iterator EndI = Stack.back().first.rend(); 1127 if (FromParent && I != EndI) 1128 std::advance(I, 1); 1129 auto It = I->SharingMap.find(D); 1130 if (It != I->SharingMap.end()) { 1131 const DSAInfo &Data = It->getSecond(); 1132 DVar.RefExpr = Data.RefExpr.getPointer(); 1133 DVar.PrivateCopy = Data.PrivateCopy; 1134 DVar.CKind = Data.Attributes; 1135 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1136 DVar.DKind = I->Directive; 1137 } 1138 1139 return DVar; 1140 } 1141 1142 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1143 bool FromParent) const { 1144 if (isStackEmpty()) { 1145 iterator I; 1146 return getDSA(I, D); 1147 } 1148 D = getCanonicalDecl(D); 1149 iterator StartI = Stack.back().first.rbegin(); 1150 iterator EndI = Stack.back().first.rend(); 1151 if (FromParent && StartI != EndI) 1152 std::advance(StartI, 1); 1153 return getDSA(StartI, D); 1154 } 1155 1156 const DSAStackTy::DSAVarData 1157 DSAStackTy::hasDSA(ValueDecl *D, 1158 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1159 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1160 bool FromParent) const { 1161 if (isStackEmpty()) 1162 return {}; 1163 D = getCanonicalDecl(D); 1164 iterator I = Stack.back().first.rbegin(); 1165 iterator EndI = Stack.back().first.rend(); 1166 if (FromParent && I != EndI) 1167 std::advance(I, 1); 1168 for (; I != EndI; std::advance(I, 1)) { 1169 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 1170 continue; 1171 iterator NewI = I; 1172 DSAVarData DVar = getDSA(NewI, D); 1173 if (I == NewI && CPred(DVar.CKind)) 1174 return DVar; 1175 } 1176 return {}; 1177 } 1178 1179 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1180 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1181 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1182 bool FromParent) const { 1183 if (isStackEmpty()) 1184 return {}; 1185 D = getCanonicalDecl(D); 1186 iterator StartI = Stack.back().first.rbegin(); 1187 iterator EndI = Stack.back().first.rend(); 1188 if (FromParent && StartI != EndI) 1189 std::advance(StartI, 1); 1190 if (StartI == EndI || !DPred(StartI->Directive)) 1191 return {}; 1192 iterator NewI = StartI; 1193 DSAVarData DVar = getDSA(NewI, D); 1194 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1195 } 1196 1197 bool DSAStackTy::hasExplicitDSA( 1198 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1199 unsigned Level, bool NotLastprivate) const { 1200 if (isStackEmpty()) 1201 return false; 1202 D = getCanonicalDecl(D); 1203 auto StartI = Stack.back().first.begin(); 1204 auto EndI = Stack.back().first.end(); 1205 if (std::distance(StartI, EndI) <= (int)Level) 1206 return false; 1207 std::advance(StartI, Level); 1208 auto I = StartI->SharingMap.find(D); 1209 return (I != StartI->SharingMap.end()) && 1210 I->getSecond().RefExpr.getPointer() && 1211 CPred(I->getSecond().Attributes) && 1212 (!NotLastprivate || !I->getSecond().RefExpr.getInt()); 1213 } 1214 1215 bool DSAStackTy::hasExplicitDirective( 1216 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1217 unsigned Level) const { 1218 if (isStackEmpty()) 1219 return false; 1220 auto StartI = Stack.back().first.begin(); 1221 auto EndI = Stack.back().first.end(); 1222 if (std::distance(StartI, EndI) <= (int)Level) 1223 return false; 1224 std::advance(StartI, Level); 1225 return DPred(StartI->Directive); 1226 } 1227 1228 bool DSAStackTy::hasDirective( 1229 const llvm::function_ref<bool(OpenMPDirectiveKind, 1230 const DeclarationNameInfo &, SourceLocation)> 1231 DPred, 1232 bool FromParent) const { 1233 // We look only in the enclosing region. 1234 if (isStackEmpty()) 1235 return false; 1236 auto StartI = std::next(Stack.back().first.rbegin()); 1237 auto EndI = Stack.back().first.rend(); 1238 if (FromParent && StartI != EndI) 1239 StartI = std::next(StartI); 1240 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1241 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1242 return true; 1243 } 1244 return false; 1245 } 1246 1247 void Sema::InitDataSharingAttributesStack() { 1248 VarDataSharingAttributesStack = new DSAStackTy(*this); 1249 } 1250 1251 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1252 1253 void Sema::pushOpenMPFunctionRegion() { 1254 DSAStack->pushFunction(); 1255 } 1256 1257 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1258 DSAStack->popFunction(OldFSI); 1259 } 1260 1261 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1262 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1263 1264 ASTContext &Ctx = getASTContext(); 1265 bool IsByRef = true; 1266 1267 // Find the directive that is associated with the provided scope. 1268 D = cast<ValueDecl>(D->getCanonicalDecl()); 1269 QualType Ty = D->getType(); 1270 1271 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1272 // This table summarizes how a given variable should be passed to the device 1273 // given its type and the clauses where it appears. This table is based on 1274 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1275 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1276 // 1277 // ========================================================================= 1278 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1279 // | |(tofrom:scalar)| | pvt | | | | 1280 // ========================================================================= 1281 // | scl | | | | - | | bycopy| 1282 // | scl | | - | x | - | - | bycopy| 1283 // | scl | | x | - | - | - | null | 1284 // | scl | x | | | - | | byref | 1285 // | scl | x | - | x | - | - | bycopy| 1286 // | scl | x | x | - | - | - | null | 1287 // | scl | | - | - | - | x | byref | 1288 // | scl | x | - | - | - | x | byref | 1289 // 1290 // | agg | n.a. | | | - | | byref | 1291 // | agg | n.a. | - | x | - | - | byref | 1292 // | agg | n.a. | x | - | - | - | null | 1293 // | agg | n.a. | - | - | - | x | byref | 1294 // | agg | n.a. | - | - | - | x[] | byref | 1295 // 1296 // | ptr | n.a. | | | - | | bycopy| 1297 // | ptr | n.a. | - | x | - | - | bycopy| 1298 // | ptr | n.a. | x | - | - | - | null | 1299 // | ptr | n.a. | - | - | - | x | byref | 1300 // | ptr | n.a. | - | - | - | x[] | bycopy| 1301 // | ptr | n.a. | - | - | x | | bycopy| 1302 // | ptr | n.a. | - | - | x | x | bycopy| 1303 // | ptr | n.a. | - | - | x | x[] | bycopy| 1304 // ========================================================================= 1305 // Legend: 1306 // scl - scalar 1307 // ptr - pointer 1308 // agg - aggregate 1309 // x - applies 1310 // - - invalid in this combination 1311 // [] - mapped with an array section 1312 // byref - should be mapped by reference 1313 // byval - should be mapped by value 1314 // null - initialize a local variable to null on the device 1315 // 1316 // Observations: 1317 // - All scalar declarations that show up in a map clause have to be passed 1318 // by reference, because they may have been mapped in the enclosing data 1319 // environment. 1320 // - If the scalar value does not fit the size of uintptr, it has to be 1321 // passed by reference, regardless the result in the table above. 1322 // - For pointers mapped by value that have either an implicit map or an 1323 // array section, the runtime library may pass the NULL value to the 1324 // device instead of the value passed to it by the compiler. 1325 1326 if (Ty->isReferenceType()) 1327 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1328 1329 // Locate map clauses and see if the variable being captured is referred to 1330 // in any of those clauses. Here we only care about variables, not fields, 1331 // because fields are part of aggregates. 1332 bool IsVariableUsedInMapClause = false; 1333 bool IsVariableAssociatedWithSection = false; 1334 1335 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1336 D, Level, 1337 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1338 OMPClauseMappableExprCommon::MappableExprComponentListRef 1339 MapExprComponents, 1340 OpenMPClauseKind WhereFoundClauseKind) { 1341 // Only the map clause information influences how a variable is 1342 // captured. E.g. is_device_ptr does not require changing the default 1343 // behavior. 1344 if (WhereFoundClauseKind != OMPC_map) 1345 return false; 1346 1347 auto EI = MapExprComponents.rbegin(); 1348 auto EE = MapExprComponents.rend(); 1349 1350 assert(EI != EE && "Invalid map expression!"); 1351 1352 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1353 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1354 1355 ++EI; 1356 if (EI == EE) 1357 return false; 1358 1359 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1360 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1361 isa<MemberExpr>(EI->getAssociatedExpression())) { 1362 IsVariableAssociatedWithSection = true; 1363 // There is nothing more we need to know about this variable. 1364 return true; 1365 } 1366 1367 // Keep looking for more map info. 1368 return false; 1369 }); 1370 1371 if (IsVariableUsedInMapClause) { 1372 // If variable is identified in a map clause it is always captured by 1373 // reference except if it is a pointer that is dereferenced somehow. 1374 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1375 } else { 1376 // By default, all the data that has a scalar type is mapped by copy 1377 // (except for reduction variables). 1378 IsByRef = 1379 !Ty->isScalarType() || 1380 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1381 DSAStack->hasExplicitDSA( 1382 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1383 } 1384 } 1385 1386 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1387 IsByRef = 1388 !DSAStack->hasExplicitDSA( 1389 D, 1390 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1391 Level, /*NotLastprivate=*/true) && 1392 // If the variable is artificial and must be captured by value - try to 1393 // capture by value. 1394 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1395 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1396 } 1397 1398 // When passing data by copy, we need to make sure it fits the uintptr size 1399 // and alignment, because the runtime library only deals with uintptr types. 1400 // If it does not fit the uintptr size, we need to pass the data by reference 1401 // instead. 1402 if (!IsByRef && 1403 (Ctx.getTypeSizeInChars(Ty) > 1404 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1405 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1406 IsByRef = true; 1407 } 1408 1409 return IsByRef; 1410 } 1411 1412 unsigned Sema::getOpenMPNestingLevel() const { 1413 assert(getLangOpts().OpenMP); 1414 return DSAStack->getNestingLevel(); 1415 } 1416 1417 bool Sema::isInOpenMPTargetExecutionDirective() const { 1418 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1419 !DSAStack->isClauseParsingMode()) || 1420 DSAStack->hasDirective( 1421 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1422 SourceLocation) -> bool { 1423 return isOpenMPTargetExecutionDirective(K); 1424 }, 1425 false); 1426 } 1427 1428 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { 1429 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1430 D = getCanonicalDecl(D); 1431 1432 // If we are attempting to capture a global variable in a directive with 1433 // 'target' we return true so that this global is also mapped to the device. 1434 // 1435 auto *VD = dyn_cast<VarDecl>(D); 1436 if (VD && !VD->hasLocalStorage()) { 1437 if (isInOpenMPDeclareTargetContext() && 1438 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1439 // Try to mark variable as declare target if it is used in capturing 1440 // regions. 1441 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1442 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1443 return nullptr; 1444 } else if (isInOpenMPTargetExecutionDirective()) { 1445 // If the declaration is enclosed in a 'declare target' directive, 1446 // then it should not be captured. 1447 // 1448 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1449 return nullptr; 1450 return VD; 1451 } 1452 } 1453 1454 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1455 (!DSAStack->isClauseParsingMode() || 1456 DSAStack->getParentDirective() != OMPD_unknown)) { 1457 auto &&Info = DSAStack->isLoopControlVariable(D); 1458 if (Info.first || 1459 (VD && VD->hasLocalStorage() && 1460 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1461 (VD && DSAStack->isForceVarCapturing())) 1462 return VD ? VD : Info.second; 1463 DSAStackTy::DSAVarData DVarPrivate = 1464 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1465 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1466 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1467 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1468 [](OpenMPDirectiveKind) { return true; }, 1469 DSAStack->isClauseParsingMode()); 1470 if (DVarPrivate.CKind != OMPC_unknown) 1471 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1472 } 1473 return nullptr; 1474 } 1475 1476 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1477 unsigned Level) const { 1478 SmallVector<OpenMPDirectiveKind, 4> Regions; 1479 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1480 FunctionScopesIndex -= Regions.size(); 1481 } 1482 1483 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1484 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1485 return DSAStack->hasExplicitDSA( 1486 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1487 (DSAStack->isClauseParsingMode() && 1488 DSAStack->getClauseParsingMode() == OMPC_private) || 1489 // Consider taskgroup reduction descriptor variable a private to avoid 1490 // possible capture in the region. 1491 (DSAStack->hasExplicitDirective( 1492 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1493 Level) && 1494 DSAStack->isTaskgroupReductionRef(D, Level)); 1495 } 1496 1497 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1498 unsigned Level) { 1499 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1500 D = getCanonicalDecl(D); 1501 OpenMPClauseKind OMPC = OMPC_unknown; 1502 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1503 const unsigned NewLevel = I - 1; 1504 if (DSAStack->hasExplicitDSA(D, 1505 [&OMPC](const OpenMPClauseKind K) { 1506 if (isOpenMPPrivate(K)) { 1507 OMPC = K; 1508 return true; 1509 } 1510 return false; 1511 }, 1512 NewLevel)) 1513 break; 1514 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1515 D, NewLevel, 1516 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1517 OpenMPClauseKind) { return true; })) { 1518 OMPC = OMPC_map; 1519 break; 1520 } 1521 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1522 NewLevel)) { 1523 OMPC = OMPC_map; 1524 if (D->getType()->isScalarType() && 1525 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1526 DefaultMapAttributes::DMA_tofrom_scalar) 1527 OMPC = OMPC_firstprivate; 1528 break; 1529 } 1530 } 1531 if (OMPC != OMPC_unknown) 1532 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1533 } 1534 1535 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1536 unsigned Level) const { 1537 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1538 // Return true if the current level is no longer enclosed in a target region. 1539 1540 const auto *VD = dyn_cast<VarDecl>(D); 1541 return VD && !VD->hasLocalStorage() && 1542 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1543 Level); 1544 } 1545 1546 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1547 1548 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1549 const DeclarationNameInfo &DirName, 1550 Scope *CurScope, SourceLocation Loc) { 1551 DSAStack->push(DKind, DirName, CurScope, Loc); 1552 PushExpressionEvaluationContext( 1553 ExpressionEvaluationContext::PotentiallyEvaluated); 1554 } 1555 1556 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1557 DSAStack->setClauseParsingMode(K); 1558 } 1559 1560 void Sema::EndOpenMPClause() { 1561 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1562 } 1563 1564 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1565 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1566 // A variable of class type (or array thereof) that appears in a lastprivate 1567 // clause requires an accessible, unambiguous default constructor for the 1568 // class type, unless the list item is also specified in a firstprivate 1569 // clause. 1570 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1571 for (OMPClause *C : D->clauses()) { 1572 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1573 SmallVector<Expr *, 8> PrivateCopies; 1574 for (Expr *DE : Clause->varlists()) { 1575 if (DE->isValueDependent() || DE->isTypeDependent()) { 1576 PrivateCopies.push_back(nullptr); 1577 continue; 1578 } 1579 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1580 auto *VD = cast<VarDecl>(DRE->getDecl()); 1581 QualType Type = VD->getType().getNonReferenceType(); 1582 const DSAStackTy::DSAVarData DVar = 1583 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1584 if (DVar.CKind == OMPC_lastprivate) { 1585 // Generate helper private variable and initialize it with the 1586 // default value. The address of the original variable is replaced 1587 // by the address of the new private variable in CodeGen. This new 1588 // variable is not added to IdResolver, so the code in the OpenMP 1589 // region uses original variable for proper diagnostics. 1590 VarDecl *VDPrivate = buildVarDecl( 1591 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1592 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1593 ActOnUninitializedDecl(VDPrivate); 1594 if (VDPrivate->isInvalidDecl()) 1595 continue; 1596 PrivateCopies.push_back(buildDeclRefExpr( 1597 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1598 } else { 1599 // The variable is also a firstprivate, so initialization sequence 1600 // for private copy is generated already. 1601 PrivateCopies.push_back(nullptr); 1602 } 1603 } 1604 // Set initializers to private copies if no errors were found. 1605 if (PrivateCopies.size() == Clause->varlist_size()) 1606 Clause->setPrivateCopies(PrivateCopies); 1607 } 1608 } 1609 } 1610 1611 DSAStack->pop(); 1612 DiscardCleanupsInEvaluationContext(); 1613 PopExpressionEvaluationContext(); 1614 } 1615 1616 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1617 Expr *NumIterations, Sema &SemaRef, 1618 Scope *S, DSAStackTy *Stack); 1619 1620 namespace { 1621 1622 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1623 private: 1624 Sema &SemaRef; 1625 1626 public: 1627 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1628 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1629 NamedDecl *ND = Candidate.getCorrectionDecl(); 1630 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1631 return VD->hasGlobalStorage() && 1632 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1633 SemaRef.getCurScope()); 1634 } 1635 return false; 1636 } 1637 }; 1638 1639 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 1640 private: 1641 Sema &SemaRef; 1642 1643 public: 1644 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1645 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1646 NamedDecl *ND = Candidate.getCorrectionDecl(); 1647 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) { 1648 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1649 SemaRef.getCurScope()); 1650 } 1651 return false; 1652 } 1653 }; 1654 1655 } // namespace 1656 1657 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1658 CXXScopeSpec &ScopeSpec, 1659 const DeclarationNameInfo &Id) { 1660 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1661 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1662 1663 if (Lookup.isAmbiguous()) 1664 return ExprError(); 1665 1666 VarDecl *VD; 1667 if (!Lookup.isSingleResult()) { 1668 if (TypoCorrection Corrected = CorrectTypo( 1669 Id, LookupOrdinaryName, CurScope, nullptr, 1670 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1671 diagnoseTypo(Corrected, 1672 PDiag(Lookup.empty() 1673 ? diag::err_undeclared_var_use_suggest 1674 : diag::err_omp_expected_var_arg_suggest) 1675 << Id.getName()); 1676 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1677 } else { 1678 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1679 : diag::err_omp_expected_var_arg) 1680 << Id.getName(); 1681 return ExprError(); 1682 } 1683 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1684 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1685 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1686 return ExprError(); 1687 } 1688 Lookup.suppressDiagnostics(); 1689 1690 // OpenMP [2.9.2, Syntax, C/C++] 1691 // Variables must be file-scope, namespace-scope, or static block-scope. 1692 if (!VD->hasGlobalStorage()) { 1693 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1694 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1695 bool IsDecl = 1696 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1697 Diag(VD->getLocation(), 1698 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1699 << VD; 1700 return ExprError(); 1701 } 1702 1703 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1704 NamedDecl *ND = CanonicalVD; 1705 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1706 // A threadprivate directive for file-scope variables must appear outside 1707 // any definition or declaration. 1708 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1709 !getCurLexicalContext()->isTranslationUnit()) { 1710 Diag(Id.getLoc(), diag::err_omp_var_scope) 1711 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1712 bool IsDecl = 1713 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1714 Diag(VD->getLocation(), 1715 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1716 << VD; 1717 return ExprError(); 1718 } 1719 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1720 // A threadprivate directive for static class member variables must appear 1721 // in the class definition, in the same scope in which the member 1722 // variables are declared. 1723 if (CanonicalVD->isStaticDataMember() && 1724 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1725 Diag(Id.getLoc(), diag::err_omp_var_scope) 1726 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1727 bool IsDecl = 1728 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1729 Diag(VD->getLocation(), 1730 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1731 << VD; 1732 return ExprError(); 1733 } 1734 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1735 // A threadprivate directive for namespace-scope variables must appear 1736 // outside any definition or declaration other than the namespace 1737 // definition itself. 1738 if (CanonicalVD->getDeclContext()->isNamespace() && 1739 (!getCurLexicalContext()->isFileContext() || 1740 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1741 Diag(Id.getLoc(), diag::err_omp_var_scope) 1742 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1743 bool IsDecl = 1744 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1745 Diag(VD->getLocation(), 1746 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1747 << VD; 1748 return ExprError(); 1749 } 1750 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1751 // A threadprivate directive for static block-scope variables must appear 1752 // in the scope of the variable and not in a nested scope. 1753 if (CanonicalVD->isStaticLocal() && CurScope && 1754 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1755 Diag(Id.getLoc(), diag::err_omp_var_scope) 1756 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1757 bool IsDecl = 1758 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1759 Diag(VD->getLocation(), 1760 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1761 << VD; 1762 return ExprError(); 1763 } 1764 1765 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1766 // A threadprivate directive must lexically precede all references to any 1767 // of the variables in its list. 1768 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1769 Diag(Id.getLoc(), diag::err_omp_var_used) 1770 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1771 return ExprError(); 1772 } 1773 1774 QualType ExprType = VD->getType().getNonReferenceType(); 1775 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1776 SourceLocation(), VD, 1777 /*RefersToEnclosingVariableOrCapture=*/false, 1778 Id.getLoc(), ExprType, VK_LValue); 1779 } 1780 1781 Sema::DeclGroupPtrTy 1782 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1783 ArrayRef<Expr *> VarList) { 1784 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1785 CurContext->addDecl(D); 1786 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1787 } 1788 return nullptr; 1789 } 1790 1791 namespace { 1792 class LocalVarRefChecker final 1793 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1794 Sema &SemaRef; 1795 1796 public: 1797 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1798 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1799 if (VD->hasLocalStorage()) { 1800 SemaRef.Diag(E->getBeginLoc(), 1801 diag::err_omp_local_var_in_threadprivate_init) 1802 << E->getSourceRange(); 1803 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1804 << VD << VD->getSourceRange(); 1805 return true; 1806 } 1807 } 1808 return false; 1809 } 1810 bool VisitStmt(const Stmt *S) { 1811 for (const Stmt *Child : S->children()) { 1812 if (Child && Visit(Child)) 1813 return true; 1814 } 1815 return false; 1816 } 1817 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1818 }; 1819 } // namespace 1820 1821 OMPThreadPrivateDecl * 1822 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1823 SmallVector<Expr *, 8> Vars; 1824 for (Expr *RefExpr : VarList) { 1825 auto *DE = cast<DeclRefExpr>(RefExpr); 1826 auto *VD = cast<VarDecl>(DE->getDecl()); 1827 SourceLocation ILoc = DE->getExprLoc(); 1828 1829 // Mark variable as used. 1830 VD->setReferenced(); 1831 VD->markUsed(Context); 1832 1833 QualType QType = VD->getType(); 1834 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1835 // It will be analyzed later. 1836 Vars.push_back(DE); 1837 continue; 1838 } 1839 1840 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1841 // A threadprivate variable must not have an incomplete type. 1842 if (RequireCompleteType(ILoc, VD->getType(), 1843 diag::err_omp_threadprivate_incomplete_type)) { 1844 continue; 1845 } 1846 1847 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1848 // A threadprivate variable must not have a reference type. 1849 if (VD->getType()->isReferenceType()) { 1850 Diag(ILoc, diag::err_omp_ref_type_arg) 1851 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1852 bool IsDecl = 1853 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1854 Diag(VD->getLocation(), 1855 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1856 << VD; 1857 continue; 1858 } 1859 1860 // Check if this is a TLS variable. If TLS is not being supported, produce 1861 // the corresponding diagnostic. 1862 if ((VD->getTLSKind() != VarDecl::TLS_None && 1863 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1864 getLangOpts().OpenMPUseTLS && 1865 getASTContext().getTargetInfo().isTLSSupported())) || 1866 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1867 !VD->isLocalVarDecl())) { 1868 Diag(ILoc, diag::err_omp_var_thread_local) 1869 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1870 bool IsDecl = 1871 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1872 Diag(VD->getLocation(), 1873 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1874 << VD; 1875 continue; 1876 } 1877 1878 // Check if initial value of threadprivate variable reference variable with 1879 // local storage (it is not supported by runtime). 1880 if (const Expr *Init = VD->getAnyInitializer()) { 1881 LocalVarRefChecker Checker(*this); 1882 if (Checker.Visit(Init)) 1883 continue; 1884 } 1885 1886 Vars.push_back(RefExpr); 1887 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1888 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1889 Context, SourceRange(Loc, Loc))); 1890 if (ASTMutationListener *ML = Context.getASTMutationListener()) 1891 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1892 } 1893 OMPThreadPrivateDecl *D = nullptr; 1894 if (!Vars.empty()) { 1895 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1896 Vars); 1897 D->setAccess(AS_public); 1898 } 1899 return D; 1900 } 1901 1902 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 1903 const ValueDecl *D, 1904 const DSAStackTy::DSAVarData &DVar, 1905 bool IsLoopIterVar = false) { 1906 if (DVar.RefExpr) { 1907 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1908 << getOpenMPClauseName(DVar.CKind); 1909 return; 1910 } 1911 enum { 1912 PDSA_StaticMemberShared, 1913 PDSA_StaticLocalVarShared, 1914 PDSA_LoopIterVarPrivate, 1915 PDSA_LoopIterVarLinear, 1916 PDSA_LoopIterVarLastprivate, 1917 PDSA_ConstVarShared, 1918 PDSA_GlobalVarShared, 1919 PDSA_TaskVarFirstprivate, 1920 PDSA_LocalVarPrivate, 1921 PDSA_Implicit 1922 } Reason = PDSA_Implicit; 1923 bool ReportHint = false; 1924 auto ReportLoc = D->getLocation(); 1925 auto *VD = dyn_cast<VarDecl>(D); 1926 if (IsLoopIterVar) { 1927 if (DVar.CKind == OMPC_private) 1928 Reason = PDSA_LoopIterVarPrivate; 1929 else if (DVar.CKind == OMPC_lastprivate) 1930 Reason = PDSA_LoopIterVarLastprivate; 1931 else 1932 Reason = PDSA_LoopIterVarLinear; 1933 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1934 DVar.CKind == OMPC_firstprivate) { 1935 Reason = PDSA_TaskVarFirstprivate; 1936 ReportLoc = DVar.ImplicitDSALoc; 1937 } else if (VD && VD->isStaticLocal()) 1938 Reason = PDSA_StaticLocalVarShared; 1939 else if (VD && VD->isStaticDataMember()) 1940 Reason = PDSA_StaticMemberShared; 1941 else if (VD && VD->isFileVarDecl()) 1942 Reason = PDSA_GlobalVarShared; 1943 else if (D->getType().isConstant(SemaRef.getASTContext())) 1944 Reason = PDSA_ConstVarShared; 1945 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1946 ReportHint = true; 1947 Reason = PDSA_LocalVarPrivate; 1948 } 1949 if (Reason != PDSA_Implicit) { 1950 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1951 << Reason << ReportHint 1952 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1953 } else if (DVar.ImplicitDSALoc.isValid()) { 1954 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1955 << getOpenMPClauseName(DVar.CKind); 1956 } 1957 } 1958 1959 namespace { 1960 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 1961 DSAStackTy *Stack; 1962 Sema &SemaRef; 1963 bool ErrorFound = false; 1964 CapturedStmt *CS = nullptr; 1965 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 1966 llvm::SmallVector<Expr *, 4> ImplicitMap; 1967 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 1968 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 1969 1970 public: 1971 void VisitDeclRefExpr(DeclRefExpr *E) { 1972 if (E->isTypeDependent() || E->isValueDependent() || 1973 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1974 return; 1975 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1976 VD = VD->getCanonicalDecl(); 1977 // Skip internally declared variables. 1978 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 1979 return; 1980 1981 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 1982 // Check if the variable has explicit DSA set and stop analysis if it so. 1983 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 1984 return; 1985 1986 // Skip internally declared static variables. 1987 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 1988 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 1989 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && 1990 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 1991 return; 1992 1993 SourceLocation ELoc = E->getExprLoc(); 1994 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 1995 // The default(none) clause requires that each variable that is referenced 1996 // in the construct, and does not have a predetermined data-sharing 1997 // attribute, must have its data-sharing attribute explicitly determined 1998 // by being listed in a data-sharing attribute clause. 1999 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2000 isParallelOrTaskRegion(DKind) && 2001 VarsWithInheritedDSA.count(VD) == 0) { 2002 VarsWithInheritedDSA[VD] = E; 2003 return; 2004 } 2005 2006 if (isOpenMPTargetExecutionDirective(DKind) && 2007 !Stack->isLoopControlVariable(VD).first) { 2008 if (!Stack->checkMappableExprComponentListsForDecl( 2009 VD, /*CurrentRegionOnly=*/true, 2010 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2011 StackComponents, 2012 OpenMPClauseKind) { 2013 // Variable is used if it has been marked as an array, array 2014 // section or the variable iself. 2015 return StackComponents.size() == 1 || 2016 std::all_of( 2017 std::next(StackComponents.rbegin()), 2018 StackComponents.rend(), 2019 [](const OMPClauseMappableExprCommon:: 2020 MappableComponent &MC) { 2021 return MC.getAssociatedDeclaration() == 2022 nullptr && 2023 (isa<OMPArraySectionExpr>( 2024 MC.getAssociatedExpression()) || 2025 isa<ArraySubscriptExpr>( 2026 MC.getAssociatedExpression())); 2027 }); 2028 })) { 2029 bool IsFirstprivate = false; 2030 // By default lambdas are captured as firstprivates. 2031 if (const auto *RD = 2032 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2033 IsFirstprivate = RD->isLambda(); 2034 IsFirstprivate = 2035 IsFirstprivate || 2036 (VD->getType().getNonReferenceType()->isScalarType() && 2037 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2038 if (IsFirstprivate) 2039 ImplicitFirstprivate.emplace_back(E); 2040 else 2041 ImplicitMap.emplace_back(E); 2042 return; 2043 } 2044 } 2045 2046 // OpenMP [2.9.3.6, Restrictions, p.2] 2047 // A list item that appears in a reduction clause of the innermost 2048 // enclosing worksharing or parallel construct may not be accessed in an 2049 // explicit task. 2050 DVar = Stack->hasInnermostDSA( 2051 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2052 [](OpenMPDirectiveKind K) { 2053 return isOpenMPParallelDirective(K) || 2054 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2055 }, 2056 /*FromParent=*/true); 2057 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2058 ErrorFound = true; 2059 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2060 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2061 return; 2062 } 2063 2064 // Define implicit data-sharing attributes for task. 2065 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2066 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2067 !Stack->isLoopControlVariable(VD).first) 2068 ImplicitFirstprivate.push_back(E); 2069 } 2070 } 2071 void VisitMemberExpr(MemberExpr *E) { 2072 if (E->isTypeDependent() || E->isValueDependent() || 2073 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2074 return; 2075 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2076 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2077 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2078 if (!FD) 2079 return; 2080 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2081 // Check if the variable has explicit DSA set and stop analysis if it 2082 // so. 2083 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2084 return; 2085 2086 if (isOpenMPTargetExecutionDirective(DKind) && 2087 !Stack->isLoopControlVariable(FD).first && 2088 !Stack->checkMappableExprComponentListsForDecl( 2089 FD, /*CurrentRegionOnly=*/true, 2090 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2091 StackComponents, 2092 OpenMPClauseKind) { 2093 return isa<CXXThisExpr>( 2094 cast<MemberExpr>( 2095 StackComponents.back().getAssociatedExpression()) 2096 ->getBase() 2097 ->IgnoreParens()); 2098 })) { 2099 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2100 // A bit-field cannot appear in a map clause. 2101 // 2102 if (FD->isBitField()) 2103 return; 2104 ImplicitMap.emplace_back(E); 2105 return; 2106 } 2107 2108 SourceLocation ELoc = E->getExprLoc(); 2109 // OpenMP [2.9.3.6, Restrictions, p.2] 2110 // A list item that appears in a reduction clause of the innermost 2111 // enclosing worksharing or parallel construct may not be accessed in 2112 // an explicit task. 2113 DVar = Stack->hasInnermostDSA( 2114 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2115 [](OpenMPDirectiveKind K) { 2116 return isOpenMPParallelDirective(K) || 2117 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2118 }, 2119 /*FromParent=*/true); 2120 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2121 ErrorFound = true; 2122 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2123 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2124 return; 2125 } 2126 2127 // Define implicit data-sharing attributes for task. 2128 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2129 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2130 !Stack->isLoopControlVariable(FD).first) 2131 ImplicitFirstprivate.push_back(E); 2132 return; 2133 } 2134 if (isOpenMPTargetExecutionDirective(DKind)) { 2135 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2136 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2137 /*NoDiagnose=*/true)) 2138 return; 2139 const auto *VD = cast<ValueDecl>( 2140 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2141 if (!Stack->checkMappableExprComponentListsForDecl( 2142 VD, /*CurrentRegionOnly=*/true, 2143 [&CurComponents]( 2144 OMPClauseMappableExprCommon::MappableExprComponentListRef 2145 StackComponents, 2146 OpenMPClauseKind) { 2147 auto CCI = CurComponents.rbegin(); 2148 auto CCE = CurComponents.rend(); 2149 for (const auto &SC : llvm::reverse(StackComponents)) { 2150 // Do both expressions have the same kind? 2151 if (CCI->getAssociatedExpression()->getStmtClass() != 2152 SC.getAssociatedExpression()->getStmtClass()) 2153 if (!(isa<OMPArraySectionExpr>( 2154 SC.getAssociatedExpression()) && 2155 isa<ArraySubscriptExpr>( 2156 CCI->getAssociatedExpression()))) 2157 return false; 2158 2159 const Decl *CCD = CCI->getAssociatedDeclaration(); 2160 const Decl *SCD = SC.getAssociatedDeclaration(); 2161 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2162 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2163 if (SCD != CCD) 2164 return false; 2165 std::advance(CCI, 1); 2166 if (CCI == CCE) 2167 break; 2168 } 2169 return true; 2170 })) { 2171 Visit(E->getBase()); 2172 } 2173 } else { 2174 Visit(E->getBase()); 2175 } 2176 } 2177 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2178 for (OMPClause *C : S->clauses()) { 2179 // Skip analysis of arguments of implicitly defined firstprivate clause 2180 // for task|target directives. 2181 // Skip analysis of arguments of implicitly defined map clause for target 2182 // directives. 2183 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2184 C->isImplicit())) { 2185 for (Stmt *CC : C->children()) { 2186 if (CC) 2187 Visit(CC); 2188 } 2189 } 2190 } 2191 } 2192 void VisitStmt(Stmt *S) { 2193 for (Stmt *C : S->children()) { 2194 if (C && !isa<OMPExecutableDirective>(C)) 2195 Visit(C); 2196 } 2197 } 2198 2199 bool isErrorFound() const { return ErrorFound; } 2200 ArrayRef<Expr *> getImplicitFirstprivate() const { 2201 return ImplicitFirstprivate; 2202 } 2203 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2204 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2205 return VarsWithInheritedDSA; 2206 } 2207 2208 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2209 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 2210 }; 2211 } // namespace 2212 2213 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2214 switch (DKind) { 2215 case OMPD_parallel: 2216 case OMPD_parallel_for: 2217 case OMPD_parallel_for_simd: 2218 case OMPD_parallel_sections: 2219 case OMPD_teams: 2220 case OMPD_teams_distribute: 2221 case OMPD_teams_distribute_simd: { 2222 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2223 QualType KmpInt32PtrTy = 2224 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2225 Sema::CapturedParamNameType Params[] = { 2226 std::make_pair(".global_tid.", KmpInt32PtrTy), 2227 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2228 std::make_pair(StringRef(), QualType()) // __context with shared vars 2229 }; 2230 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2231 Params); 2232 break; 2233 } 2234 case OMPD_target_teams: 2235 case OMPD_target_parallel: 2236 case OMPD_target_parallel_for: 2237 case OMPD_target_parallel_for_simd: 2238 case OMPD_target_teams_distribute: 2239 case OMPD_target_teams_distribute_simd: { 2240 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2241 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2242 QualType KmpInt32PtrTy = 2243 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2244 QualType Args[] = {VoidPtrTy}; 2245 FunctionProtoType::ExtProtoInfo EPI; 2246 EPI.Variadic = true; 2247 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2248 Sema::CapturedParamNameType Params[] = { 2249 std::make_pair(".global_tid.", KmpInt32Ty), 2250 std::make_pair(".part_id.", KmpInt32PtrTy), 2251 std::make_pair(".privates.", VoidPtrTy), 2252 std::make_pair( 2253 ".copy_fn.", 2254 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2255 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2256 std::make_pair(StringRef(), QualType()) // __context with shared vars 2257 }; 2258 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2259 Params); 2260 // Mark this captured region as inlined, because we don't use outlined 2261 // function directly. 2262 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2263 AlwaysInlineAttr::CreateImplicit( 2264 Context, AlwaysInlineAttr::Keyword_forceinline)); 2265 Sema::CapturedParamNameType ParamsTarget[] = { 2266 std::make_pair(StringRef(), QualType()) // __context with shared vars 2267 }; 2268 // Start a captured region for 'target' with no implicit parameters. 2269 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2270 ParamsTarget); 2271 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2272 std::make_pair(".global_tid.", KmpInt32PtrTy), 2273 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2274 std::make_pair(StringRef(), QualType()) // __context with shared vars 2275 }; 2276 // Start a captured region for 'teams' or 'parallel'. Both regions have 2277 // the same implicit parameters. 2278 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2279 ParamsTeamsOrParallel); 2280 break; 2281 } 2282 case OMPD_target: 2283 case OMPD_target_simd: { 2284 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2285 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2286 QualType KmpInt32PtrTy = 2287 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2288 QualType Args[] = {VoidPtrTy}; 2289 FunctionProtoType::ExtProtoInfo EPI; 2290 EPI.Variadic = true; 2291 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2292 Sema::CapturedParamNameType Params[] = { 2293 std::make_pair(".global_tid.", KmpInt32Ty), 2294 std::make_pair(".part_id.", KmpInt32PtrTy), 2295 std::make_pair(".privates.", VoidPtrTy), 2296 std::make_pair( 2297 ".copy_fn.", 2298 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2299 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2300 std::make_pair(StringRef(), QualType()) // __context with shared vars 2301 }; 2302 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2303 Params); 2304 // Mark this captured region as inlined, because we don't use outlined 2305 // function directly. 2306 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2307 AlwaysInlineAttr::CreateImplicit( 2308 Context, AlwaysInlineAttr::Keyword_forceinline)); 2309 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2310 std::make_pair(StringRef(), QualType())); 2311 break; 2312 } 2313 case OMPD_simd: 2314 case OMPD_for: 2315 case OMPD_for_simd: 2316 case OMPD_sections: 2317 case OMPD_section: 2318 case OMPD_single: 2319 case OMPD_master: 2320 case OMPD_critical: 2321 case OMPD_taskgroup: 2322 case OMPD_distribute: 2323 case OMPD_distribute_simd: 2324 case OMPD_ordered: 2325 case OMPD_atomic: 2326 case OMPD_target_data: { 2327 Sema::CapturedParamNameType Params[] = { 2328 std::make_pair(StringRef(), QualType()) // __context with shared vars 2329 }; 2330 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2331 Params); 2332 break; 2333 } 2334 case OMPD_task: { 2335 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2336 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2337 QualType KmpInt32PtrTy = 2338 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2339 QualType Args[] = {VoidPtrTy}; 2340 FunctionProtoType::ExtProtoInfo EPI; 2341 EPI.Variadic = true; 2342 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2343 Sema::CapturedParamNameType Params[] = { 2344 std::make_pair(".global_tid.", KmpInt32Ty), 2345 std::make_pair(".part_id.", KmpInt32PtrTy), 2346 std::make_pair(".privates.", VoidPtrTy), 2347 std::make_pair( 2348 ".copy_fn.", 2349 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2350 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2351 std::make_pair(StringRef(), QualType()) // __context with shared vars 2352 }; 2353 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2354 Params); 2355 // Mark this captured region as inlined, because we don't use outlined 2356 // function directly. 2357 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2358 AlwaysInlineAttr::CreateImplicit( 2359 Context, AlwaysInlineAttr::Keyword_forceinline)); 2360 break; 2361 } 2362 case OMPD_taskloop: 2363 case OMPD_taskloop_simd: { 2364 QualType KmpInt32Ty = 2365 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 2366 .withConst(); 2367 QualType KmpUInt64Ty = 2368 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 2369 .withConst(); 2370 QualType KmpInt64Ty = 2371 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 2372 .withConst(); 2373 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2374 QualType KmpInt32PtrTy = 2375 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2376 QualType Args[] = {VoidPtrTy}; 2377 FunctionProtoType::ExtProtoInfo EPI; 2378 EPI.Variadic = true; 2379 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2380 Sema::CapturedParamNameType Params[] = { 2381 std::make_pair(".global_tid.", KmpInt32Ty), 2382 std::make_pair(".part_id.", KmpInt32PtrTy), 2383 std::make_pair(".privates.", VoidPtrTy), 2384 std::make_pair( 2385 ".copy_fn.", 2386 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2387 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2388 std::make_pair(".lb.", KmpUInt64Ty), 2389 std::make_pair(".ub.", KmpUInt64Ty), 2390 std::make_pair(".st.", KmpInt64Ty), 2391 std::make_pair(".liter.", KmpInt32Ty), 2392 std::make_pair(".reductions.", VoidPtrTy), 2393 std::make_pair(StringRef(), QualType()) // __context with shared vars 2394 }; 2395 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2396 Params); 2397 // Mark this captured region as inlined, because we don't use outlined 2398 // function directly. 2399 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2400 AlwaysInlineAttr::CreateImplicit( 2401 Context, AlwaysInlineAttr::Keyword_forceinline)); 2402 break; 2403 } 2404 case OMPD_distribute_parallel_for_simd: 2405 case OMPD_distribute_parallel_for: { 2406 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2407 QualType KmpInt32PtrTy = 2408 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2409 Sema::CapturedParamNameType Params[] = { 2410 std::make_pair(".global_tid.", KmpInt32PtrTy), 2411 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2412 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2413 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2414 std::make_pair(StringRef(), QualType()) // __context with shared vars 2415 }; 2416 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2417 Params); 2418 break; 2419 } 2420 case OMPD_target_teams_distribute_parallel_for: 2421 case OMPD_target_teams_distribute_parallel_for_simd: { 2422 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2423 QualType KmpInt32PtrTy = 2424 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2425 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2426 2427 QualType Args[] = {VoidPtrTy}; 2428 FunctionProtoType::ExtProtoInfo EPI; 2429 EPI.Variadic = true; 2430 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2431 Sema::CapturedParamNameType Params[] = { 2432 std::make_pair(".global_tid.", KmpInt32Ty), 2433 std::make_pair(".part_id.", KmpInt32PtrTy), 2434 std::make_pair(".privates.", VoidPtrTy), 2435 std::make_pair( 2436 ".copy_fn.", 2437 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2438 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2439 std::make_pair(StringRef(), QualType()) // __context with shared vars 2440 }; 2441 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2442 Params); 2443 // Mark this captured region as inlined, because we don't use outlined 2444 // function directly. 2445 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2446 AlwaysInlineAttr::CreateImplicit( 2447 Context, AlwaysInlineAttr::Keyword_forceinline)); 2448 Sema::CapturedParamNameType ParamsTarget[] = { 2449 std::make_pair(StringRef(), QualType()) // __context with shared vars 2450 }; 2451 // Start a captured region for 'target' with no implicit parameters. 2452 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2453 ParamsTarget); 2454 2455 Sema::CapturedParamNameType ParamsTeams[] = { 2456 std::make_pair(".global_tid.", KmpInt32PtrTy), 2457 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2458 std::make_pair(StringRef(), QualType()) // __context with shared vars 2459 }; 2460 // Start a captured region for 'target' with no implicit parameters. 2461 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2462 ParamsTeams); 2463 2464 Sema::CapturedParamNameType ParamsParallel[] = { 2465 std::make_pair(".global_tid.", KmpInt32PtrTy), 2466 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2467 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2468 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2469 std::make_pair(StringRef(), QualType()) // __context with shared vars 2470 }; 2471 // Start a captured region for 'teams' or 'parallel'. Both regions have 2472 // the same implicit parameters. 2473 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2474 ParamsParallel); 2475 break; 2476 } 2477 2478 case OMPD_teams_distribute_parallel_for: 2479 case OMPD_teams_distribute_parallel_for_simd: { 2480 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2481 QualType KmpInt32PtrTy = 2482 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2483 2484 Sema::CapturedParamNameType ParamsTeams[] = { 2485 std::make_pair(".global_tid.", KmpInt32PtrTy), 2486 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2487 std::make_pair(StringRef(), QualType()) // __context with shared vars 2488 }; 2489 // Start a captured region for 'target' with no implicit parameters. 2490 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2491 ParamsTeams); 2492 2493 Sema::CapturedParamNameType ParamsParallel[] = { 2494 std::make_pair(".global_tid.", KmpInt32PtrTy), 2495 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2496 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2497 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2498 std::make_pair(StringRef(), QualType()) // __context with shared vars 2499 }; 2500 // Start a captured region for 'teams' or 'parallel'. Both regions have 2501 // the same implicit parameters. 2502 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2503 ParamsParallel); 2504 break; 2505 } 2506 case OMPD_target_update: 2507 case OMPD_target_enter_data: 2508 case OMPD_target_exit_data: { 2509 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2510 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2511 QualType KmpInt32PtrTy = 2512 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2513 QualType Args[] = {VoidPtrTy}; 2514 FunctionProtoType::ExtProtoInfo EPI; 2515 EPI.Variadic = true; 2516 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2517 Sema::CapturedParamNameType Params[] = { 2518 std::make_pair(".global_tid.", KmpInt32Ty), 2519 std::make_pair(".part_id.", KmpInt32PtrTy), 2520 std::make_pair(".privates.", VoidPtrTy), 2521 std::make_pair( 2522 ".copy_fn.", 2523 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2524 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2525 std::make_pair(StringRef(), QualType()) // __context with shared vars 2526 }; 2527 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2528 Params); 2529 // Mark this captured region as inlined, because we don't use outlined 2530 // function directly. 2531 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2532 AlwaysInlineAttr::CreateImplicit( 2533 Context, AlwaysInlineAttr::Keyword_forceinline)); 2534 break; 2535 } 2536 case OMPD_threadprivate: 2537 case OMPD_taskyield: 2538 case OMPD_barrier: 2539 case OMPD_taskwait: 2540 case OMPD_cancellation_point: 2541 case OMPD_cancel: 2542 case OMPD_flush: 2543 case OMPD_declare_reduction: 2544 case OMPD_declare_simd: 2545 case OMPD_declare_target: 2546 case OMPD_end_declare_target: 2547 llvm_unreachable("OpenMP Directive is not allowed"); 2548 case OMPD_unknown: 2549 llvm_unreachable("Unknown OpenMP directive"); 2550 } 2551 } 2552 2553 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 2554 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2555 getOpenMPCaptureRegions(CaptureRegions, DKind); 2556 return CaptureRegions.size(); 2557 } 2558 2559 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2560 Expr *CaptureExpr, bool WithInit, 2561 bool AsExpression) { 2562 assert(CaptureExpr); 2563 ASTContext &C = S.getASTContext(); 2564 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 2565 QualType Ty = Init->getType(); 2566 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 2567 if (S.getLangOpts().CPlusPlus) { 2568 Ty = C.getLValueReferenceType(Ty); 2569 } else { 2570 Ty = C.getPointerType(Ty); 2571 ExprResult Res = 2572 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 2573 if (!Res.isUsable()) 2574 return nullptr; 2575 Init = Res.get(); 2576 } 2577 WithInit = true; 2578 } 2579 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 2580 CaptureExpr->getBeginLoc()); 2581 if (!WithInit) 2582 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 2583 S.CurContext->addHiddenDecl(CED); 2584 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 2585 return CED; 2586 } 2587 2588 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2589 bool WithInit) { 2590 OMPCapturedExprDecl *CD; 2591 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 2592 CD = cast<OMPCapturedExprDecl>(VD); 2593 else 2594 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 2595 /*AsExpression=*/false); 2596 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2597 CaptureExpr->getExprLoc()); 2598 } 2599 2600 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 2601 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 2602 if (!Ref) { 2603 OMPCapturedExprDecl *CD = buildCaptureDecl( 2604 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 2605 /*WithInit=*/true, /*AsExpression=*/true); 2606 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2607 CaptureExpr->getExprLoc()); 2608 } 2609 ExprResult Res = Ref; 2610 if (!S.getLangOpts().CPlusPlus && 2611 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 2612 Ref->getType()->isPointerType()) { 2613 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 2614 if (!Res.isUsable()) 2615 return ExprError(); 2616 } 2617 return S.DefaultLvalueConversion(Res.get()); 2618 } 2619 2620 namespace { 2621 // OpenMP directives parsed in this section are represented as a 2622 // CapturedStatement with an associated statement. If a syntax error 2623 // is detected during the parsing of the associated statement, the 2624 // compiler must abort processing and close the CapturedStatement. 2625 // 2626 // Combined directives such as 'target parallel' have more than one 2627 // nested CapturedStatements. This RAII ensures that we unwind out 2628 // of all the nested CapturedStatements when an error is found. 2629 class CaptureRegionUnwinderRAII { 2630 private: 2631 Sema &S; 2632 bool &ErrorFound; 2633 OpenMPDirectiveKind DKind = OMPD_unknown; 2634 2635 public: 2636 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 2637 OpenMPDirectiveKind DKind) 2638 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 2639 ~CaptureRegionUnwinderRAII() { 2640 if (ErrorFound) { 2641 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 2642 while (--ThisCaptureLevel >= 0) 2643 S.ActOnCapturedRegionError(); 2644 } 2645 } 2646 }; 2647 } // namespace 2648 2649 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 2650 ArrayRef<OMPClause *> Clauses) { 2651 bool ErrorFound = false; 2652 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 2653 *this, ErrorFound, DSAStack->getCurrentDirective()); 2654 if (!S.isUsable()) { 2655 ErrorFound = true; 2656 return StmtError(); 2657 } 2658 2659 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2660 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 2661 OMPOrderedClause *OC = nullptr; 2662 OMPScheduleClause *SC = nullptr; 2663 SmallVector<const OMPLinearClause *, 4> LCs; 2664 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 2665 // This is required for proper codegen. 2666 for (OMPClause *Clause : Clauses) { 2667 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2668 Clause->getClauseKind() == OMPC_in_reduction) { 2669 // Capture taskgroup task_reduction descriptors inside the tasking regions 2670 // with the corresponding in_reduction items. 2671 auto *IRC = cast<OMPInReductionClause>(Clause); 2672 for (Expr *E : IRC->taskgroup_descriptors()) 2673 if (E) 2674 MarkDeclarationsReferencedInExpr(E); 2675 } 2676 if (isOpenMPPrivate(Clause->getClauseKind()) || 2677 Clause->getClauseKind() == OMPC_copyprivate || 2678 (getLangOpts().OpenMPUseTLS && 2679 getASTContext().getTargetInfo().isTLSSupported() && 2680 Clause->getClauseKind() == OMPC_copyin)) { 2681 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 2682 // Mark all variables in private list clauses as used in inner region. 2683 for (Stmt *VarRef : Clause->children()) { 2684 if (auto *E = cast_or_null<Expr>(VarRef)) { 2685 MarkDeclarationsReferencedInExpr(E); 2686 } 2687 } 2688 DSAStack->setForceVarCapturing(/*V=*/false); 2689 } else if (CaptureRegions.size() > 1 || 2690 CaptureRegions.back() != OMPD_unknown) { 2691 if (auto *C = OMPClauseWithPreInit::get(Clause)) 2692 PICs.push_back(C); 2693 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 2694 if (Expr *E = C->getPostUpdateExpr()) 2695 MarkDeclarationsReferencedInExpr(E); 2696 } 2697 } 2698 if (Clause->getClauseKind() == OMPC_schedule) 2699 SC = cast<OMPScheduleClause>(Clause); 2700 else if (Clause->getClauseKind() == OMPC_ordered) 2701 OC = cast<OMPOrderedClause>(Clause); 2702 else if (Clause->getClauseKind() == OMPC_linear) 2703 LCs.push_back(cast<OMPLinearClause>(Clause)); 2704 } 2705 // OpenMP, 2.7.1 Loop Construct, Restrictions 2706 // The nonmonotonic modifier cannot be specified if an ordered clause is 2707 // specified. 2708 if (SC && 2709 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 2710 SC->getSecondScheduleModifier() == 2711 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 2712 OC) { 2713 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 2714 ? SC->getFirstScheduleModifierLoc() 2715 : SC->getSecondScheduleModifierLoc(), 2716 diag::err_omp_schedule_nonmonotonic_ordered) 2717 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 2718 ErrorFound = true; 2719 } 2720 if (!LCs.empty() && OC && OC->getNumForLoops()) { 2721 for (const OMPLinearClause *C : LCs) { 2722 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 2723 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 2724 } 2725 ErrorFound = true; 2726 } 2727 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 2728 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 2729 OC->getNumForLoops()) { 2730 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 2731 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 2732 ErrorFound = true; 2733 } 2734 if (ErrorFound) { 2735 return StmtError(); 2736 } 2737 StmtResult SR = S; 2738 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 2739 // Mark all variables in private list clauses as used in inner region. 2740 // Required for proper codegen of combined directives. 2741 // TODO: add processing for other clauses. 2742 if (ThisCaptureRegion != OMPD_unknown) { 2743 for (const clang::OMPClauseWithPreInit *C : PICs) { 2744 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 2745 // Find the particular capture region for the clause if the 2746 // directive is a combined one with multiple capture regions. 2747 // If the directive is not a combined one, the capture region 2748 // associated with the clause is OMPD_unknown and is generated 2749 // only once. 2750 if (CaptureRegion == ThisCaptureRegion || 2751 CaptureRegion == OMPD_unknown) { 2752 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 2753 for (Decl *D : DS->decls()) 2754 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 2755 } 2756 } 2757 } 2758 } 2759 SR = ActOnCapturedRegionEnd(SR.get()); 2760 } 2761 return SR; 2762 } 2763 2764 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 2765 OpenMPDirectiveKind CancelRegion, 2766 SourceLocation StartLoc) { 2767 // CancelRegion is only needed for cancel and cancellation_point. 2768 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 2769 return false; 2770 2771 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 2772 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 2773 return false; 2774 2775 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 2776 << getOpenMPDirectiveName(CancelRegion); 2777 return true; 2778 } 2779 2780 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 2781 OpenMPDirectiveKind CurrentRegion, 2782 const DeclarationNameInfo &CurrentName, 2783 OpenMPDirectiveKind CancelRegion, 2784 SourceLocation StartLoc) { 2785 if (Stack->getCurScope()) { 2786 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 2787 OpenMPDirectiveKind OffendingRegion = ParentRegion; 2788 bool NestingProhibited = false; 2789 bool CloseNesting = true; 2790 bool OrphanSeen = false; 2791 enum { 2792 NoRecommend, 2793 ShouldBeInParallelRegion, 2794 ShouldBeInOrderedRegion, 2795 ShouldBeInTargetRegion, 2796 ShouldBeInTeamsRegion 2797 } Recommend = NoRecommend; 2798 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 2799 // OpenMP [2.16, Nesting of Regions] 2800 // OpenMP constructs may not be nested inside a simd region. 2801 // OpenMP [2.8.1,simd Construct, Restrictions] 2802 // An ordered construct with the simd clause is the only OpenMP 2803 // construct that can appear in the simd region. 2804 // Allowing a SIMD construct nested in another SIMD construct is an 2805 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 2806 // message. 2807 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 2808 ? diag::err_omp_prohibited_region_simd 2809 : diag::warn_omp_nesting_simd); 2810 return CurrentRegion != OMPD_simd; 2811 } 2812 if (ParentRegion == OMPD_atomic) { 2813 // OpenMP [2.16, Nesting of Regions] 2814 // OpenMP constructs may not be nested inside an atomic region. 2815 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2816 return true; 2817 } 2818 if (CurrentRegion == OMPD_section) { 2819 // OpenMP [2.7.2, sections Construct, Restrictions] 2820 // Orphaned section directives are prohibited. That is, the section 2821 // directives must appear within the sections construct and must not be 2822 // encountered elsewhere in the sections region. 2823 if (ParentRegion != OMPD_sections && 2824 ParentRegion != OMPD_parallel_sections) { 2825 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2826 << (ParentRegion != OMPD_unknown) 2827 << getOpenMPDirectiveName(ParentRegion); 2828 return true; 2829 } 2830 return false; 2831 } 2832 // Allow some constructs (except teams) to be orphaned (they could be 2833 // used in functions, called from OpenMP regions with the required 2834 // preconditions). 2835 if (ParentRegion == OMPD_unknown && 2836 !isOpenMPNestingTeamsDirective(CurrentRegion)) 2837 return false; 2838 if (CurrentRegion == OMPD_cancellation_point || 2839 CurrentRegion == OMPD_cancel) { 2840 // OpenMP [2.16, Nesting of Regions] 2841 // A cancellation point construct for which construct-type-clause is 2842 // taskgroup must be nested inside a task construct. A cancellation 2843 // point construct for which construct-type-clause is not taskgroup must 2844 // be closely nested inside an OpenMP construct that matches the type 2845 // specified in construct-type-clause. 2846 // A cancel construct for which construct-type-clause is taskgroup must be 2847 // nested inside a task construct. A cancel construct for which 2848 // construct-type-clause is not taskgroup must be closely nested inside an 2849 // OpenMP construct that matches the type specified in 2850 // construct-type-clause. 2851 NestingProhibited = 2852 !((CancelRegion == OMPD_parallel && 2853 (ParentRegion == OMPD_parallel || 2854 ParentRegion == OMPD_target_parallel)) || 2855 (CancelRegion == OMPD_for && 2856 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2857 ParentRegion == OMPD_target_parallel_for || 2858 ParentRegion == OMPD_distribute_parallel_for || 2859 ParentRegion == OMPD_teams_distribute_parallel_for || 2860 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 2861 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2862 (CancelRegion == OMPD_sections && 2863 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2864 ParentRegion == OMPD_parallel_sections))); 2865 } else if (CurrentRegion == OMPD_master) { 2866 // OpenMP [2.16, Nesting of Regions] 2867 // A master region may not be closely nested inside a worksharing, 2868 // atomic, or explicit task region. 2869 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2870 isOpenMPTaskingDirective(ParentRegion); 2871 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2872 // OpenMP [2.16, Nesting of Regions] 2873 // A critical region may not be nested (closely or otherwise) inside a 2874 // critical region with the same name. Note that this restriction is not 2875 // sufficient to prevent deadlock. 2876 SourceLocation PreviousCriticalLoc; 2877 bool DeadLock = Stack->hasDirective( 2878 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 2879 const DeclarationNameInfo &DNI, 2880 SourceLocation Loc) { 2881 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 2882 PreviousCriticalLoc = Loc; 2883 return true; 2884 } 2885 return false; 2886 }, 2887 false /* skip top directive */); 2888 if (DeadLock) { 2889 SemaRef.Diag(StartLoc, 2890 diag::err_omp_prohibited_region_critical_same_name) 2891 << CurrentName.getName(); 2892 if (PreviousCriticalLoc.isValid()) 2893 SemaRef.Diag(PreviousCriticalLoc, 2894 diag::note_omp_previous_critical_region); 2895 return true; 2896 } 2897 } else if (CurrentRegion == OMPD_barrier) { 2898 // OpenMP [2.16, Nesting of Regions] 2899 // A barrier region may not be closely nested inside a worksharing, 2900 // explicit task, critical, ordered, atomic, or master region. 2901 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2902 isOpenMPTaskingDirective(ParentRegion) || 2903 ParentRegion == OMPD_master || 2904 ParentRegion == OMPD_critical || 2905 ParentRegion == OMPD_ordered; 2906 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2907 !isOpenMPParallelDirective(CurrentRegion) && 2908 !isOpenMPTeamsDirective(CurrentRegion)) { 2909 // OpenMP [2.16, Nesting of Regions] 2910 // A worksharing region may not be closely nested inside a worksharing, 2911 // explicit task, critical, ordered, atomic, or master region. 2912 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2913 isOpenMPTaskingDirective(ParentRegion) || 2914 ParentRegion == OMPD_master || 2915 ParentRegion == OMPD_critical || 2916 ParentRegion == OMPD_ordered; 2917 Recommend = ShouldBeInParallelRegion; 2918 } else if (CurrentRegion == OMPD_ordered) { 2919 // OpenMP [2.16, Nesting of Regions] 2920 // An ordered region may not be closely nested inside a critical, 2921 // atomic, or explicit task region. 2922 // An ordered region must be closely nested inside a loop region (or 2923 // parallel loop region) with an ordered clause. 2924 // OpenMP [2.8.1,simd Construct, Restrictions] 2925 // An ordered construct with the simd clause is the only OpenMP construct 2926 // that can appear in the simd region. 2927 NestingProhibited = ParentRegion == OMPD_critical || 2928 isOpenMPTaskingDirective(ParentRegion) || 2929 !(isOpenMPSimdDirective(ParentRegion) || 2930 Stack->isParentOrderedRegion()); 2931 Recommend = ShouldBeInOrderedRegion; 2932 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 2933 // OpenMP [2.16, Nesting of Regions] 2934 // If specified, a teams construct must be contained within a target 2935 // construct. 2936 NestingProhibited = ParentRegion != OMPD_target; 2937 OrphanSeen = ParentRegion == OMPD_unknown; 2938 Recommend = ShouldBeInTargetRegion; 2939 } 2940 if (!NestingProhibited && 2941 !isOpenMPTargetExecutionDirective(CurrentRegion) && 2942 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 2943 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 2944 // OpenMP [2.16, Nesting of Regions] 2945 // distribute, parallel, parallel sections, parallel workshare, and the 2946 // parallel loop and parallel loop SIMD constructs are the only OpenMP 2947 // constructs that can be closely nested in the teams region. 2948 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 2949 !isOpenMPDistributeDirective(CurrentRegion); 2950 Recommend = ShouldBeInParallelRegion; 2951 } 2952 if (!NestingProhibited && 2953 isOpenMPNestingDistributeDirective(CurrentRegion)) { 2954 // OpenMP 4.5 [2.17 Nesting of Regions] 2955 // The region associated with the distribute construct must be strictly 2956 // nested inside a teams region 2957 NestingProhibited = 2958 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 2959 Recommend = ShouldBeInTeamsRegion; 2960 } 2961 if (!NestingProhibited && 2962 (isOpenMPTargetExecutionDirective(CurrentRegion) || 2963 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 2964 // OpenMP 4.5 [2.17 Nesting of Regions] 2965 // If a target, target update, target data, target enter data, or 2966 // target exit data construct is encountered during execution of a 2967 // target region, the behavior is unspecified. 2968 NestingProhibited = Stack->hasDirective( 2969 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2970 SourceLocation) { 2971 if (isOpenMPTargetExecutionDirective(K)) { 2972 OffendingRegion = K; 2973 return true; 2974 } 2975 return false; 2976 }, 2977 false /* don't skip top directive */); 2978 CloseNesting = false; 2979 } 2980 if (NestingProhibited) { 2981 if (OrphanSeen) { 2982 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 2983 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 2984 } else { 2985 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 2986 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 2987 << Recommend << getOpenMPDirectiveName(CurrentRegion); 2988 } 2989 return true; 2990 } 2991 } 2992 return false; 2993 } 2994 2995 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 2996 ArrayRef<OMPClause *> Clauses, 2997 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 2998 bool ErrorFound = false; 2999 unsigned NamedModifiersNumber = 0; 3000 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3001 OMPD_unknown + 1); 3002 SmallVector<SourceLocation, 4> NameModifierLoc; 3003 for (const OMPClause *C : Clauses) { 3004 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3005 // At most one if clause without a directive-name-modifier can appear on 3006 // the directive. 3007 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3008 if (FoundNameModifiers[CurNM]) { 3009 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3010 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3011 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3012 ErrorFound = true; 3013 } else if (CurNM != OMPD_unknown) { 3014 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3015 ++NamedModifiersNumber; 3016 } 3017 FoundNameModifiers[CurNM] = IC; 3018 if (CurNM == OMPD_unknown) 3019 continue; 3020 // Check if the specified name modifier is allowed for the current 3021 // directive. 3022 // At most one if clause with the particular directive-name-modifier can 3023 // appear on the directive. 3024 bool MatchFound = false; 3025 for (auto NM : AllowedNameModifiers) { 3026 if (CurNM == NM) { 3027 MatchFound = true; 3028 break; 3029 } 3030 } 3031 if (!MatchFound) { 3032 S.Diag(IC->getNameModifierLoc(), 3033 diag::err_omp_wrong_if_directive_name_modifier) 3034 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3035 ErrorFound = true; 3036 } 3037 } 3038 } 3039 // If any if clause on the directive includes a directive-name-modifier then 3040 // all if clauses on the directive must include a directive-name-modifier. 3041 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3042 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3043 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3044 diag::err_omp_no_more_if_clause); 3045 } else { 3046 std::string Values; 3047 std::string Sep(", "); 3048 unsigned AllowedCnt = 0; 3049 unsigned TotalAllowedNum = 3050 AllowedNameModifiers.size() - NamedModifiersNumber; 3051 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3052 ++Cnt) { 3053 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3054 if (!FoundNameModifiers[NM]) { 3055 Values += "'"; 3056 Values += getOpenMPDirectiveName(NM); 3057 Values += "'"; 3058 if (AllowedCnt + 2 == TotalAllowedNum) 3059 Values += " or "; 3060 else if (AllowedCnt + 1 != TotalAllowedNum) 3061 Values += Sep; 3062 ++AllowedCnt; 3063 } 3064 } 3065 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3066 diag::err_omp_unnamed_if_clause) 3067 << (TotalAllowedNum > 1) << Values; 3068 } 3069 for (SourceLocation Loc : NameModifierLoc) { 3070 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3071 } 3072 ErrorFound = true; 3073 } 3074 return ErrorFound; 3075 } 3076 3077 StmtResult Sema::ActOnOpenMPExecutableDirective( 3078 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3079 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3080 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3081 StmtResult Res = StmtError(); 3082 // First check CancelRegion which is then used in checkNestingOfRegions. 3083 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3084 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3085 StartLoc)) 3086 return StmtError(); 3087 3088 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3089 VarsWithInheritedDSAType VarsWithInheritedDSA; 3090 bool ErrorFound = false; 3091 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3092 if (AStmt && !CurContext->isDependentContext()) { 3093 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3094 3095 // Check default data sharing attributes for referenced variables. 3096 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3097 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3098 Stmt *S = AStmt; 3099 while (--ThisCaptureLevel >= 0) 3100 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3101 DSAChecker.Visit(S); 3102 if (DSAChecker.isErrorFound()) 3103 return StmtError(); 3104 // Generate list of implicitly defined firstprivate variables. 3105 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3106 3107 SmallVector<Expr *, 4> ImplicitFirstprivates( 3108 DSAChecker.getImplicitFirstprivate().begin(), 3109 DSAChecker.getImplicitFirstprivate().end()); 3110 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3111 DSAChecker.getImplicitMap().end()); 3112 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3113 for (OMPClause *C : Clauses) { 3114 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3115 for (Expr *E : IRC->taskgroup_descriptors()) 3116 if (E) 3117 ImplicitFirstprivates.emplace_back(E); 3118 } 3119 } 3120 if (!ImplicitFirstprivates.empty()) { 3121 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3122 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3123 SourceLocation())) { 3124 ClausesWithImplicit.push_back(Implicit); 3125 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3126 ImplicitFirstprivates.size(); 3127 } else { 3128 ErrorFound = true; 3129 } 3130 } 3131 if (!ImplicitMaps.empty()) { 3132 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3133 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, 3134 SourceLocation(), SourceLocation(), ImplicitMaps, 3135 SourceLocation(), SourceLocation(), SourceLocation())) { 3136 ClausesWithImplicit.emplace_back(Implicit); 3137 ErrorFound |= 3138 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3139 } else { 3140 ErrorFound = true; 3141 } 3142 } 3143 } 3144 3145 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3146 switch (Kind) { 3147 case OMPD_parallel: 3148 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3149 EndLoc); 3150 AllowedNameModifiers.push_back(OMPD_parallel); 3151 break; 3152 case OMPD_simd: 3153 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3154 VarsWithInheritedDSA); 3155 break; 3156 case OMPD_for: 3157 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3158 VarsWithInheritedDSA); 3159 break; 3160 case OMPD_for_simd: 3161 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3162 EndLoc, VarsWithInheritedDSA); 3163 break; 3164 case OMPD_sections: 3165 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3166 EndLoc); 3167 break; 3168 case OMPD_section: 3169 assert(ClausesWithImplicit.empty() && 3170 "No clauses are allowed for 'omp section' directive"); 3171 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3172 break; 3173 case OMPD_single: 3174 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3175 EndLoc); 3176 break; 3177 case OMPD_master: 3178 assert(ClausesWithImplicit.empty() && 3179 "No clauses are allowed for 'omp master' directive"); 3180 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3181 break; 3182 case OMPD_critical: 3183 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3184 StartLoc, EndLoc); 3185 break; 3186 case OMPD_parallel_for: 3187 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3188 EndLoc, VarsWithInheritedDSA); 3189 AllowedNameModifiers.push_back(OMPD_parallel); 3190 break; 3191 case OMPD_parallel_for_simd: 3192 Res = ActOnOpenMPParallelForSimdDirective( 3193 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3194 AllowedNameModifiers.push_back(OMPD_parallel); 3195 break; 3196 case OMPD_parallel_sections: 3197 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3198 StartLoc, EndLoc); 3199 AllowedNameModifiers.push_back(OMPD_parallel); 3200 break; 3201 case OMPD_task: 3202 Res = 3203 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3204 AllowedNameModifiers.push_back(OMPD_task); 3205 break; 3206 case OMPD_taskyield: 3207 assert(ClausesWithImplicit.empty() && 3208 "No clauses are allowed for 'omp taskyield' directive"); 3209 assert(AStmt == nullptr && 3210 "No associated statement allowed for 'omp taskyield' directive"); 3211 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3212 break; 3213 case OMPD_barrier: 3214 assert(ClausesWithImplicit.empty() && 3215 "No clauses are allowed for 'omp barrier' directive"); 3216 assert(AStmt == nullptr && 3217 "No associated statement allowed for 'omp barrier' directive"); 3218 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3219 break; 3220 case OMPD_taskwait: 3221 assert(ClausesWithImplicit.empty() && 3222 "No clauses are allowed for 'omp taskwait' directive"); 3223 assert(AStmt == nullptr && 3224 "No associated statement allowed for 'omp taskwait' directive"); 3225 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3226 break; 3227 case OMPD_taskgroup: 3228 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 3229 EndLoc); 3230 break; 3231 case OMPD_flush: 3232 assert(AStmt == nullptr && 3233 "No associated statement allowed for 'omp flush' directive"); 3234 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3235 break; 3236 case OMPD_ordered: 3237 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3238 EndLoc); 3239 break; 3240 case OMPD_atomic: 3241 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3242 EndLoc); 3243 break; 3244 case OMPD_teams: 3245 Res = 3246 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3247 break; 3248 case OMPD_target: 3249 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3250 EndLoc); 3251 AllowedNameModifiers.push_back(OMPD_target); 3252 break; 3253 case OMPD_target_parallel: 3254 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3255 StartLoc, EndLoc); 3256 AllowedNameModifiers.push_back(OMPD_target); 3257 AllowedNameModifiers.push_back(OMPD_parallel); 3258 break; 3259 case OMPD_target_parallel_for: 3260 Res = ActOnOpenMPTargetParallelForDirective( 3261 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3262 AllowedNameModifiers.push_back(OMPD_target); 3263 AllowedNameModifiers.push_back(OMPD_parallel); 3264 break; 3265 case OMPD_cancellation_point: 3266 assert(ClausesWithImplicit.empty() && 3267 "No clauses are allowed for 'omp cancellation point' directive"); 3268 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3269 "cancellation point' directive"); 3270 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3271 break; 3272 case OMPD_cancel: 3273 assert(AStmt == nullptr && 3274 "No associated statement allowed for 'omp cancel' directive"); 3275 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3276 CancelRegion); 3277 AllowedNameModifiers.push_back(OMPD_cancel); 3278 break; 3279 case OMPD_target_data: 3280 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3281 EndLoc); 3282 AllowedNameModifiers.push_back(OMPD_target_data); 3283 break; 3284 case OMPD_target_enter_data: 3285 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3286 EndLoc, AStmt); 3287 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3288 break; 3289 case OMPD_target_exit_data: 3290 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3291 EndLoc, AStmt); 3292 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3293 break; 3294 case OMPD_taskloop: 3295 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3296 EndLoc, VarsWithInheritedDSA); 3297 AllowedNameModifiers.push_back(OMPD_taskloop); 3298 break; 3299 case OMPD_taskloop_simd: 3300 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3301 EndLoc, VarsWithInheritedDSA); 3302 AllowedNameModifiers.push_back(OMPD_taskloop); 3303 break; 3304 case OMPD_distribute: 3305 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3306 EndLoc, VarsWithInheritedDSA); 3307 break; 3308 case OMPD_target_update: 3309 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 3310 EndLoc, AStmt); 3311 AllowedNameModifiers.push_back(OMPD_target_update); 3312 break; 3313 case OMPD_distribute_parallel_for: 3314 Res = ActOnOpenMPDistributeParallelForDirective( 3315 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3316 AllowedNameModifiers.push_back(OMPD_parallel); 3317 break; 3318 case OMPD_distribute_parallel_for_simd: 3319 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3320 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3321 AllowedNameModifiers.push_back(OMPD_parallel); 3322 break; 3323 case OMPD_distribute_simd: 3324 Res = ActOnOpenMPDistributeSimdDirective( 3325 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3326 break; 3327 case OMPD_target_parallel_for_simd: 3328 Res = ActOnOpenMPTargetParallelForSimdDirective( 3329 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3330 AllowedNameModifiers.push_back(OMPD_target); 3331 AllowedNameModifiers.push_back(OMPD_parallel); 3332 break; 3333 case OMPD_target_simd: 3334 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3335 EndLoc, VarsWithInheritedDSA); 3336 AllowedNameModifiers.push_back(OMPD_target); 3337 break; 3338 case OMPD_teams_distribute: 3339 Res = ActOnOpenMPTeamsDistributeDirective( 3340 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3341 break; 3342 case OMPD_teams_distribute_simd: 3343 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3344 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3345 break; 3346 case OMPD_teams_distribute_parallel_for_simd: 3347 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3348 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3349 AllowedNameModifiers.push_back(OMPD_parallel); 3350 break; 3351 case OMPD_teams_distribute_parallel_for: 3352 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3353 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3354 AllowedNameModifiers.push_back(OMPD_parallel); 3355 break; 3356 case OMPD_target_teams: 3357 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3358 EndLoc); 3359 AllowedNameModifiers.push_back(OMPD_target); 3360 break; 3361 case OMPD_target_teams_distribute: 3362 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3363 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3364 AllowedNameModifiers.push_back(OMPD_target); 3365 break; 3366 case OMPD_target_teams_distribute_parallel_for: 3367 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3368 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3369 AllowedNameModifiers.push_back(OMPD_target); 3370 AllowedNameModifiers.push_back(OMPD_parallel); 3371 break; 3372 case OMPD_target_teams_distribute_parallel_for_simd: 3373 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3374 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3375 AllowedNameModifiers.push_back(OMPD_target); 3376 AllowedNameModifiers.push_back(OMPD_parallel); 3377 break; 3378 case OMPD_target_teams_distribute_simd: 3379 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3380 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3381 AllowedNameModifiers.push_back(OMPD_target); 3382 break; 3383 case OMPD_declare_target: 3384 case OMPD_end_declare_target: 3385 case OMPD_threadprivate: 3386 case OMPD_declare_reduction: 3387 case OMPD_declare_simd: 3388 llvm_unreachable("OpenMP Directive is not allowed"); 3389 case OMPD_unknown: 3390 llvm_unreachable("Unknown OpenMP directive"); 3391 } 3392 3393 for (const auto &P : VarsWithInheritedDSA) { 3394 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3395 << P.first << P.second->getSourceRange(); 3396 } 3397 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3398 3399 if (!AllowedNameModifiers.empty()) 3400 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3401 ErrorFound; 3402 3403 if (ErrorFound) 3404 return StmtError(); 3405 return Res; 3406 } 3407 3408 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3409 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3410 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3411 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3412 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3413 assert(Aligneds.size() == Alignments.size()); 3414 assert(Linears.size() == LinModifiers.size()); 3415 assert(Linears.size() == Steps.size()); 3416 if (!DG || DG.get().isNull()) 3417 return DeclGroupPtrTy(); 3418 3419 if (!DG.get().isSingleDecl()) { 3420 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3421 return DG; 3422 } 3423 Decl *ADecl = DG.get().getSingleDecl(); 3424 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3425 ADecl = FTD->getTemplatedDecl(); 3426 3427 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3428 if (!FD) { 3429 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3430 return DeclGroupPtrTy(); 3431 } 3432 3433 // OpenMP [2.8.2, declare simd construct, Description] 3434 // The parameter of the simdlen clause must be a constant positive integer 3435 // expression. 3436 ExprResult SL; 3437 if (Simdlen) 3438 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3439 // OpenMP [2.8.2, declare simd construct, Description] 3440 // The special this pointer can be used as if was one of the arguments to the 3441 // function in any of the linear, aligned, or uniform clauses. 3442 // The uniform clause declares one or more arguments to have an invariant 3443 // value for all concurrent invocations of the function in the execution of a 3444 // single SIMD loop. 3445 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 3446 const Expr *UniformedLinearThis = nullptr; 3447 for (const Expr *E : Uniforms) { 3448 E = E->IgnoreParenImpCasts(); 3449 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3450 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3451 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3452 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3453 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3454 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 3455 continue; 3456 } 3457 if (isa<CXXThisExpr>(E)) { 3458 UniformedLinearThis = E; 3459 continue; 3460 } 3461 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3462 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3463 } 3464 // OpenMP [2.8.2, declare simd construct, Description] 3465 // The aligned clause declares that the object to which each list item points 3466 // is aligned to the number of bytes expressed in the optional parameter of 3467 // the aligned clause. 3468 // The special this pointer can be used as if was one of the arguments to the 3469 // function in any of the linear, aligned, or uniform clauses. 3470 // The type of list items appearing in the aligned clause must be array, 3471 // pointer, reference to array, or reference to pointer. 3472 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 3473 const Expr *AlignedThis = nullptr; 3474 for (const Expr *E : Aligneds) { 3475 E = E->IgnoreParenImpCasts(); 3476 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3477 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3478 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3479 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3480 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3481 ->getCanonicalDecl() == CanonPVD) { 3482 // OpenMP [2.8.1, simd construct, Restrictions] 3483 // A list-item cannot appear in more than one aligned clause. 3484 if (AlignedArgs.count(CanonPVD) > 0) { 3485 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3486 << 1 << E->getSourceRange(); 3487 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3488 diag::note_omp_explicit_dsa) 3489 << getOpenMPClauseName(OMPC_aligned); 3490 continue; 3491 } 3492 AlignedArgs[CanonPVD] = E; 3493 QualType QTy = PVD->getType() 3494 .getNonReferenceType() 3495 .getUnqualifiedType() 3496 .getCanonicalType(); 3497 const Type *Ty = QTy.getTypePtrOrNull(); 3498 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3499 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3500 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3501 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3502 } 3503 continue; 3504 } 3505 } 3506 if (isa<CXXThisExpr>(E)) { 3507 if (AlignedThis) { 3508 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3509 << 2 << E->getSourceRange(); 3510 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3511 << getOpenMPClauseName(OMPC_aligned); 3512 } 3513 AlignedThis = E; 3514 continue; 3515 } 3516 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3517 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3518 } 3519 // The optional parameter of the aligned clause, alignment, must be a constant 3520 // positive integer expression. If no optional parameter is specified, 3521 // implementation-defined default alignments for SIMD instructions on the 3522 // target platforms are assumed. 3523 SmallVector<const Expr *, 4> NewAligns; 3524 for (Expr *E : Alignments) { 3525 ExprResult Align; 3526 if (E) 3527 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3528 NewAligns.push_back(Align.get()); 3529 } 3530 // OpenMP [2.8.2, declare simd construct, Description] 3531 // The linear clause declares one or more list items to be private to a SIMD 3532 // lane and to have a linear relationship with respect to the iteration space 3533 // of a loop. 3534 // The special this pointer can be used as if was one of the arguments to the 3535 // function in any of the linear, aligned, or uniform clauses. 3536 // When a linear-step expression is specified in a linear clause it must be 3537 // either a constant integer expression or an integer-typed parameter that is 3538 // specified in a uniform clause on the directive. 3539 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 3540 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3541 auto MI = LinModifiers.begin(); 3542 for (const Expr *E : Linears) { 3543 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3544 ++MI; 3545 E = E->IgnoreParenImpCasts(); 3546 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3547 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3548 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3549 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3550 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3551 ->getCanonicalDecl() == CanonPVD) { 3552 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3553 // A list-item cannot appear in more than one linear clause. 3554 if (LinearArgs.count(CanonPVD) > 0) { 3555 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3556 << getOpenMPClauseName(OMPC_linear) 3557 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3558 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3559 diag::note_omp_explicit_dsa) 3560 << getOpenMPClauseName(OMPC_linear); 3561 continue; 3562 } 3563 // Each argument can appear in at most one uniform or linear clause. 3564 if (UniformedArgs.count(CanonPVD) > 0) { 3565 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3566 << getOpenMPClauseName(OMPC_linear) 3567 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3568 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3569 diag::note_omp_explicit_dsa) 3570 << getOpenMPClauseName(OMPC_uniform); 3571 continue; 3572 } 3573 LinearArgs[CanonPVD] = E; 3574 if (E->isValueDependent() || E->isTypeDependent() || 3575 E->isInstantiationDependent() || 3576 E->containsUnexpandedParameterPack()) 3577 continue; 3578 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 3579 PVD->getOriginalType()); 3580 continue; 3581 } 3582 } 3583 if (isa<CXXThisExpr>(E)) { 3584 if (UniformedLinearThis) { 3585 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3586 << getOpenMPClauseName(OMPC_linear) 3587 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 3588 << E->getSourceRange(); 3589 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 3590 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 3591 : OMPC_linear); 3592 continue; 3593 } 3594 UniformedLinearThis = E; 3595 if (E->isValueDependent() || E->isTypeDependent() || 3596 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 3597 continue; 3598 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 3599 E->getType()); 3600 continue; 3601 } 3602 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3603 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3604 } 3605 Expr *Step = nullptr; 3606 Expr *NewStep = nullptr; 3607 SmallVector<Expr *, 4> NewSteps; 3608 for (Expr *E : Steps) { 3609 // Skip the same step expression, it was checked already. 3610 if (Step == E || !E) { 3611 NewSteps.push_back(E ? NewStep : nullptr); 3612 continue; 3613 } 3614 Step = E; 3615 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 3616 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3617 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3618 if (UniformedArgs.count(CanonPVD) == 0) { 3619 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 3620 << Step->getSourceRange(); 3621 } else if (E->isValueDependent() || E->isTypeDependent() || 3622 E->isInstantiationDependent() || 3623 E->containsUnexpandedParameterPack() || 3624 CanonPVD->getType()->hasIntegerRepresentation()) { 3625 NewSteps.push_back(Step); 3626 } else { 3627 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 3628 << Step->getSourceRange(); 3629 } 3630 continue; 3631 } 3632 NewStep = Step; 3633 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 3634 !Step->isInstantiationDependent() && 3635 !Step->containsUnexpandedParameterPack()) { 3636 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 3637 .get(); 3638 if (NewStep) 3639 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 3640 } 3641 NewSteps.push_back(NewStep); 3642 } 3643 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3644 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 3645 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 3646 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 3647 const_cast<Expr **>(Linears.data()), Linears.size(), 3648 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 3649 NewSteps.data(), NewSteps.size(), SR); 3650 ADecl->addAttr(NewAttr); 3651 return ConvertDeclToDeclGroup(ADecl); 3652 } 3653 3654 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3655 Stmt *AStmt, 3656 SourceLocation StartLoc, 3657 SourceLocation EndLoc) { 3658 if (!AStmt) 3659 return StmtError(); 3660 3661 auto *CS = cast<CapturedStmt>(AStmt); 3662 // 1.2.2 OpenMP Language Terminology 3663 // Structured block - An executable statement with a single entry at the 3664 // top and a single exit at the bottom. 3665 // The point of exit cannot be a branch out of the structured block. 3666 // longjmp() and throw() must not violate the entry/exit criteria. 3667 CS->getCapturedDecl()->setNothrow(); 3668 3669 setFunctionHasBranchProtectedScope(); 3670 3671 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3672 DSAStack->isCancelRegion()); 3673 } 3674 3675 namespace { 3676 /// Helper class for checking canonical form of the OpenMP loops and 3677 /// extracting iteration space of each loop in the loop nest, that will be used 3678 /// for IR generation. 3679 class OpenMPIterationSpaceChecker { 3680 /// Reference to Sema. 3681 Sema &SemaRef; 3682 /// A location for diagnostics (when there is no some better location). 3683 SourceLocation DefaultLoc; 3684 /// A location for diagnostics (when increment is not compatible). 3685 SourceLocation ConditionLoc; 3686 /// A source location for referring to loop init later. 3687 SourceRange InitSrcRange; 3688 /// A source location for referring to condition later. 3689 SourceRange ConditionSrcRange; 3690 /// A source location for referring to increment later. 3691 SourceRange IncrementSrcRange; 3692 /// Loop variable. 3693 ValueDecl *LCDecl = nullptr; 3694 /// Reference to loop variable. 3695 Expr *LCRef = nullptr; 3696 /// Lower bound (initializer for the var). 3697 Expr *LB = nullptr; 3698 /// Upper bound. 3699 Expr *UB = nullptr; 3700 /// Loop step (increment). 3701 Expr *Step = nullptr; 3702 /// This flag is true when condition is one of: 3703 /// Var < UB 3704 /// Var <= UB 3705 /// UB > Var 3706 /// UB >= Var 3707 bool TestIsLessOp = false; 3708 /// This flag is true when condition is strict ( < or > ). 3709 bool TestIsStrictOp = false; 3710 /// This flag is true when step is subtracted on each iteration. 3711 bool SubtractStep = false; 3712 3713 public: 3714 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3715 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3716 /// Check init-expr for canonical loop form and save loop counter 3717 /// variable - #Var and its initialization value - #LB. 3718 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 3719 /// Check test-expr for canonical form, save upper-bound (#UB), flags 3720 /// for less/greater and for strict/non-strict comparison. 3721 bool checkAndSetCond(Expr *S); 3722 /// Check incr-expr for canonical loop form and return true if it 3723 /// does not conform, otherwise save loop step (#Step). 3724 bool checkAndSetInc(Expr *S); 3725 /// Return the loop counter variable. 3726 ValueDecl *getLoopDecl() const { return LCDecl; } 3727 /// Return the reference expression to loop counter variable. 3728 Expr *getLoopDeclRefExpr() const { return LCRef; } 3729 /// Source range of the loop init. 3730 SourceRange getInitSrcRange() const { return InitSrcRange; } 3731 /// Source range of the loop condition. 3732 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 3733 /// Source range of the loop increment. 3734 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 3735 /// True if the step should be subtracted. 3736 bool shouldSubtractStep() const { return SubtractStep; } 3737 /// Build the expression to calculate the number of iterations. 3738 Expr *buildNumIterations( 3739 Scope *S, const bool LimitedType, 3740 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 3741 /// Build the precondition expression for the loops. 3742 Expr * 3743 buildPreCond(Scope *S, Expr *Cond, 3744 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 3745 /// Build reference expression to the counter be used for codegen. 3746 DeclRefExpr * 3747 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 3748 DSAStackTy &DSA) const; 3749 /// Build reference expression to the private counter be used for 3750 /// codegen. 3751 Expr *buildPrivateCounterVar() const; 3752 /// Build initialization of the counter be used for codegen. 3753 Expr *buildCounterInit() const; 3754 /// Build step of the counter be used for codegen. 3755 Expr *buildCounterStep() const; 3756 /// Build loop data with counter value for depend clauses in ordered 3757 /// directives. 3758 Expr * 3759 buildOrderedLoopData(Scope *S, Expr *Counter, 3760 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 3761 SourceLocation Loc, Expr *Inc = nullptr, 3762 OverloadedOperatorKind OOK = OO_Amp); 3763 /// Return true if any expression is dependent. 3764 bool dependent() const; 3765 3766 private: 3767 /// Check the right-hand side of an assignment in the increment 3768 /// expression. 3769 bool checkAndSetIncRHS(Expr *RHS); 3770 /// Helper to set loop counter variable and its initializer. 3771 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3772 /// Helper to set upper bound. 3773 bool setUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3774 SourceLocation SL); 3775 /// Helper to set loop increment. 3776 bool setStep(Expr *NewStep, bool Subtract); 3777 }; 3778 3779 bool OpenMPIterationSpaceChecker::dependent() const { 3780 if (!LCDecl) { 3781 assert(!LB && !UB && !Step); 3782 return false; 3783 } 3784 return LCDecl->getType()->isDependentType() || 3785 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3786 (Step && Step->isValueDependent()); 3787 } 3788 3789 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 3790 Expr *NewLCRefExpr, 3791 Expr *NewLB) { 3792 // State consistency checking to ensure correct usage. 3793 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3794 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3795 if (!NewLCDecl || !NewLB) 3796 return true; 3797 LCDecl = getCanonicalDecl(NewLCDecl); 3798 LCRef = NewLCRefExpr; 3799 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3800 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3801 if ((Ctor->isCopyOrMoveConstructor() || 3802 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3803 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3804 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3805 LB = NewLB; 3806 return false; 3807 } 3808 3809 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, bool LessOp, bool StrictOp, 3810 SourceRange SR, SourceLocation SL) { 3811 // State consistency checking to ensure correct usage. 3812 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3813 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3814 if (!NewUB) 3815 return true; 3816 UB = NewUB; 3817 TestIsLessOp = LessOp; 3818 TestIsStrictOp = StrictOp; 3819 ConditionSrcRange = SR; 3820 ConditionLoc = SL; 3821 return false; 3822 } 3823 3824 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 3825 // State consistency checking to ensure correct usage. 3826 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3827 if (!NewStep) 3828 return true; 3829 if (!NewStep->isValueDependent()) { 3830 // Check that the step is integer expression. 3831 SourceLocation StepLoc = NewStep->getBeginLoc(); 3832 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 3833 StepLoc, getExprAsWritten(NewStep)); 3834 if (Val.isInvalid()) 3835 return true; 3836 NewStep = Val.get(); 3837 3838 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3839 // If test-expr is of form var relational-op b and relational-op is < or 3840 // <= then incr-expr must cause var to increase on each iteration of the 3841 // loop. If test-expr is of form var relational-op b and relational-op is 3842 // > or >= then incr-expr must cause var to decrease on each iteration of 3843 // the loop. 3844 // If test-expr is of form b relational-op var and relational-op is < or 3845 // <= then incr-expr must cause var to decrease on each iteration of the 3846 // loop. If test-expr is of form b relational-op var and relational-op is 3847 // > or >= then incr-expr must cause var to increase on each iteration of 3848 // the loop. 3849 llvm::APSInt Result; 3850 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3851 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3852 bool IsConstNeg = 3853 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3854 bool IsConstPos = 3855 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3856 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3857 if (UB && (IsConstZero || 3858 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3859 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3860 SemaRef.Diag(NewStep->getExprLoc(), 3861 diag::err_omp_loop_incr_not_compatible) 3862 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3863 SemaRef.Diag(ConditionLoc, 3864 diag::note_omp_loop_cond_requres_compatible_incr) 3865 << TestIsLessOp << ConditionSrcRange; 3866 return true; 3867 } 3868 if (TestIsLessOp == Subtract) { 3869 NewStep = 3870 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 3871 .get(); 3872 Subtract = !Subtract; 3873 } 3874 } 3875 3876 Step = NewStep; 3877 SubtractStep = Subtract; 3878 return false; 3879 } 3880 3881 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 3882 // Check init-expr for canonical loop form and save loop counter 3883 // variable - #Var and its initialization value - #LB. 3884 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3885 // var = lb 3886 // integer-type var = lb 3887 // random-access-iterator-type var = lb 3888 // pointer-type var = lb 3889 // 3890 if (!S) { 3891 if (EmitDiags) { 3892 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3893 } 3894 return true; 3895 } 3896 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3897 if (!ExprTemp->cleanupsHaveSideEffects()) 3898 S = ExprTemp->getSubExpr(); 3899 3900 InitSrcRange = S->getSourceRange(); 3901 if (Expr *E = dyn_cast<Expr>(S)) 3902 S = E->IgnoreParens(); 3903 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3904 if (BO->getOpcode() == BO_Assign) { 3905 Expr *LHS = BO->getLHS()->IgnoreParens(); 3906 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3907 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3908 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3909 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3910 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3911 } 3912 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3913 if (ME->isArrow() && 3914 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3915 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3916 } 3917 } 3918 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 3919 if (DS->isSingleDecl()) { 3920 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3921 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3922 // Accept non-canonical init form here but emit ext. warning. 3923 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3924 SemaRef.Diag(S->getBeginLoc(), 3925 diag::ext_omp_loop_not_canonical_init) 3926 << S->getSourceRange(); 3927 return setLCDeclAndLB( 3928 Var, 3929 buildDeclRefExpr(SemaRef, Var, 3930 Var->getType().getNonReferenceType(), 3931 DS->getBeginLoc()), 3932 Var->getInit()); 3933 } 3934 } 3935 } 3936 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3937 if (CE->getOperator() == OO_Equal) { 3938 Expr *LHS = CE->getArg(0); 3939 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3940 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3941 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3942 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3943 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 3944 } 3945 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3946 if (ME->isArrow() && 3947 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3948 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3949 } 3950 } 3951 } 3952 3953 if (dependent() || SemaRef.CurContext->isDependentContext()) 3954 return false; 3955 if (EmitDiags) { 3956 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 3957 << S->getSourceRange(); 3958 } 3959 return true; 3960 } 3961 3962 /// Ignore parenthesizes, implicit casts, copy constructor and return the 3963 /// variable (which may be the loop variable) if possible. 3964 static const ValueDecl *getInitLCDecl(const Expr *E) { 3965 if (!E) 3966 return nullptr; 3967 E = getExprAsWritten(E); 3968 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3969 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3970 if ((Ctor->isCopyOrMoveConstructor() || 3971 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3972 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3973 E = CE->getArg(0)->IgnoreParenImpCasts(); 3974 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 3975 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 3976 return getCanonicalDecl(VD); 3977 } 3978 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 3979 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3980 return getCanonicalDecl(ME->getMemberDecl()); 3981 return nullptr; 3982 } 3983 3984 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 3985 // Check test-expr for canonical form, save upper-bound UB, flags for 3986 // less/greater and for strict/non-strict comparison. 3987 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3988 // var relational-op b 3989 // b relational-op var 3990 // 3991 if (!S) { 3992 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 3993 return true; 3994 } 3995 S = getExprAsWritten(S); 3996 SourceLocation CondLoc = S->getBeginLoc(); 3997 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3998 if (BO->isRelationalOp()) { 3999 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4000 return setUB(BO->getRHS(), 4001 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4002 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4003 BO->getSourceRange(), BO->getOperatorLoc()); 4004 if (getInitLCDecl(BO->getRHS()) == LCDecl) 4005 return setUB(BO->getLHS(), 4006 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4007 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4008 BO->getSourceRange(), BO->getOperatorLoc()); 4009 } 4010 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4011 if (CE->getNumArgs() == 2) { 4012 auto Op = CE->getOperator(); 4013 switch (Op) { 4014 case OO_Greater: 4015 case OO_GreaterEqual: 4016 case OO_Less: 4017 case OO_LessEqual: 4018 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4019 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4020 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4021 CE->getOperatorLoc()); 4022 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 4023 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4024 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4025 CE->getOperatorLoc()); 4026 break; 4027 default: 4028 break; 4029 } 4030 } 4031 } 4032 if (dependent() || SemaRef.CurContext->isDependentContext()) 4033 return false; 4034 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4035 << S->getSourceRange() << LCDecl; 4036 return true; 4037 } 4038 4039 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 4040 // RHS of canonical loop form increment can be: 4041 // var + incr 4042 // incr + var 4043 // var - incr 4044 // 4045 RHS = RHS->IgnoreParenImpCasts(); 4046 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 4047 if (BO->isAdditiveOp()) { 4048 bool IsAdd = BO->getOpcode() == BO_Add; 4049 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4050 return setStep(BO->getRHS(), !IsAdd); 4051 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 4052 return setStep(BO->getLHS(), /*Subtract=*/false); 4053 } 4054 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 4055 bool IsAdd = CE->getOperator() == OO_Plus; 4056 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 4057 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4058 return setStep(CE->getArg(1), !IsAdd); 4059 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 4060 return setStep(CE->getArg(0), /*Subtract=*/false); 4061 } 4062 } 4063 if (dependent() || SemaRef.CurContext->isDependentContext()) 4064 return false; 4065 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4066 << RHS->getSourceRange() << LCDecl; 4067 return true; 4068 } 4069 4070 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 4071 // Check incr-expr for canonical loop form and return true if it 4072 // does not conform. 4073 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4074 // ++var 4075 // var++ 4076 // --var 4077 // var-- 4078 // var += incr 4079 // var -= incr 4080 // var = var + incr 4081 // var = incr + var 4082 // var = var - incr 4083 // 4084 if (!S) { 4085 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 4086 return true; 4087 } 4088 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4089 if (!ExprTemp->cleanupsHaveSideEffects()) 4090 S = ExprTemp->getSubExpr(); 4091 4092 IncrementSrcRange = S->getSourceRange(); 4093 S = S->IgnoreParens(); 4094 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 4095 if (UO->isIncrementDecrementOp() && 4096 getInitLCDecl(UO->getSubExpr()) == LCDecl) 4097 return setStep(SemaRef 4098 .ActOnIntegerConstant(UO->getBeginLoc(), 4099 (UO->isDecrementOp() ? -1 : 1)) 4100 .get(), 4101 /*Subtract=*/false); 4102 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4103 switch (BO->getOpcode()) { 4104 case BO_AddAssign: 4105 case BO_SubAssign: 4106 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4107 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4108 break; 4109 case BO_Assign: 4110 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4111 return checkAndSetIncRHS(BO->getRHS()); 4112 break; 4113 default: 4114 break; 4115 } 4116 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4117 switch (CE->getOperator()) { 4118 case OO_PlusPlus: 4119 case OO_MinusMinus: 4120 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4121 return setStep(SemaRef 4122 .ActOnIntegerConstant( 4123 CE->getBeginLoc(), 4124 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 4125 .get(), 4126 /*Subtract=*/false); 4127 break; 4128 case OO_PlusEqual: 4129 case OO_MinusEqual: 4130 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4131 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4132 break; 4133 case OO_Equal: 4134 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4135 return checkAndSetIncRHS(CE->getArg(1)); 4136 break; 4137 default: 4138 break; 4139 } 4140 } 4141 if (dependent() || SemaRef.CurContext->isDependentContext()) 4142 return false; 4143 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4144 << S->getSourceRange() << LCDecl; 4145 return true; 4146 } 4147 4148 static ExprResult 4149 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4150 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4151 if (SemaRef.CurContext->isDependentContext()) 4152 return ExprResult(Capture); 4153 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4154 return SemaRef.PerformImplicitConversion( 4155 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4156 /*AllowExplicit=*/true); 4157 auto I = Captures.find(Capture); 4158 if (I != Captures.end()) 4159 return buildCapture(SemaRef, Capture, I->second); 4160 DeclRefExpr *Ref = nullptr; 4161 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4162 Captures[Capture] = Ref; 4163 return Res; 4164 } 4165 4166 /// Build the expression to calculate the number of iterations. 4167 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 4168 Scope *S, const bool LimitedType, 4169 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4170 ExprResult Diff; 4171 QualType VarType = LCDecl->getType().getNonReferenceType(); 4172 if (VarType->isIntegerType() || VarType->isPointerType() || 4173 SemaRef.getLangOpts().CPlusPlus) { 4174 // Upper - Lower 4175 Expr *UBExpr = TestIsLessOp ? UB : LB; 4176 Expr *LBExpr = TestIsLessOp ? LB : UB; 4177 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4178 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4179 if (!Upper || !Lower) 4180 return nullptr; 4181 4182 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4183 4184 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4185 // BuildBinOp already emitted error, this one is to point user to upper 4186 // and lower bound, and to tell what is passed to 'operator-'. 4187 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4188 << Upper->getSourceRange() << Lower->getSourceRange(); 4189 return nullptr; 4190 } 4191 } 4192 4193 if (!Diff.isUsable()) 4194 return nullptr; 4195 4196 // Upper - Lower [- 1] 4197 if (TestIsStrictOp) 4198 Diff = SemaRef.BuildBinOp( 4199 S, DefaultLoc, BO_Sub, Diff.get(), 4200 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4201 if (!Diff.isUsable()) 4202 return nullptr; 4203 4204 // Upper - Lower [- 1] + Step 4205 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4206 if (!NewStep.isUsable()) 4207 return nullptr; 4208 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4209 if (!Diff.isUsable()) 4210 return nullptr; 4211 4212 // Parentheses (for dumping/debugging purposes only). 4213 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4214 if (!Diff.isUsable()) 4215 return nullptr; 4216 4217 // (Upper - Lower [- 1] + Step) / Step 4218 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4219 if (!Diff.isUsable()) 4220 return nullptr; 4221 4222 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4223 QualType Type = Diff.get()->getType(); 4224 ASTContext &C = SemaRef.Context; 4225 bool UseVarType = VarType->hasIntegerRepresentation() && 4226 C.getTypeSize(Type) > C.getTypeSize(VarType); 4227 if (!Type->isIntegerType() || UseVarType) { 4228 unsigned NewSize = 4229 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4230 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4231 : Type->hasSignedIntegerRepresentation(); 4232 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4233 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4234 Diff = SemaRef.PerformImplicitConversion( 4235 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4236 if (!Diff.isUsable()) 4237 return nullptr; 4238 } 4239 } 4240 if (LimitedType) { 4241 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4242 if (NewSize != C.getTypeSize(Type)) { 4243 if (NewSize < C.getTypeSize(Type)) { 4244 assert(NewSize == 64 && "incorrect loop var size"); 4245 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4246 << InitSrcRange << ConditionSrcRange; 4247 } 4248 QualType NewType = C.getIntTypeForBitwidth( 4249 NewSize, Type->hasSignedIntegerRepresentation() || 4250 C.getTypeSize(Type) < NewSize); 4251 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4252 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4253 Sema::AA_Converting, true); 4254 if (!Diff.isUsable()) 4255 return nullptr; 4256 } 4257 } 4258 } 4259 4260 return Diff.get(); 4261 } 4262 4263 Expr *OpenMPIterationSpaceChecker::buildPreCond( 4264 Scope *S, Expr *Cond, 4265 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4266 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4267 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4268 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4269 4270 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 4271 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 4272 if (!NewLB.isUsable() || !NewUB.isUsable()) 4273 return nullptr; 4274 4275 ExprResult CondExpr = 4276 SemaRef.BuildBinOp(S, DefaultLoc, 4277 TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 4278 : (TestIsStrictOp ? BO_GT : BO_GE), 4279 NewLB.get(), NewUB.get()); 4280 if (CondExpr.isUsable()) { 4281 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4282 SemaRef.Context.BoolTy)) 4283 CondExpr = SemaRef.PerformImplicitConversion( 4284 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4285 /*AllowExplicit=*/true); 4286 } 4287 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4288 // Otherwise use original loop conditon and evaluate it in runtime. 4289 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4290 } 4291 4292 /// Build reference expression to the counter be used for codegen. 4293 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 4294 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4295 DSAStackTy &DSA) const { 4296 auto *VD = dyn_cast<VarDecl>(LCDecl); 4297 if (!VD) { 4298 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 4299 DeclRefExpr *Ref = buildDeclRefExpr( 4300 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4301 const DSAStackTy::DSAVarData Data = 4302 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4303 // If the loop control decl is explicitly marked as private, do not mark it 4304 // as captured again. 4305 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4306 Captures.insert(std::make_pair(LCRef, Ref)); 4307 return Ref; 4308 } 4309 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 4310 DefaultLoc); 4311 } 4312 4313 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 4314 if (LCDecl && !LCDecl->isInvalidDecl()) { 4315 QualType Type = LCDecl->getType().getNonReferenceType(); 4316 VarDecl *PrivateVar = buildVarDecl( 4317 SemaRef, DefaultLoc, Type, LCDecl->getName(), 4318 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 4319 isa<VarDecl>(LCDecl) 4320 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 4321 : nullptr); 4322 if (PrivateVar->isInvalidDecl()) 4323 return nullptr; 4324 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4325 } 4326 return nullptr; 4327 } 4328 4329 /// Build initialization of the counter to be used for codegen. 4330 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 4331 4332 /// Build step of the counter be used for codegen. 4333 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 4334 4335 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 4336 Scope *S, Expr *Counter, 4337 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 4338 Expr *Inc, OverloadedOperatorKind OOK) { 4339 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 4340 if (!Cnt) 4341 return nullptr; 4342 if (Inc) { 4343 assert((OOK == OO_Plus || OOK == OO_Minus) && 4344 "Expected only + or - operations for depend clauses."); 4345 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 4346 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 4347 if (!Cnt) 4348 return nullptr; 4349 } 4350 ExprResult Diff; 4351 QualType VarType = LCDecl->getType().getNonReferenceType(); 4352 if (VarType->isIntegerType() || VarType->isPointerType() || 4353 SemaRef.getLangOpts().CPlusPlus) { 4354 // Upper - Lower 4355 Expr *Upper = 4356 TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get(); 4357 Expr *Lower = 4358 TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; 4359 if (!Upper || !Lower) 4360 return nullptr; 4361 4362 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4363 4364 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4365 // BuildBinOp already emitted error, this one is to point user to upper 4366 // and lower bound, and to tell what is passed to 'operator-'. 4367 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4368 << Upper->getSourceRange() << Lower->getSourceRange(); 4369 return nullptr; 4370 } 4371 } 4372 4373 if (!Diff.isUsable()) 4374 return nullptr; 4375 4376 // Parentheses (for dumping/debugging purposes only). 4377 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4378 if (!Diff.isUsable()) 4379 return nullptr; 4380 4381 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4382 if (!NewStep.isUsable()) 4383 return nullptr; 4384 // (Upper - Lower) / Step 4385 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4386 if (!Diff.isUsable()) 4387 return nullptr; 4388 4389 return Diff.get(); 4390 } 4391 4392 /// Iteration space of a single for loop. 4393 struct LoopIterationSpace final { 4394 /// Condition of the loop. 4395 Expr *PreCond = nullptr; 4396 /// This expression calculates the number of iterations in the loop. 4397 /// It is always possible to calculate it before starting the loop. 4398 Expr *NumIterations = nullptr; 4399 /// The loop counter variable. 4400 Expr *CounterVar = nullptr; 4401 /// Private loop counter variable. 4402 Expr *PrivateCounterVar = nullptr; 4403 /// This is initializer for the initial value of #CounterVar. 4404 Expr *CounterInit = nullptr; 4405 /// This is step for the #CounterVar used to generate its update: 4406 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4407 Expr *CounterStep = nullptr; 4408 /// Should step be subtracted? 4409 bool Subtract = false; 4410 /// Source range of the loop init. 4411 SourceRange InitSrcRange; 4412 /// Source range of the loop condition. 4413 SourceRange CondSrcRange; 4414 /// Source range of the loop increment. 4415 SourceRange IncSrcRange; 4416 }; 4417 4418 } // namespace 4419 4420 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4421 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4422 assert(Init && "Expected loop in canonical form."); 4423 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4424 if (AssociatedLoops > 0 && 4425 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4426 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4427 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 4428 if (ValueDecl *D = ISC.getLoopDecl()) { 4429 auto *VD = dyn_cast<VarDecl>(D); 4430 if (!VD) { 4431 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 4432 VD = Private; 4433 } else { 4434 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 4435 /*WithInit=*/false); 4436 VD = cast<VarDecl>(Ref->getDecl()); 4437 } 4438 } 4439 DSAStack->addLoopControlVariable(D, VD); 4440 } 4441 } 4442 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4443 } 4444 } 4445 4446 /// Called on a for stmt to check and extract its iteration space 4447 /// for further processing (such as collapsing). 4448 static bool checkOpenMPIterationSpace( 4449 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4450 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4451 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 4452 Expr *OrderedLoopCountExpr, 4453 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 4454 LoopIterationSpace &ResultIterSpace, 4455 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4456 // OpenMP [2.6, Canonical Loop Form] 4457 // for (init-expr; test-expr; incr-expr) structured-block 4458 auto *For = dyn_cast_or_null<ForStmt>(S); 4459 if (!For) { 4460 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 4461 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4462 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 4463 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4464 if (TotalNestedLoopCount > 1) { 4465 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4466 SemaRef.Diag(DSA.getConstructLoc(), 4467 diag::note_omp_collapse_ordered_expr) 4468 << 2 << CollapseLoopCountExpr->getSourceRange() 4469 << OrderedLoopCountExpr->getSourceRange(); 4470 else if (CollapseLoopCountExpr) 4471 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4472 diag::note_omp_collapse_ordered_expr) 4473 << 0 << CollapseLoopCountExpr->getSourceRange(); 4474 else 4475 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4476 diag::note_omp_collapse_ordered_expr) 4477 << 1 << OrderedLoopCountExpr->getSourceRange(); 4478 } 4479 return true; 4480 } 4481 assert(For->getBody()); 4482 4483 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4484 4485 // Check init. 4486 Stmt *Init = For->getInit(); 4487 if (ISC.checkAndSetInit(Init)) 4488 return true; 4489 4490 bool HasErrors = false; 4491 4492 // Check loop variable's type. 4493 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 4494 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 4495 4496 // OpenMP [2.6, Canonical Loop Form] 4497 // Var is one of the following: 4498 // A variable of signed or unsigned integer type. 4499 // For C++, a variable of a random access iterator type. 4500 // For C, a variable of a pointer type. 4501 QualType VarType = LCDecl->getType().getNonReferenceType(); 4502 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4503 !VarType->isPointerType() && 4504 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4505 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 4506 << SemaRef.getLangOpts().CPlusPlus; 4507 HasErrors = true; 4508 } 4509 4510 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4511 // a Construct 4512 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4513 // parallel for construct is (are) private. 4514 // The loop iteration variable in the associated for-loop of a simd 4515 // construct with just one associated for-loop is linear with a 4516 // constant-linear-step that is the increment of the associated for-loop. 4517 // Exclude loop var from the list of variables with implicitly defined data 4518 // sharing attributes. 4519 VarsWithImplicitDSA.erase(LCDecl); 4520 4521 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4522 // in a Construct, C/C++]. 4523 // The loop iteration variable in the associated for-loop of a simd 4524 // construct with just one associated for-loop may be listed in a linear 4525 // clause with a constant-linear-step that is the increment of the 4526 // associated for-loop. 4527 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4528 // parallel for construct may be listed in a private or lastprivate clause. 4529 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4530 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4531 // declared in the loop and it is predetermined as a private. 4532 OpenMPClauseKind PredeterminedCKind = 4533 isOpenMPSimdDirective(DKind) 4534 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4535 : OMPC_private; 4536 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4537 DVar.CKind != PredeterminedCKind) || 4538 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4539 isOpenMPDistributeDirective(DKind)) && 4540 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4541 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4542 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4543 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 4544 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4545 << getOpenMPClauseName(PredeterminedCKind); 4546 if (DVar.RefExpr == nullptr) 4547 DVar.CKind = PredeterminedCKind; 4548 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4549 HasErrors = true; 4550 } else if (LoopDeclRefExpr != nullptr) { 4551 // Make the loop iteration variable private (for worksharing constructs), 4552 // linear (for simd directives with the only one associated loop) or 4553 // lastprivate (for simd directives with several collapsed or ordered 4554 // loops). 4555 if (DVar.CKind == OMPC_unknown) 4556 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 4557 [](OpenMPDirectiveKind) -> bool { return true; }, 4558 /*FromParent=*/false); 4559 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4560 } 4561 4562 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4563 4564 // Check test-expr. 4565 HasErrors |= ISC.checkAndSetCond(For->getCond()); 4566 4567 // Check incr-expr. 4568 HasErrors |= ISC.checkAndSetInc(For->getInc()); 4569 } 4570 4571 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4572 return HasErrors; 4573 4574 // Build the loop's iteration space representation. 4575 ResultIterSpace.PreCond = 4576 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4577 ResultIterSpace.NumIterations = ISC.buildNumIterations( 4578 DSA.getCurScope(), 4579 (isOpenMPWorksharingDirective(DKind) || 4580 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4581 Captures); 4582 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 4583 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 4584 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 4585 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 4586 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 4587 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 4588 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 4589 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 4590 4591 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4592 ResultIterSpace.NumIterations == nullptr || 4593 ResultIterSpace.CounterVar == nullptr || 4594 ResultIterSpace.PrivateCounterVar == nullptr || 4595 ResultIterSpace.CounterInit == nullptr || 4596 ResultIterSpace.CounterStep == nullptr); 4597 if (!HasErrors && DSA.isOrderedRegion()) { 4598 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 4599 if (CurrentNestedLoopCount < 4600 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 4601 DSA.getOrderedRegionParam().second->setLoopNumIterations( 4602 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 4603 DSA.getOrderedRegionParam().second->setLoopCounter( 4604 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 4605 } 4606 } 4607 for (auto &Pair : DSA.getDoacrossDependClauses()) { 4608 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 4609 // Erroneous case - clause has some problems. 4610 continue; 4611 } 4612 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 4613 Pair.second.size() <= CurrentNestedLoopCount) { 4614 // Erroneous case - clause has some problems. 4615 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 4616 continue; 4617 } 4618 Expr *CntValue; 4619 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 4620 CntValue = ISC.buildOrderedLoopData( 4621 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 4622 Pair.first->getDependencyLoc()); 4623 else 4624 CntValue = ISC.buildOrderedLoopData( 4625 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 4626 Pair.first->getDependencyLoc(), 4627 Pair.second[CurrentNestedLoopCount].first, 4628 Pair.second[CurrentNestedLoopCount].second); 4629 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 4630 } 4631 } 4632 4633 return HasErrors; 4634 } 4635 4636 /// Build 'VarRef = Start. 4637 static ExprResult 4638 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4639 ExprResult Start, 4640 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4641 // Build 'VarRef = Start. 4642 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4643 if (!NewStart.isUsable()) 4644 return ExprError(); 4645 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4646 VarRef.get()->getType())) { 4647 NewStart = SemaRef.PerformImplicitConversion( 4648 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4649 /*AllowExplicit=*/true); 4650 if (!NewStart.isUsable()) 4651 return ExprError(); 4652 } 4653 4654 ExprResult Init = 4655 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4656 return Init; 4657 } 4658 4659 /// Build 'VarRef = Start + Iter * Step'. 4660 static ExprResult buildCounterUpdate( 4661 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4662 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 4663 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 4664 // Add parentheses (for debugging purposes only). 4665 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4666 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4667 !Step.isUsable()) 4668 return ExprError(); 4669 4670 ExprResult NewStep = Step; 4671 if (Captures) 4672 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4673 if (NewStep.isInvalid()) 4674 return ExprError(); 4675 ExprResult Update = 4676 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4677 if (!Update.isUsable()) 4678 return ExprError(); 4679 4680 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4681 // 'VarRef = Start (+|-) Iter * Step'. 4682 ExprResult NewStart = Start; 4683 if (Captures) 4684 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4685 if (NewStart.isInvalid()) 4686 return ExprError(); 4687 4688 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4689 ExprResult SavedUpdate = Update; 4690 ExprResult UpdateVal; 4691 if (VarRef.get()->getType()->isOverloadableType() || 4692 NewStart.get()->getType()->isOverloadableType() || 4693 Update.get()->getType()->isOverloadableType()) { 4694 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4695 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4696 Update = 4697 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4698 if (Update.isUsable()) { 4699 UpdateVal = 4700 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4701 VarRef.get(), SavedUpdate.get()); 4702 if (UpdateVal.isUsable()) { 4703 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4704 UpdateVal.get()); 4705 } 4706 } 4707 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4708 } 4709 4710 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4711 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4712 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4713 NewStart.get(), SavedUpdate.get()); 4714 if (!Update.isUsable()) 4715 return ExprError(); 4716 4717 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4718 VarRef.get()->getType())) { 4719 Update = SemaRef.PerformImplicitConversion( 4720 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4721 if (!Update.isUsable()) 4722 return ExprError(); 4723 } 4724 4725 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4726 } 4727 return Update; 4728 } 4729 4730 /// Convert integer expression \a E to make it have at least \a Bits 4731 /// bits. 4732 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 4733 if (E == nullptr) 4734 return ExprError(); 4735 ASTContext &C = SemaRef.Context; 4736 QualType OldType = E->getType(); 4737 unsigned HasBits = C.getTypeSize(OldType); 4738 if (HasBits >= Bits) 4739 return ExprResult(E); 4740 // OK to convert to signed, because new type has more bits than old. 4741 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4742 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4743 true); 4744 } 4745 4746 /// Check if the given expression \a E is a constant integer that fits 4747 /// into \a Bits bits. 4748 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 4749 if (E == nullptr) 4750 return false; 4751 llvm::APSInt Result; 4752 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4753 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4754 return false; 4755 } 4756 4757 /// Build preinits statement for the given declarations. 4758 static Stmt *buildPreInits(ASTContext &Context, 4759 MutableArrayRef<Decl *> PreInits) { 4760 if (!PreInits.empty()) { 4761 return new (Context) DeclStmt( 4762 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4763 SourceLocation(), SourceLocation()); 4764 } 4765 return nullptr; 4766 } 4767 4768 /// Build preinits statement for the given declarations. 4769 static Stmt * 4770 buildPreInits(ASTContext &Context, 4771 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4772 if (!Captures.empty()) { 4773 SmallVector<Decl *, 16> PreInits; 4774 for (const auto &Pair : Captures) 4775 PreInits.push_back(Pair.second->getDecl()); 4776 return buildPreInits(Context, PreInits); 4777 } 4778 return nullptr; 4779 } 4780 4781 /// Build postupdate expression for the given list of postupdates expressions. 4782 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4783 Expr *PostUpdate = nullptr; 4784 if (!PostUpdates.empty()) { 4785 for (Expr *E : PostUpdates) { 4786 Expr *ConvE = S.BuildCStyleCastExpr( 4787 E->getExprLoc(), 4788 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4789 E->getExprLoc(), E) 4790 .get(); 4791 PostUpdate = PostUpdate 4792 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4793 PostUpdate, ConvE) 4794 .get() 4795 : ConvE; 4796 } 4797 } 4798 return PostUpdate; 4799 } 4800 4801 /// Called on a for stmt to check itself and nested loops (if any). 4802 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4803 /// number of collapsed loops otherwise. 4804 static unsigned 4805 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4806 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4807 DSAStackTy &DSA, 4808 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 4809 OMPLoopDirective::HelperExprs &Built) { 4810 unsigned NestedLoopCount = 1; 4811 if (CollapseLoopCountExpr) { 4812 // Found 'collapse' clause - calculate collapse number. 4813 llvm::APSInt Result; 4814 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4815 NestedLoopCount = Result.getLimitedValue(); 4816 } 4817 unsigned OrderedLoopCount = 1; 4818 if (OrderedLoopCountExpr) { 4819 // Found 'ordered' clause - calculate collapse number. 4820 llvm::APSInt Result; 4821 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4822 if (Result.getLimitedValue() < NestedLoopCount) { 4823 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4824 diag::err_omp_wrong_ordered_loop_count) 4825 << OrderedLoopCountExpr->getSourceRange(); 4826 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4827 diag::note_collapse_loop_count) 4828 << CollapseLoopCountExpr->getSourceRange(); 4829 } 4830 OrderedLoopCount = Result.getLimitedValue(); 4831 } 4832 } 4833 // This is helper routine for loop directives (e.g., 'for', 'simd', 4834 // 'for simd', etc.). 4835 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 4836 SmallVector<LoopIterationSpace, 4> IterSpaces; 4837 IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount)); 4838 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4839 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4840 if (checkOpenMPIterationSpace( 4841 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 4842 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 4843 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 4844 Captures)) 4845 return 0; 4846 // Move on to the next nested for loop, or to the loop body. 4847 // OpenMP [2.8.1, simd construct, Restrictions] 4848 // All loops associated with the construct must be perfectly nested; that 4849 // is, there must be no intervening code nor any OpenMP directive between 4850 // any two loops. 4851 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4852 } 4853 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 4854 if (checkOpenMPIterationSpace( 4855 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 4856 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 4857 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 4858 Captures)) 4859 return 0; 4860 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 4861 // Handle initialization of captured loop iterator variables. 4862 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 4863 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 4864 Captures[DRE] = DRE; 4865 } 4866 } 4867 // Move on to the next nested for loop, or to the loop body. 4868 // OpenMP [2.8.1, simd construct, Restrictions] 4869 // All loops associated with the construct must be perfectly nested; that 4870 // is, there must be no intervening code nor any OpenMP directive between 4871 // any two loops. 4872 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4873 } 4874 4875 Built.clear(/* size */ NestedLoopCount); 4876 4877 if (SemaRef.CurContext->isDependentContext()) 4878 return NestedLoopCount; 4879 4880 // An example of what is generated for the following code: 4881 // 4882 // #pragma omp simd collapse(2) ordered(2) 4883 // for (i = 0; i < NI; ++i) 4884 // for (k = 0; k < NK; ++k) 4885 // for (j = J0; j < NJ; j+=2) { 4886 // <loop body> 4887 // } 4888 // 4889 // We generate the code below. 4890 // Note: the loop body may be outlined in CodeGen. 4891 // Note: some counters may be C++ classes, operator- is used to find number of 4892 // iterations and operator+= to calculate counter value. 4893 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4894 // or i64 is currently supported). 4895 // 4896 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4897 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4898 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4899 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4900 // // similar updates for vars in clauses (e.g. 'linear') 4901 // <loop body (using local i and j)> 4902 // } 4903 // i = NI; // assign final values of counters 4904 // j = NJ; 4905 // 4906 4907 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4908 // the iteration counts of the collapsed for loops. 4909 // Precondition tests if there is at least one iteration (all conditions are 4910 // true). 4911 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4912 Expr *N0 = IterSpaces[0].NumIterations; 4913 ExprResult LastIteration32 = 4914 widenIterationCount(/*Bits=*/32, 4915 SemaRef 4916 .PerformImplicitConversion( 4917 N0->IgnoreImpCasts(), N0->getType(), 4918 Sema::AA_Converting, /*AllowExplicit=*/true) 4919 .get(), 4920 SemaRef); 4921 ExprResult LastIteration64 = widenIterationCount( 4922 /*Bits=*/64, 4923 SemaRef 4924 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 4925 Sema::AA_Converting, 4926 /*AllowExplicit=*/true) 4927 .get(), 4928 SemaRef); 4929 4930 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4931 return NestedLoopCount; 4932 4933 ASTContext &C = SemaRef.Context; 4934 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4935 4936 Scope *CurScope = DSA.getCurScope(); 4937 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4938 if (PreCond.isUsable()) { 4939 PreCond = 4940 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 4941 PreCond.get(), IterSpaces[Cnt].PreCond); 4942 } 4943 Expr *N = IterSpaces[Cnt].NumIterations; 4944 SourceLocation Loc = N->getExprLoc(); 4945 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4946 if (LastIteration32.isUsable()) 4947 LastIteration32 = SemaRef.BuildBinOp( 4948 CurScope, Loc, BO_Mul, LastIteration32.get(), 4949 SemaRef 4950 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4951 Sema::AA_Converting, 4952 /*AllowExplicit=*/true) 4953 .get()); 4954 if (LastIteration64.isUsable()) 4955 LastIteration64 = SemaRef.BuildBinOp( 4956 CurScope, Loc, BO_Mul, LastIteration64.get(), 4957 SemaRef 4958 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4959 Sema::AA_Converting, 4960 /*AllowExplicit=*/true) 4961 .get()); 4962 } 4963 4964 // Choose either the 32-bit or 64-bit version. 4965 ExprResult LastIteration = LastIteration64; 4966 if (LastIteration32.isUsable() && 4967 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4968 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4969 fitsInto( 4970 /*Bits=*/32, 4971 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4972 LastIteration64.get(), SemaRef))) 4973 LastIteration = LastIteration32; 4974 QualType VType = LastIteration.get()->getType(); 4975 QualType RealVType = VType; 4976 QualType StrideVType = VType; 4977 if (isOpenMPTaskLoopDirective(DKind)) { 4978 VType = 4979 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 4980 StrideVType = 4981 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 4982 } 4983 4984 if (!LastIteration.isUsable()) 4985 return 0; 4986 4987 // Save the number of iterations. 4988 ExprResult NumIterations = LastIteration; 4989 { 4990 LastIteration = SemaRef.BuildBinOp( 4991 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 4992 LastIteration.get(), 4993 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4994 if (!LastIteration.isUsable()) 4995 return 0; 4996 } 4997 4998 // Calculate the last iteration number beforehand instead of doing this on 4999 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5000 llvm::APSInt Result; 5001 bool IsConstant = 5002 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5003 ExprResult CalcLastIteration; 5004 if (!IsConstant) { 5005 ExprResult SaveRef = 5006 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5007 LastIteration = SaveRef; 5008 5009 // Prepare SaveRef + 1. 5010 NumIterations = SemaRef.BuildBinOp( 5011 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 5012 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5013 if (!NumIterations.isUsable()) 5014 return 0; 5015 } 5016 5017 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5018 5019 // Build variables passed into runtime, necessary for worksharing directives. 5020 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 5021 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5022 isOpenMPDistributeDirective(DKind)) { 5023 // Lower bound variable, initialized with zero. 5024 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5025 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5026 SemaRef.AddInitializerToDecl(LBDecl, 5027 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5028 /*DirectInit*/ false); 5029 5030 // Upper bound variable, initialized with last iteration number. 5031 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 5032 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 5033 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 5034 /*DirectInit*/ false); 5035 5036 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 5037 // This will be used to implement clause 'lastprivate'. 5038 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 5039 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 5040 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 5041 SemaRef.AddInitializerToDecl(ILDecl, 5042 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5043 /*DirectInit*/ false); 5044 5045 // Stride variable returned by runtime (we initialize it to 1 by default). 5046 VarDecl *STDecl = 5047 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 5048 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 5049 SemaRef.AddInitializerToDecl(STDecl, 5050 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 5051 /*DirectInit*/ false); 5052 5053 // Build expression: UB = min(UB, LastIteration) 5054 // It is necessary for CodeGen of directives with static scheduling. 5055 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 5056 UB.get(), LastIteration.get()); 5057 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5058 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 5059 LastIteration.get(), UB.get()); 5060 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 5061 CondOp.get()); 5062 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 5063 5064 // If we have a combined directive that combines 'distribute', 'for' or 5065 // 'simd' we need to be able to access the bounds of the schedule of the 5066 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 5067 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 5068 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5069 // Lower bound variable, initialized with zero. 5070 VarDecl *CombLBDecl = 5071 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 5072 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 5073 SemaRef.AddInitializerToDecl( 5074 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5075 /*DirectInit*/ false); 5076 5077 // Upper bound variable, initialized with last iteration number. 5078 VarDecl *CombUBDecl = 5079 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 5080 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 5081 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 5082 /*DirectInit*/ false); 5083 5084 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 5085 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 5086 ExprResult CombCondOp = 5087 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 5088 LastIteration.get(), CombUB.get()); 5089 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 5090 CombCondOp.get()); 5091 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); 5092 5093 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 5094 // We expect to have at least 2 more parameters than the 'parallel' 5095 // directive does - the lower and upper bounds of the previous schedule. 5096 assert(CD->getNumParams() >= 4 && 5097 "Unexpected number of parameters in loop combined directive"); 5098 5099 // Set the proper type for the bounds given what we learned from the 5100 // enclosed loops. 5101 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 5102 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 5103 5104 // Previous lower and upper bounds are obtained from the region 5105 // parameters. 5106 PrevLB = 5107 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 5108 PrevUB = 5109 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 5110 } 5111 } 5112 5113 // Build the iteration variable and its initialization before loop. 5114 ExprResult IV; 5115 ExprResult Init, CombInit; 5116 { 5117 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 5118 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 5119 Expr *RHS = 5120 (isOpenMPWorksharingDirective(DKind) || 5121 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5122 ? LB.get() 5123 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5124 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 5125 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 5126 5127 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5128 Expr *CombRHS = 5129 (isOpenMPWorksharingDirective(DKind) || 5130 isOpenMPTaskLoopDirective(DKind) || 5131 isOpenMPDistributeDirective(DKind)) 5132 ? CombLB.get() 5133 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5134 CombInit = 5135 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 5136 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); 5137 } 5138 } 5139 5140 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 5141 SourceLocation CondLoc = AStmt->getBeginLoc(); 5142 ExprResult Cond = 5143 (isOpenMPWorksharingDirective(DKind) || 5144 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5145 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 5146 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5147 NumIterations.get()); 5148 ExprResult CombCond; 5149 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5150 CombCond = 5151 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get()); 5152 } 5153 // Loop increment (IV = IV + 1) 5154 SourceLocation IncLoc = AStmt->getBeginLoc(); 5155 ExprResult Inc = 5156 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 5157 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 5158 if (!Inc.isUsable()) 5159 return 0; 5160 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 5161 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 5162 if (!Inc.isUsable()) 5163 return 0; 5164 5165 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 5166 // Used for directives with static scheduling. 5167 // In combined construct, add combined version that use CombLB and CombUB 5168 // base variables for the update 5169 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 5170 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5171 isOpenMPDistributeDirective(DKind)) { 5172 // LB + ST 5173 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 5174 if (!NextLB.isUsable()) 5175 return 0; 5176 // LB = LB + ST 5177 NextLB = 5178 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 5179 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 5180 if (!NextLB.isUsable()) 5181 return 0; 5182 // UB + ST 5183 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 5184 if (!NextUB.isUsable()) 5185 return 0; 5186 // UB = UB + ST 5187 NextUB = 5188 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 5189 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 5190 if (!NextUB.isUsable()) 5191 return 0; 5192 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5193 CombNextLB = 5194 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 5195 if (!NextLB.isUsable()) 5196 return 0; 5197 // LB = LB + ST 5198 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 5199 CombNextLB.get()); 5200 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); 5201 if (!CombNextLB.isUsable()) 5202 return 0; 5203 // UB + ST 5204 CombNextUB = 5205 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 5206 if (!CombNextUB.isUsable()) 5207 return 0; 5208 // UB = UB + ST 5209 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 5210 CombNextUB.get()); 5211 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); 5212 if (!CombNextUB.isUsable()) 5213 return 0; 5214 } 5215 } 5216 5217 // Create increment expression for distribute loop when combined in a same 5218 // directive with for as IV = IV + ST; ensure upper bound expression based 5219 // on PrevUB instead of NumIterations - used to implement 'for' when found 5220 // in combination with 'distribute', like in 'distribute parallel for' 5221 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 5222 ExprResult DistCond, DistInc, PrevEUB; 5223 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5224 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); 5225 assert(DistCond.isUsable() && "distribute cond expr was not built"); 5226 5227 DistInc = 5228 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 5229 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5230 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 5231 DistInc.get()); 5232 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); 5233 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5234 5235 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 5236 // construct 5237 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 5238 ExprResult IsUBGreater = 5239 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 5240 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5241 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 5242 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 5243 CondOp.get()); 5244 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); 5245 } 5246 5247 // Build updates and final values of the loop counters. 5248 bool HasErrors = false; 5249 Built.Counters.resize(NestedLoopCount); 5250 Built.Inits.resize(NestedLoopCount); 5251 Built.Updates.resize(NestedLoopCount); 5252 Built.Finals.resize(NestedLoopCount); 5253 { 5254 ExprResult Div; 5255 // Go from inner nested loop to outer. 5256 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 5257 LoopIterationSpace &IS = IterSpaces[Cnt]; 5258 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 5259 // Build: Iter = (IV / Div) % IS.NumIters 5260 // where Div is product of previous iterations' IS.NumIters. 5261 ExprResult Iter; 5262 if (Div.isUsable()) { 5263 Iter = 5264 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 5265 } else { 5266 Iter = IV; 5267 assert((Cnt == (int)NestedLoopCount - 1) && 5268 "unusable div expected on first iteration only"); 5269 } 5270 5271 if (Cnt != 0 && Iter.isUsable()) 5272 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 5273 IS.NumIterations); 5274 if (!Iter.isUsable()) { 5275 HasErrors = true; 5276 break; 5277 } 5278 5279 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 5280 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 5281 DeclRefExpr *CounterVar = buildDeclRefExpr( 5282 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 5283 /*RefersToCapture=*/true); 5284 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 5285 IS.CounterInit, Captures); 5286 if (!Init.isUsable()) { 5287 HasErrors = true; 5288 break; 5289 } 5290 ExprResult Update = buildCounterUpdate( 5291 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 5292 IS.CounterStep, IS.Subtract, &Captures); 5293 if (!Update.isUsable()) { 5294 HasErrors = true; 5295 break; 5296 } 5297 5298 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 5299 ExprResult Final = buildCounterUpdate( 5300 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 5301 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 5302 if (!Final.isUsable()) { 5303 HasErrors = true; 5304 break; 5305 } 5306 5307 // Build Div for the next iteration: Div <- Div * IS.NumIters 5308 if (Cnt != 0) { 5309 if (Div.isUnset()) 5310 Div = IS.NumIterations; 5311 else 5312 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 5313 IS.NumIterations); 5314 5315 // Add parentheses (for debugging purposes only). 5316 if (Div.isUsable()) 5317 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 5318 if (!Div.isUsable()) { 5319 HasErrors = true; 5320 break; 5321 } 5322 } 5323 if (!Update.isUsable() || !Final.isUsable()) { 5324 HasErrors = true; 5325 break; 5326 } 5327 // Save results 5328 Built.Counters[Cnt] = IS.CounterVar; 5329 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 5330 Built.Inits[Cnt] = Init.get(); 5331 Built.Updates[Cnt] = Update.get(); 5332 Built.Finals[Cnt] = Final.get(); 5333 } 5334 } 5335 5336 if (HasErrors) 5337 return 0; 5338 5339 // Save results 5340 Built.IterationVarRef = IV.get(); 5341 Built.LastIteration = LastIteration.get(); 5342 Built.NumIterations = NumIterations.get(); 5343 Built.CalcLastIteration = 5344 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 5345 Built.PreCond = PreCond.get(); 5346 Built.PreInits = buildPreInits(C, Captures); 5347 Built.Cond = Cond.get(); 5348 Built.Init = Init.get(); 5349 Built.Inc = Inc.get(); 5350 Built.LB = LB.get(); 5351 Built.UB = UB.get(); 5352 Built.IL = IL.get(); 5353 Built.ST = ST.get(); 5354 Built.EUB = EUB.get(); 5355 Built.NLB = NextLB.get(); 5356 Built.NUB = NextUB.get(); 5357 Built.PrevLB = PrevLB.get(); 5358 Built.PrevUB = PrevUB.get(); 5359 Built.DistInc = DistInc.get(); 5360 Built.PrevEUB = PrevEUB.get(); 5361 Built.DistCombinedFields.LB = CombLB.get(); 5362 Built.DistCombinedFields.UB = CombUB.get(); 5363 Built.DistCombinedFields.EUB = CombEUB.get(); 5364 Built.DistCombinedFields.Init = CombInit.get(); 5365 Built.DistCombinedFields.Cond = CombCond.get(); 5366 Built.DistCombinedFields.NLB = CombNextLB.get(); 5367 Built.DistCombinedFields.NUB = CombNextUB.get(); 5368 5369 return NestedLoopCount; 5370 } 5371 5372 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 5373 auto CollapseClauses = 5374 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 5375 if (CollapseClauses.begin() != CollapseClauses.end()) 5376 return (*CollapseClauses.begin())->getNumForLoops(); 5377 return nullptr; 5378 } 5379 5380 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 5381 auto OrderedClauses = 5382 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 5383 if (OrderedClauses.begin() != OrderedClauses.end()) 5384 return (*OrderedClauses.begin())->getNumForLoops(); 5385 return nullptr; 5386 } 5387 5388 static bool checkSimdlenSafelenSpecified(Sema &S, 5389 const ArrayRef<OMPClause *> Clauses) { 5390 const OMPSafelenClause *Safelen = nullptr; 5391 const OMPSimdlenClause *Simdlen = nullptr; 5392 5393 for (const OMPClause *Clause : Clauses) { 5394 if (Clause->getClauseKind() == OMPC_safelen) 5395 Safelen = cast<OMPSafelenClause>(Clause); 5396 else if (Clause->getClauseKind() == OMPC_simdlen) 5397 Simdlen = cast<OMPSimdlenClause>(Clause); 5398 if (Safelen && Simdlen) 5399 break; 5400 } 5401 5402 if (Simdlen && Safelen) { 5403 llvm::APSInt SimdlenRes, SafelenRes; 5404 const Expr *SimdlenLength = Simdlen->getSimdlen(); 5405 const Expr *SafelenLength = Safelen->getSafelen(); 5406 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 5407 SimdlenLength->isInstantiationDependent() || 5408 SimdlenLength->containsUnexpandedParameterPack()) 5409 return false; 5410 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 5411 SafelenLength->isInstantiationDependent() || 5412 SafelenLength->containsUnexpandedParameterPack()) 5413 return false; 5414 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); 5415 SafelenLength->EvaluateAsInt(SafelenRes, S.Context); 5416 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 5417 // If both simdlen and safelen clauses are specified, the value of the 5418 // simdlen parameter must be less than or equal to the value of the safelen 5419 // parameter. 5420 if (SimdlenRes > SafelenRes) { 5421 S.Diag(SimdlenLength->getExprLoc(), 5422 diag::err_omp_wrong_simdlen_safelen_values) 5423 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 5424 return true; 5425 } 5426 } 5427 return false; 5428 } 5429 5430 StmtResult 5431 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 5432 SourceLocation StartLoc, SourceLocation EndLoc, 5433 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5434 if (!AStmt) 5435 return StmtError(); 5436 5437 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5438 OMPLoopDirective::HelperExprs B; 5439 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5440 // define the nested loops number. 5441 unsigned NestedLoopCount = checkOpenMPLoop( 5442 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5443 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5444 if (NestedLoopCount == 0) 5445 return StmtError(); 5446 5447 assert((CurContext->isDependentContext() || B.builtAll()) && 5448 "omp simd loop exprs were not built"); 5449 5450 if (!CurContext->isDependentContext()) { 5451 // Finalize the clauses that need pre-built expressions for CodeGen. 5452 for (OMPClause *C : Clauses) { 5453 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5454 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5455 B.NumIterations, *this, CurScope, 5456 DSAStack)) 5457 return StmtError(); 5458 } 5459 } 5460 5461 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5462 return StmtError(); 5463 5464 setFunctionHasBranchProtectedScope(); 5465 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5466 Clauses, AStmt, B); 5467 } 5468 5469 StmtResult 5470 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 5471 SourceLocation StartLoc, SourceLocation EndLoc, 5472 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5473 if (!AStmt) 5474 return StmtError(); 5475 5476 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5477 OMPLoopDirective::HelperExprs B; 5478 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5479 // define the nested loops number. 5480 unsigned NestedLoopCount = checkOpenMPLoop( 5481 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5482 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5483 if (NestedLoopCount == 0) 5484 return StmtError(); 5485 5486 assert((CurContext->isDependentContext() || B.builtAll()) && 5487 "omp for loop exprs were not built"); 5488 5489 if (!CurContext->isDependentContext()) { 5490 // Finalize the clauses that need pre-built expressions for CodeGen. 5491 for (OMPClause *C : Clauses) { 5492 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5493 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5494 B.NumIterations, *this, CurScope, 5495 DSAStack)) 5496 return StmtError(); 5497 } 5498 } 5499 5500 setFunctionHasBranchProtectedScope(); 5501 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5502 Clauses, AStmt, B, DSAStack->isCancelRegion()); 5503 } 5504 5505 StmtResult Sema::ActOnOpenMPForSimdDirective( 5506 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5507 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5508 if (!AStmt) 5509 return StmtError(); 5510 5511 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5512 OMPLoopDirective::HelperExprs B; 5513 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5514 // define the nested loops number. 5515 unsigned NestedLoopCount = 5516 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5517 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5518 VarsWithImplicitDSA, B); 5519 if (NestedLoopCount == 0) 5520 return StmtError(); 5521 5522 assert((CurContext->isDependentContext() || B.builtAll()) && 5523 "omp for simd loop exprs were not built"); 5524 5525 if (!CurContext->isDependentContext()) { 5526 // Finalize the clauses that need pre-built expressions for CodeGen. 5527 for (OMPClause *C : Clauses) { 5528 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5529 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5530 B.NumIterations, *this, CurScope, 5531 DSAStack)) 5532 return StmtError(); 5533 } 5534 } 5535 5536 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5537 return StmtError(); 5538 5539 setFunctionHasBranchProtectedScope(); 5540 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5541 Clauses, AStmt, B); 5542 } 5543 5544 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5545 Stmt *AStmt, 5546 SourceLocation StartLoc, 5547 SourceLocation EndLoc) { 5548 if (!AStmt) 5549 return StmtError(); 5550 5551 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5552 auto BaseStmt = AStmt; 5553 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5554 BaseStmt = CS->getCapturedStmt(); 5555 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5556 auto S = C->children(); 5557 if (S.begin() == S.end()) 5558 return StmtError(); 5559 // All associated statements must be '#pragma omp section' except for 5560 // the first one. 5561 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5562 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5563 if (SectionStmt) 5564 Diag(SectionStmt->getBeginLoc(), 5565 diag::err_omp_sections_substmt_not_section); 5566 return StmtError(); 5567 } 5568 cast<OMPSectionDirective>(SectionStmt) 5569 ->setHasCancel(DSAStack->isCancelRegion()); 5570 } 5571 } else { 5572 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 5573 return StmtError(); 5574 } 5575 5576 setFunctionHasBranchProtectedScope(); 5577 5578 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5579 DSAStack->isCancelRegion()); 5580 } 5581 5582 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5583 SourceLocation StartLoc, 5584 SourceLocation EndLoc) { 5585 if (!AStmt) 5586 return StmtError(); 5587 5588 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5589 5590 setFunctionHasBranchProtectedScope(); 5591 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5592 5593 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5594 DSAStack->isCancelRegion()); 5595 } 5596 5597 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5598 Stmt *AStmt, 5599 SourceLocation StartLoc, 5600 SourceLocation EndLoc) { 5601 if (!AStmt) 5602 return StmtError(); 5603 5604 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5605 5606 setFunctionHasBranchProtectedScope(); 5607 5608 // OpenMP [2.7.3, single Construct, Restrictions] 5609 // The copyprivate clause must not be used with the nowait clause. 5610 const OMPClause *Nowait = nullptr; 5611 const OMPClause *Copyprivate = nullptr; 5612 for (const OMPClause *Clause : Clauses) { 5613 if (Clause->getClauseKind() == OMPC_nowait) 5614 Nowait = Clause; 5615 else if (Clause->getClauseKind() == OMPC_copyprivate) 5616 Copyprivate = Clause; 5617 if (Copyprivate && Nowait) { 5618 Diag(Copyprivate->getBeginLoc(), 5619 diag::err_omp_single_copyprivate_with_nowait); 5620 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 5621 return StmtError(); 5622 } 5623 } 5624 5625 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5626 } 5627 5628 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5629 SourceLocation StartLoc, 5630 SourceLocation EndLoc) { 5631 if (!AStmt) 5632 return StmtError(); 5633 5634 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5635 5636 setFunctionHasBranchProtectedScope(); 5637 5638 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5639 } 5640 5641 StmtResult Sema::ActOnOpenMPCriticalDirective( 5642 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5643 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5644 if (!AStmt) 5645 return StmtError(); 5646 5647 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5648 5649 bool ErrorFound = false; 5650 llvm::APSInt Hint; 5651 SourceLocation HintLoc; 5652 bool DependentHint = false; 5653 for (const OMPClause *C : Clauses) { 5654 if (C->getClauseKind() == OMPC_hint) { 5655 if (!DirName.getName()) { 5656 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 5657 ErrorFound = true; 5658 } 5659 Expr *E = cast<OMPHintClause>(C)->getHint(); 5660 if (E->isTypeDependent() || E->isValueDependent() || 5661 E->isInstantiationDependent()) { 5662 DependentHint = true; 5663 } else { 5664 Hint = E->EvaluateKnownConstInt(Context); 5665 HintLoc = C->getBeginLoc(); 5666 } 5667 } 5668 } 5669 if (ErrorFound) 5670 return StmtError(); 5671 const auto Pair = DSAStack->getCriticalWithHint(DirName); 5672 if (Pair.first && DirName.getName() && !DependentHint) { 5673 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 5674 Diag(StartLoc, diag::err_omp_critical_with_hint); 5675 if (HintLoc.isValid()) 5676 Diag(HintLoc, diag::note_omp_critical_hint_here) 5677 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 5678 else 5679 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 5680 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 5681 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 5682 << 1 5683 << C->getHint()->EvaluateKnownConstInt(Context).toString( 5684 /*Radix=*/10, /*Signed=*/false); 5685 } else { 5686 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 5687 } 5688 } 5689 } 5690 5691 setFunctionHasBranchProtectedScope(); 5692 5693 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 5694 Clauses, AStmt); 5695 if (!Pair.first && DirName.getName() && !DependentHint) 5696 DSAStack->addCriticalWithHint(Dir, Hint); 5697 return Dir; 5698 } 5699 5700 StmtResult Sema::ActOnOpenMPParallelForDirective( 5701 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5702 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5703 if (!AStmt) 5704 return StmtError(); 5705 5706 auto *CS = cast<CapturedStmt>(AStmt); 5707 // 1.2.2 OpenMP Language Terminology 5708 // Structured block - An executable statement with a single entry at the 5709 // top and a single exit at the bottom. 5710 // The point of exit cannot be a branch out of the structured block. 5711 // longjmp() and throw() must not violate the entry/exit criteria. 5712 CS->getCapturedDecl()->setNothrow(); 5713 5714 OMPLoopDirective::HelperExprs B; 5715 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5716 // define the nested loops number. 5717 unsigned NestedLoopCount = 5718 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 5719 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5720 VarsWithImplicitDSA, B); 5721 if (NestedLoopCount == 0) 5722 return StmtError(); 5723 5724 assert((CurContext->isDependentContext() || B.builtAll()) && 5725 "omp parallel for loop exprs were not built"); 5726 5727 if (!CurContext->isDependentContext()) { 5728 // Finalize the clauses that need pre-built expressions for CodeGen. 5729 for (OMPClause *C : Clauses) { 5730 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5731 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5732 B.NumIterations, *this, CurScope, 5733 DSAStack)) 5734 return StmtError(); 5735 } 5736 } 5737 5738 setFunctionHasBranchProtectedScope(); 5739 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 5740 NestedLoopCount, Clauses, AStmt, B, 5741 DSAStack->isCancelRegion()); 5742 } 5743 5744 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 5745 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5746 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5747 if (!AStmt) 5748 return StmtError(); 5749 5750 auto *CS = cast<CapturedStmt>(AStmt); 5751 // 1.2.2 OpenMP Language Terminology 5752 // Structured block - An executable statement with a single entry at the 5753 // top and a single exit at the bottom. 5754 // The point of exit cannot be a branch out of the structured block. 5755 // longjmp() and throw() must not violate the entry/exit criteria. 5756 CS->getCapturedDecl()->setNothrow(); 5757 5758 OMPLoopDirective::HelperExprs B; 5759 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5760 // define the nested loops number. 5761 unsigned NestedLoopCount = 5762 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 5763 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5764 VarsWithImplicitDSA, B); 5765 if (NestedLoopCount == 0) 5766 return StmtError(); 5767 5768 if (!CurContext->isDependentContext()) { 5769 // Finalize the clauses that need pre-built expressions for CodeGen. 5770 for (OMPClause *C : Clauses) { 5771 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5772 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5773 B.NumIterations, *this, CurScope, 5774 DSAStack)) 5775 return StmtError(); 5776 } 5777 } 5778 5779 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5780 return StmtError(); 5781 5782 setFunctionHasBranchProtectedScope(); 5783 return OMPParallelForSimdDirective::Create( 5784 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5785 } 5786 5787 StmtResult 5788 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5789 Stmt *AStmt, SourceLocation StartLoc, 5790 SourceLocation EndLoc) { 5791 if (!AStmt) 5792 return StmtError(); 5793 5794 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5795 auto BaseStmt = AStmt; 5796 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5797 BaseStmt = CS->getCapturedStmt(); 5798 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5799 auto S = C->children(); 5800 if (S.begin() == S.end()) 5801 return StmtError(); 5802 // All associated statements must be '#pragma omp section' except for 5803 // the first one. 5804 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5805 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5806 if (SectionStmt) 5807 Diag(SectionStmt->getBeginLoc(), 5808 diag::err_omp_parallel_sections_substmt_not_section); 5809 return StmtError(); 5810 } 5811 cast<OMPSectionDirective>(SectionStmt) 5812 ->setHasCancel(DSAStack->isCancelRegion()); 5813 } 5814 } else { 5815 Diag(AStmt->getBeginLoc(), 5816 diag::err_omp_parallel_sections_not_compound_stmt); 5817 return StmtError(); 5818 } 5819 5820 setFunctionHasBranchProtectedScope(); 5821 5822 return OMPParallelSectionsDirective::Create( 5823 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5824 } 5825 5826 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5827 Stmt *AStmt, SourceLocation StartLoc, 5828 SourceLocation EndLoc) { 5829 if (!AStmt) 5830 return StmtError(); 5831 5832 auto *CS = cast<CapturedStmt>(AStmt); 5833 // 1.2.2 OpenMP Language Terminology 5834 // Structured block - An executable statement with a single entry at the 5835 // top and a single exit at the bottom. 5836 // The point of exit cannot be a branch out of the structured block. 5837 // longjmp() and throw() must not violate the entry/exit criteria. 5838 CS->getCapturedDecl()->setNothrow(); 5839 5840 setFunctionHasBranchProtectedScope(); 5841 5842 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5843 DSAStack->isCancelRegion()); 5844 } 5845 5846 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5847 SourceLocation EndLoc) { 5848 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5849 } 5850 5851 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5852 SourceLocation EndLoc) { 5853 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5854 } 5855 5856 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5857 SourceLocation EndLoc) { 5858 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5859 } 5860 5861 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 5862 Stmt *AStmt, 5863 SourceLocation StartLoc, 5864 SourceLocation EndLoc) { 5865 if (!AStmt) 5866 return StmtError(); 5867 5868 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5869 5870 setFunctionHasBranchProtectedScope(); 5871 5872 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 5873 AStmt, 5874 DSAStack->getTaskgroupReductionRef()); 5875 } 5876 5877 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5878 SourceLocation StartLoc, 5879 SourceLocation EndLoc) { 5880 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5881 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5882 } 5883 5884 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5885 Stmt *AStmt, 5886 SourceLocation StartLoc, 5887 SourceLocation EndLoc) { 5888 const OMPClause *DependFound = nullptr; 5889 const OMPClause *DependSourceClause = nullptr; 5890 const OMPClause *DependSinkClause = nullptr; 5891 bool ErrorFound = false; 5892 const OMPThreadsClause *TC = nullptr; 5893 const OMPSIMDClause *SC = nullptr; 5894 for (const OMPClause *C : Clauses) { 5895 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5896 DependFound = C; 5897 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5898 if (DependSourceClause) { 5899 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5900 << getOpenMPDirectiveName(OMPD_ordered) 5901 << getOpenMPClauseName(OMPC_depend) << 2; 5902 ErrorFound = true; 5903 } else { 5904 DependSourceClause = C; 5905 } 5906 if (DependSinkClause) { 5907 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 5908 << 0; 5909 ErrorFound = true; 5910 } 5911 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5912 if (DependSourceClause) { 5913 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 5914 << 1; 5915 ErrorFound = true; 5916 } 5917 DependSinkClause = C; 5918 } 5919 } else if (C->getClauseKind() == OMPC_threads) { 5920 TC = cast<OMPThreadsClause>(C); 5921 } else if (C->getClauseKind() == OMPC_simd) { 5922 SC = cast<OMPSIMDClause>(C); 5923 } 5924 } 5925 if (!ErrorFound && !SC && 5926 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5927 // OpenMP [2.8.1,simd Construct, Restrictions] 5928 // An ordered construct with the simd clause is the only OpenMP construct 5929 // that can appear in the simd region. 5930 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5931 ErrorFound = true; 5932 } else if (DependFound && (TC || SC)) { 5933 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 5934 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5935 ErrorFound = true; 5936 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 5937 Diag(DependFound->getBeginLoc(), 5938 diag::err_omp_ordered_directive_without_param); 5939 ErrorFound = true; 5940 } else if (TC || Clauses.empty()) { 5941 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 5942 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 5943 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5944 << (TC != nullptr); 5945 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 5946 ErrorFound = true; 5947 } 5948 } 5949 if ((!AStmt && !DependFound) || ErrorFound) 5950 return StmtError(); 5951 5952 if (AStmt) { 5953 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5954 5955 setFunctionHasBranchProtectedScope(); 5956 } 5957 5958 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5959 } 5960 5961 namespace { 5962 /// Helper class for checking expression in 'omp atomic [update]' 5963 /// construct. 5964 class OpenMPAtomicUpdateChecker { 5965 /// Error results for atomic update expressions. 5966 enum ExprAnalysisErrorCode { 5967 /// A statement is not an expression statement. 5968 NotAnExpression, 5969 /// Expression is not builtin binary or unary operation. 5970 NotABinaryOrUnaryExpression, 5971 /// Unary operation is not post-/pre- increment/decrement operation. 5972 NotAnUnaryIncDecExpression, 5973 /// An expression is not of scalar type. 5974 NotAScalarType, 5975 /// A binary operation is not an assignment operation. 5976 NotAnAssignmentOp, 5977 /// RHS part of the binary operation is not a binary expression. 5978 NotABinaryExpression, 5979 /// RHS part is not additive/multiplicative/shift/biwise binary 5980 /// expression. 5981 NotABinaryOperator, 5982 /// RHS binary operation does not have reference to the updated LHS 5983 /// part. 5984 NotAnUpdateExpression, 5985 /// No errors is found. 5986 NoError 5987 }; 5988 /// Reference to Sema. 5989 Sema &SemaRef; 5990 /// A location for note diagnostics (when error is found). 5991 SourceLocation NoteLoc; 5992 /// 'x' lvalue part of the source atomic expression. 5993 Expr *X; 5994 /// 'expr' rvalue part of the source atomic expression. 5995 Expr *E; 5996 /// Helper expression of the form 5997 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5998 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5999 Expr *UpdateExpr; 6000 /// Is 'x' a LHS in a RHS part of full update expression. It is 6001 /// important for non-associative operations. 6002 bool IsXLHSInRHSPart; 6003 BinaryOperatorKind Op; 6004 SourceLocation OpLoc; 6005 /// true if the source expression is a postfix unary operation, false 6006 /// if it is a prefix unary operation. 6007 bool IsPostfixUpdate; 6008 6009 public: 6010 OpenMPAtomicUpdateChecker(Sema &SemaRef) 6011 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 6012 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 6013 /// Check specified statement that it is suitable for 'atomic update' 6014 /// constructs and extract 'x', 'expr' and Operation from the original 6015 /// expression. If DiagId and NoteId == 0, then only check is performed 6016 /// without error notification. 6017 /// \param DiagId Diagnostic which should be emitted if error is found. 6018 /// \param NoteId Diagnostic note for the main error message. 6019 /// \return true if statement is not an update expression, false otherwise. 6020 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 6021 /// Return the 'x' lvalue part of the source atomic expression. 6022 Expr *getX() const { return X; } 6023 /// Return the 'expr' rvalue part of the source atomic expression. 6024 Expr *getExpr() const { return E; } 6025 /// Return the update expression used in calculation of the updated 6026 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6027 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6028 Expr *getUpdateExpr() const { return UpdateExpr; } 6029 /// Return true if 'x' is LHS in RHS part of full update expression, 6030 /// false otherwise. 6031 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 6032 6033 /// true if the source expression is a postfix unary operation, false 6034 /// if it is a prefix unary operation. 6035 bool isPostfixUpdate() const { return IsPostfixUpdate; } 6036 6037 private: 6038 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 6039 unsigned NoteId = 0); 6040 }; 6041 } // namespace 6042 6043 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 6044 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 6045 ExprAnalysisErrorCode ErrorFound = NoError; 6046 SourceLocation ErrorLoc, NoteLoc; 6047 SourceRange ErrorRange, NoteRange; 6048 // Allowed constructs are: 6049 // x = x binop expr; 6050 // x = expr binop x; 6051 if (AtomicBinOp->getOpcode() == BO_Assign) { 6052 X = AtomicBinOp->getLHS(); 6053 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 6054 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 6055 if (AtomicInnerBinOp->isMultiplicativeOp() || 6056 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 6057 AtomicInnerBinOp->isBitwiseOp()) { 6058 Op = AtomicInnerBinOp->getOpcode(); 6059 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 6060 Expr *LHS = AtomicInnerBinOp->getLHS(); 6061 Expr *RHS = AtomicInnerBinOp->getRHS(); 6062 llvm::FoldingSetNodeID XId, LHSId, RHSId; 6063 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 6064 /*Canonical=*/true); 6065 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 6066 /*Canonical=*/true); 6067 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 6068 /*Canonical=*/true); 6069 if (XId == LHSId) { 6070 E = RHS; 6071 IsXLHSInRHSPart = true; 6072 } else if (XId == RHSId) { 6073 E = LHS; 6074 IsXLHSInRHSPart = false; 6075 } else { 6076 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6077 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6078 NoteLoc = X->getExprLoc(); 6079 NoteRange = X->getSourceRange(); 6080 ErrorFound = NotAnUpdateExpression; 6081 } 6082 } else { 6083 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6084 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6085 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 6086 NoteRange = SourceRange(NoteLoc, NoteLoc); 6087 ErrorFound = NotABinaryOperator; 6088 } 6089 } else { 6090 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 6091 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 6092 ErrorFound = NotABinaryExpression; 6093 } 6094 } else { 6095 ErrorLoc = AtomicBinOp->getExprLoc(); 6096 ErrorRange = AtomicBinOp->getSourceRange(); 6097 NoteLoc = AtomicBinOp->getOperatorLoc(); 6098 NoteRange = SourceRange(NoteLoc, NoteLoc); 6099 ErrorFound = NotAnAssignmentOp; 6100 } 6101 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6102 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6103 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6104 return true; 6105 } 6106 if (SemaRef.CurContext->isDependentContext()) 6107 E = X = UpdateExpr = nullptr; 6108 return ErrorFound != NoError; 6109 } 6110 6111 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 6112 unsigned NoteId) { 6113 ExprAnalysisErrorCode ErrorFound = NoError; 6114 SourceLocation ErrorLoc, NoteLoc; 6115 SourceRange ErrorRange, NoteRange; 6116 // Allowed constructs are: 6117 // x++; 6118 // x--; 6119 // ++x; 6120 // --x; 6121 // x binop= expr; 6122 // x = x binop expr; 6123 // x = expr binop x; 6124 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 6125 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 6126 if (AtomicBody->getType()->isScalarType() || 6127 AtomicBody->isInstantiationDependent()) { 6128 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 6129 AtomicBody->IgnoreParenImpCasts())) { 6130 // Check for Compound Assignment Operation 6131 Op = BinaryOperator::getOpForCompoundAssignment( 6132 AtomicCompAssignOp->getOpcode()); 6133 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 6134 E = AtomicCompAssignOp->getRHS(); 6135 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 6136 IsXLHSInRHSPart = true; 6137 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 6138 AtomicBody->IgnoreParenImpCasts())) { 6139 // Check for Binary Operation 6140 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 6141 return true; 6142 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 6143 AtomicBody->IgnoreParenImpCasts())) { 6144 // Check for Unary Operation 6145 if (AtomicUnaryOp->isIncrementDecrementOp()) { 6146 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 6147 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 6148 OpLoc = AtomicUnaryOp->getOperatorLoc(); 6149 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 6150 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 6151 IsXLHSInRHSPart = true; 6152 } else { 6153 ErrorFound = NotAnUnaryIncDecExpression; 6154 ErrorLoc = AtomicUnaryOp->getExprLoc(); 6155 ErrorRange = AtomicUnaryOp->getSourceRange(); 6156 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 6157 NoteRange = SourceRange(NoteLoc, NoteLoc); 6158 } 6159 } else if (!AtomicBody->isInstantiationDependent()) { 6160 ErrorFound = NotABinaryOrUnaryExpression; 6161 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 6162 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 6163 } 6164 } else { 6165 ErrorFound = NotAScalarType; 6166 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 6167 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6168 } 6169 } else { 6170 ErrorFound = NotAnExpression; 6171 NoteLoc = ErrorLoc = S->getBeginLoc(); 6172 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6173 } 6174 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6175 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6176 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6177 return true; 6178 } 6179 if (SemaRef.CurContext->isDependentContext()) 6180 E = X = UpdateExpr = nullptr; 6181 if (ErrorFound == NoError && E && X) { 6182 // Build an update expression of form 'OpaqueValueExpr(x) binop 6183 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 6184 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 6185 auto *OVEX = new (SemaRef.getASTContext()) 6186 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 6187 auto *OVEExpr = new (SemaRef.getASTContext()) 6188 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 6189 ExprResult Update = 6190 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 6191 IsXLHSInRHSPart ? OVEExpr : OVEX); 6192 if (Update.isInvalid()) 6193 return true; 6194 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 6195 Sema::AA_Casting); 6196 if (Update.isInvalid()) 6197 return true; 6198 UpdateExpr = Update.get(); 6199 } 6200 return ErrorFound != NoError; 6201 } 6202 6203 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 6204 Stmt *AStmt, 6205 SourceLocation StartLoc, 6206 SourceLocation EndLoc) { 6207 if (!AStmt) 6208 return StmtError(); 6209 6210 auto *CS = cast<CapturedStmt>(AStmt); 6211 // 1.2.2 OpenMP Language Terminology 6212 // Structured block - An executable statement with a single entry at the 6213 // top and a single exit at the bottom. 6214 // The point of exit cannot be a branch out of the structured block. 6215 // longjmp() and throw() must not violate the entry/exit criteria. 6216 OpenMPClauseKind AtomicKind = OMPC_unknown; 6217 SourceLocation AtomicKindLoc; 6218 for (const OMPClause *C : Clauses) { 6219 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 6220 C->getClauseKind() == OMPC_update || 6221 C->getClauseKind() == OMPC_capture) { 6222 if (AtomicKind != OMPC_unknown) { 6223 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 6224 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 6225 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 6226 << getOpenMPClauseName(AtomicKind); 6227 } else { 6228 AtomicKind = C->getClauseKind(); 6229 AtomicKindLoc = C->getBeginLoc(); 6230 } 6231 } 6232 } 6233 6234 Stmt *Body = CS->getCapturedStmt(); 6235 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 6236 Body = EWC->getSubExpr(); 6237 6238 Expr *X = nullptr; 6239 Expr *V = nullptr; 6240 Expr *E = nullptr; 6241 Expr *UE = nullptr; 6242 bool IsXLHSInRHSPart = false; 6243 bool IsPostfixUpdate = false; 6244 // OpenMP [2.12.6, atomic Construct] 6245 // In the next expressions: 6246 // * x and v (as applicable) are both l-value expressions with scalar type. 6247 // * During the execution of an atomic region, multiple syntactic 6248 // occurrences of x must designate the same storage location. 6249 // * Neither of v and expr (as applicable) may access the storage location 6250 // designated by x. 6251 // * Neither of x and expr (as applicable) may access the storage location 6252 // designated by v. 6253 // * expr is an expression with scalar type. 6254 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 6255 // * binop, binop=, ++, and -- are not overloaded operators. 6256 // * The expression x binop expr must be numerically equivalent to x binop 6257 // (expr). This requirement is satisfied if the operators in expr have 6258 // precedence greater than binop, or by using parentheses around expr or 6259 // subexpressions of expr. 6260 // * The expression expr binop x must be numerically equivalent to (expr) 6261 // binop x. This requirement is satisfied if the operators in expr have 6262 // precedence equal to or greater than binop, or by using parentheses around 6263 // expr or subexpressions of expr. 6264 // * For forms that allow multiple occurrences of x, the number of times 6265 // that x is evaluated is unspecified. 6266 if (AtomicKind == OMPC_read) { 6267 enum { 6268 NotAnExpression, 6269 NotAnAssignmentOp, 6270 NotAScalarType, 6271 NotAnLValue, 6272 NoError 6273 } ErrorFound = NoError; 6274 SourceLocation ErrorLoc, NoteLoc; 6275 SourceRange ErrorRange, NoteRange; 6276 // If clause is read: 6277 // v = x; 6278 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6279 const auto *AtomicBinOp = 6280 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6281 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6282 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6283 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 6284 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6285 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 6286 if (!X->isLValue() || !V->isLValue()) { 6287 const Expr *NotLValueExpr = X->isLValue() ? V : X; 6288 ErrorFound = NotAnLValue; 6289 ErrorLoc = AtomicBinOp->getExprLoc(); 6290 ErrorRange = AtomicBinOp->getSourceRange(); 6291 NoteLoc = NotLValueExpr->getExprLoc(); 6292 NoteRange = NotLValueExpr->getSourceRange(); 6293 } 6294 } else if (!X->isInstantiationDependent() || 6295 !V->isInstantiationDependent()) { 6296 const Expr *NotScalarExpr = 6297 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6298 ? V 6299 : X; 6300 ErrorFound = NotAScalarType; 6301 ErrorLoc = AtomicBinOp->getExprLoc(); 6302 ErrorRange = AtomicBinOp->getSourceRange(); 6303 NoteLoc = NotScalarExpr->getExprLoc(); 6304 NoteRange = NotScalarExpr->getSourceRange(); 6305 } 6306 } else if (!AtomicBody->isInstantiationDependent()) { 6307 ErrorFound = NotAnAssignmentOp; 6308 ErrorLoc = AtomicBody->getExprLoc(); 6309 ErrorRange = AtomicBody->getSourceRange(); 6310 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6311 : AtomicBody->getExprLoc(); 6312 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6313 : AtomicBody->getSourceRange(); 6314 } 6315 } else { 6316 ErrorFound = NotAnExpression; 6317 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6318 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6319 } 6320 if (ErrorFound != NoError) { 6321 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 6322 << ErrorRange; 6323 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6324 << NoteRange; 6325 return StmtError(); 6326 } 6327 if (CurContext->isDependentContext()) 6328 V = X = nullptr; 6329 } else if (AtomicKind == OMPC_write) { 6330 enum { 6331 NotAnExpression, 6332 NotAnAssignmentOp, 6333 NotAScalarType, 6334 NotAnLValue, 6335 NoError 6336 } ErrorFound = NoError; 6337 SourceLocation ErrorLoc, NoteLoc; 6338 SourceRange ErrorRange, NoteRange; 6339 // If clause is write: 6340 // x = expr; 6341 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6342 const auto *AtomicBinOp = 6343 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6344 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6345 X = AtomicBinOp->getLHS(); 6346 E = AtomicBinOp->getRHS(); 6347 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6348 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 6349 if (!X->isLValue()) { 6350 ErrorFound = NotAnLValue; 6351 ErrorLoc = AtomicBinOp->getExprLoc(); 6352 ErrorRange = AtomicBinOp->getSourceRange(); 6353 NoteLoc = X->getExprLoc(); 6354 NoteRange = X->getSourceRange(); 6355 } 6356 } else if (!X->isInstantiationDependent() || 6357 !E->isInstantiationDependent()) { 6358 const Expr *NotScalarExpr = 6359 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6360 ? E 6361 : X; 6362 ErrorFound = NotAScalarType; 6363 ErrorLoc = AtomicBinOp->getExprLoc(); 6364 ErrorRange = AtomicBinOp->getSourceRange(); 6365 NoteLoc = NotScalarExpr->getExprLoc(); 6366 NoteRange = NotScalarExpr->getSourceRange(); 6367 } 6368 } else if (!AtomicBody->isInstantiationDependent()) { 6369 ErrorFound = NotAnAssignmentOp; 6370 ErrorLoc = AtomicBody->getExprLoc(); 6371 ErrorRange = AtomicBody->getSourceRange(); 6372 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6373 : AtomicBody->getExprLoc(); 6374 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6375 : AtomicBody->getSourceRange(); 6376 } 6377 } else { 6378 ErrorFound = NotAnExpression; 6379 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6380 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6381 } 6382 if (ErrorFound != NoError) { 6383 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 6384 << ErrorRange; 6385 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6386 << NoteRange; 6387 return StmtError(); 6388 } 6389 if (CurContext->isDependentContext()) 6390 E = X = nullptr; 6391 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 6392 // If clause is update: 6393 // x++; 6394 // x--; 6395 // ++x; 6396 // --x; 6397 // x binop= expr; 6398 // x = x binop expr; 6399 // x = expr binop x; 6400 OpenMPAtomicUpdateChecker Checker(*this); 6401 if (Checker.checkStatement( 6402 Body, (AtomicKind == OMPC_update) 6403 ? diag::err_omp_atomic_update_not_expression_statement 6404 : diag::err_omp_atomic_not_expression_statement, 6405 diag::note_omp_atomic_update)) 6406 return StmtError(); 6407 if (!CurContext->isDependentContext()) { 6408 E = Checker.getExpr(); 6409 X = Checker.getX(); 6410 UE = Checker.getUpdateExpr(); 6411 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6412 } 6413 } else if (AtomicKind == OMPC_capture) { 6414 enum { 6415 NotAnAssignmentOp, 6416 NotACompoundStatement, 6417 NotTwoSubstatements, 6418 NotASpecificExpression, 6419 NoError 6420 } ErrorFound = NoError; 6421 SourceLocation ErrorLoc, NoteLoc; 6422 SourceRange ErrorRange, NoteRange; 6423 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6424 // If clause is a capture: 6425 // v = x++; 6426 // v = x--; 6427 // v = ++x; 6428 // v = --x; 6429 // v = x binop= expr; 6430 // v = x = x binop expr; 6431 // v = x = expr binop x; 6432 const auto *AtomicBinOp = 6433 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6434 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6435 V = AtomicBinOp->getLHS(); 6436 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6437 OpenMPAtomicUpdateChecker Checker(*this); 6438 if (Checker.checkStatement( 6439 Body, diag::err_omp_atomic_capture_not_expression_statement, 6440 diag::note_omp_atomic_update)) 6441 return StmtError(); 6442 E = Checker.getExpr(); 6443 X = Checker.getX(); 6444 UE = Checker.getUpdateExpr(); 6445 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6446 IsPostfixUpdate = Checker.isPostfixUpdate(); 6447 } else if (!AtomicBody->isInstantiationDependent()) { 6448 ErrorLoc = AtomicBody->getExprLoc(); 6449 ErrorRange = AtomicBody->getSourceRange(); 6450 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6451 : AtomicBody->getExprLoc(); 6452 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6453 : AtomicBody->getSourceRange(); 6454 ErrorFound = NotAnAssignmentOp; 6455 } 6456 if (ErrorFound != NoError) { 6457 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 6458 << ErrorRange; 6459 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6460 return StmtError(); 6461 } 6462 if (CurContext->isDependentContext()) 6463 UE = V = E = X = nullptr; 6464 } else { 6465 // If clause is a capture: 6466 // { v = x; x = expr; } 6467 // { v = x; x++; } 6468 // { v = x; x--; } 6469 // { v = x; ++x; } 6470 // { v = x; --x; } 6471 // { v = x; x binop= expr; } 6472 // { v = x; x = x binop expr; } 6473 // { v = x; x = expr binop x; } 6474 // { x++; v = x; } 6475 // { x--; v = x; } 6476 // { ++x; v = x; } 6477 // { --x; v = x; } 6478 // { x binop= expr; v = x; } 6479 // { x = x binop expr; v = x; } 6480 // { x = expr binop x; v = x; } 6481 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 6482 // Check that this is { expr1; expr2; } 6483 if (CS->size() == 2) { 6484 Stmt *First = CS->body_front(); 6485 Stmt *Second = CS->body_back(); 6486 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6487 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6488 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6489 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6490 // Need to find what subexpression is 'v' and what is 'x'. 6491 OpenMPAtomicUpdateChecker Checker(*this); 6492 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6493 BinaryOperator *BinOp = nullptr; 6494 if (IsUpdateExprFound) { 6495 BinOp = dyn_cast<BinaryOperator>(First); 6496 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6497 } 6498 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6499 // { v = x; x++; } 6500 // { v = x; x--; } 6501 // { v = x; ++x; } 6502 // { v = x; --x; } 6503 // { v = x; x binop= expr; } 6504 // { v = x; x = x binop expr; } 6505 // { v = x; x = expr binop x; } 6506 // Check that the first expression has form v = x. 6507 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6508 llvm::FoldingSetNodeID XId, PossibleXId; 6509 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6510 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6511 IsUpdateExprFound = XId == PossibleXId; 6512 if (IsUpdateExprFound) { 6513 V = BinOp->getLHS(); 6514 X = Checker.getX(); 6515 E = Checker.getExpr(); 6516 UE = Checker.getUpdateExpr(); 6517 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6518 IsPostfixUpdate = true; 6519 } 6520 } 6521 if (!IsUpdateExprFound) { 6522 IsUpdateExprFound = !Checker.checkStatement(First); 6523 BinOp = nullptr; 6524 if (IsUpdateExprFound) { 6525 BinOp = dyn_cast<BinaryOperator>(Second); 6526 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6527 } 6528 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6529 // { x++; v = x; } 6530 // { x--; v = x; } 6531 // { ++x; v = x; } 6532 // { --x; v = x; } 6533 // { x binop= expr; v = x; } 6534 // { x = x binop expr; v = x; } 6535 // { x = expr binop x; v = x; } 6536 // Check that the second expression has form v = x. 6537 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6538 llvm::FoldingSetNodeID XId, PossibleXId; 6539 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6540 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6541 IsUpdateExprFound = XId == PossibleXId; 6542 if (IsUpdateExprFound) { 6543 V = BinOp->getLHS(); 6544 X = Checker.getX(); 6545 E = Checker.getExpr(); 6546 UE = Checker.getUpdateExpr(); 6547 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6548 IsPostfixUpdate = false; 6549 } 6550 } 6551 } 6552 if (!IsUpdateExprFound) { 6553 // { v = x; x = expr; } 6554 auto *FirstExpr = dyn_cast<Expr>(First); 6555 auto *SecondExpr = dyn_cast<Expr>(Second); 6556 if (!FirstExpr || !SecondExpr || 6557 !(FirstExpr->isInstantiationDependent() || 6558 SecondExpr->isInstantiationDependent())) { 6559 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6560 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6561 ErrorFound = NotAnAssignmentOp; 6562 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6563 : First->getBeginLoc(); 6564 NoteRange = ErrorRange = FirstBinOp 6565 ? FirstBinOp->getSourceRange() 6566 : SourceRange(ErrorLoc, ErrorLoc); 6567 } else { 6568 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6569 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6570 ErrorFound = NotAnAssignmentOp; 6571 NoteLoc = ErrorLoc = SecondBinOp 6572 ? SecondBinOp->getOperatorLoc() 6573 : Second->getBeginLoc(); 6574 NoteRange = ErrorRange = 6575 SecondBinOp ? SecondBinOp->getSourceRange() 6576 : SourceRange(ErrorLoc, ErrorLoc); 6577 } else { 6578 Expr *PossibleXRHSInFirst = 6579 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6580 Expr *PossibleXLHSInSecond = 6581 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6582 llvm::FoldingSetNodeID X1Id, X2Id; 6583 PossibleXRHSInFirst->Profile(X1Id, Context, 6584 /*Canonical=*/true); 6585 PossibleXLHSInSecond->Profile(X2Id, Context, 6586 /*Canonical=*/true); 6587 IsUpdateExprFound = X1Id == X2Id; 6588 if (IsUpdateExprFound) { 6589 V = FirstBinOp->getLHS(); 6590 X = SecondBinOp->getLHS(); 6591 E = SecondBinOp->getRHS(); 6592 UE = nullptr; 6593 IsXLHSInRHSPart = false; 6594 IsPostfixUpdate = true; 6595 } else { 6596 ErrorFound = NotASpecificExpression; 6597 ErrorLoc = FirstBinOp->getExprLoc(); 6598 ErrorRange = FirstBinOp->getSourceRange(); 6599 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6600 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6601 } 6602 } 6603 } 6604 } 6605 } 6606 } else { 6607 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6608 NoteRange = ErrorRange = 6609 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 6610 ErrorFound = NotTwoSubstatements; 6611 } 6612 } else { 6613 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6614 NoteRange = ErrorRange = 6615 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 6616 ErrorFound = NotACompoundStatement; 6617 } 6618 if (ErrorFound != NoError) { 6619 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6620 << ErrorRange; 6621 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6622 return StmtError(); 6623 } 6624 if (CurContext->isDependentContext()) 6625 UE = V = E = X = nullptr; 6626 } 6627 } 6628 6629 setFunctionHasBranchProtectedScope(); 6630 6631 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6632 X, V, E, UE, IsXLHSInRHSPart, 6633 IsPostfixUpdate); 6634 } 6635 6636 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6637 Stmt *AStmt, 6638 SourceLocation StartLoc, 6639 SourceLocation EndLoc) { 6640 if (!AStmt) 6641 return StmtError(); 6642 6643 auto *CS = cast<CapturedStmt>(AStmt); 6644 // 1.2.2 OpenMP Language Terminology 6645 // Structured block - An executable statement with a single entry at the 6646 // top and a single exit at the bottom. 6647 // The point of exit cannot be a branch out of the structured block. 6648 // longjmp() and throw() must not violate the entry/exit criteria. 6649 CS->getCapturedDecl()->setNothrow(); 6650 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 6651 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6652 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6653 // 1.2.2 OpenMP Language Terminology 6654 // Structured block - An executable statement with a single entry at the 6655 // top and a single exit at the bottom. 6656 // The point of exit cannot be a branch out of the structured block. 6657 // longjmp() and throw() must not violate the entry/exit criteria. 6658 CS->getCapturedDecl()->setNothrow(); 6659 } 6660 6661 // OpenMP [2.16, Nesting of Regions] 6662 // If specified, a teams construct must be contained within a target 6663 // construct. That target construct must contain no statements or directives 6664 // outside of the teams construct. 6665 if (DSAStack->hasInnerTeamsRegion()) { 6666 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 6667 bool OMPTeamsFound = true; 6668 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 6669 auto I = CS->body_begin(); 6670 while (I != CS->body_end()) { 6671 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 6672 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 6673 OMPTeamsFound = false; 6674 break; 6675 } 6676 ++I; 6677 } 6678 assert(I != CS->body_end() && "Not found statement"); 6679 S = *I; 6680 } else { 6681 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 6682 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 6683 } 6684 if (!OMPTeamsFound) { 6685 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 6686 Diag(DSAStack->getInnerTeamsRegionLoc(), 6687 diag::note_omp_nested_teams_construct_here); 6688 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 6689 << isa<OMPExecutableDirective>(S); 6690 return StmtError(); 6691 } 6692 } 6693 6694 setFunctionHasBranchProtectedScope(); 6695 6696 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6697 } 6698 6699 StmtResult 6700 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 6701 Stmt *AStmt, SourceLocation StartLoc, 6702 SourceLocation EndLoc) { 6703 if (!AStmt) 6704 return StmtError(); 6705 6706 auto *CS = cast<CapturedStmt>(AStmt); 6707 // 1.2.2 OpenMP Language Terminology 6708 // Structured block - An executable statement with a single entry at the 6709 // top and a single exit at the bottom. 6710 // The point of exit cannot be a branch out of the structured block. 6711 // longjmp() and throw() must not violate the entry/exit criteria. 6712 CS->getCapturedDecl()->setNothrow(); 6713 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 6714 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6715 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6716 // 1.2.2 OpenMP Language Terminology 6717 // Structured block - An executable statement with a single entry at the 6718 // top and a single exit at the bottom. 6719 // The point of exit cannot be a branch out of the structured block. 6720 // longjmp() and throw() must not violate the entry/exit criteria. 6721 CS->getCapturedDecl()->setNothrow(); 6722 } 6723 6724 setFunctionHasBranchProtectedScope(); 6725 6726 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6727 AStmt); 6728 } 6729 6730 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 6731 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6732 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6733 if (!AStmt) 6734 return StmtError(); 6735 6736 auto *CS = cast<CapturedStmt>(AStmt); 6737 // 1.2.2 OpenMP Language Terminology 6738 // Structured block - An executable statement with a single entry at the 6739 // top and a single exit at the bottom. 6740 // The point of exit cannot be a branch out of the structured block. 6741 // longjmp() and throw() must not violate the entry/exit criteria. 6742 CS->getCapturedDecl()->setNothrow(); 6743 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 6744 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6745 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6746 // 1.2.2 OpenMP Language Terminology 6747 // Structured block - An executable statement with a single entry at the 6748 // top and a single exit at the bottom. 6749 // The point of exit cannot be a branch out of the structured block. 6750 // longjmp() and throw() must not violate the entry/exit criteria. 6751 CS->getCapturedDecl()->setNothrow(); 6752 } 6753 6754 OMPLoopDirective::HelperExprs B; 6755 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6756 // define the nested loops number. 6757 unsigned NestedLoopCount = 6758 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 6759 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 6760 VarsWithImplicitDSA, B); 6761 if (NestedLoopCount == 0) 6762 return StmtError(); 6763 6764 assert((CurContext->isDependentContext() || B.builtAll()) && 6765 "omp target parallel for loop exprs were not built"); 6766 6767 if (!CurContext->isDependentContext()) { 6768 // Finalize the clauses that need pre-built expressions for CodeGen. 6769 for (OMPClause *C : Clauses) { 6770 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6771 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6772 B.NumIterations, *this, CurScope, 6773 DSAStack)) 6774 return StmtError(); 6775 } 6776 } 6777 6778 setFunctionHasBranchProtectedScope(); 6779 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 6780 NestedLoopCount, Clauses, AStmt, 6781 B, DSAStack->isCancelRegion()); 6782 } 6783 6784 /// Check for existence of a map clause in the list of clauses. 6785 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 6786 const OpenMPClauseKind K) { 6787 return llvm::any_of( 6788 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 6789 } 6790 6791 template <typename... Params> 6792 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 6793 const Params... ClauseTypes) { 6794 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 6795 } 6796 6797 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 6798 Stmt *AStmt, 6799 SourceLocation StartLoc, 6800 SourceLocation EndLoc) { 6801 if (!AStmt) 6802 return StmtError(); 6803 6804 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6805 6806 // OpenMP [2.10.1, Restrictions, p. 97] 6807 // At least one map clause must appear on the directive. 6808 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 6809 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6810 << "'map' or 'use_device_ptr'" 6811 << getOpenMPDirectiveName(OMPD_target_data); 6812 return StmtError(); 6813 } 6814 6815 setFunctionHasBranchProtectedScope(); 6816 6817 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6818 AStmt); 6819 } 6820 6821 StmtResult 6822 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6823 SourceLocation StartLoc, 6824 SourceLocation EndLoc, Stmt *AStmt) { 6825 if (!AStmt) 6826 return StmtError(); 6827 6828 auto *CS = cast<CapturedStmt>(AStmt); 6829 // 1.2.2 OpenMP Language Terminology 6830 // Structured block - An executable statement with a single entry at the 6831 // top and a single exit at the bottom. 6832 // The point of exit cannot be a branch out of the structured block. 6833 // longjmp() and throw() must not violate the entry/exit criteria. 6834 CS->getCapturedDecl()->setNothrow(); 6835 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 6836 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6837 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6838 // 1.2.2 OpenMP Language Terminology 6839 // Structured block - An executable statement with a single entry at the 6840 // top and a single exit at the bottom. 6841 // The point of exit cannot be a branch out of the structured block. 6842 // longjmp() and throw() must not violate the entry/exit criteria. 6843 CS->getCapturedDecl()->setNothrow(); 6844 } 6845 6846 // OpenMP [2.10.2, Restrictions, p. 99] 6847 // At least one map clause must appear on the directive. 6848 if (!hasClauses(Clauses, OMPC_map)) { 6849 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6850 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 6851 return StmtError(); 6852 } 6853 6854 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6855 AStmt); 6856 } 6857 6858 StmtResult 6859 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6860 SourceLocation StartLoc, 6861 SourceLocation EndLoc, Stmt *AStmt) { 6862 if (!AStmt) 6863 return StmtError(); 6864 6865 auto *CS = cast<CapturedStmt>(AStmt); 6866 // 1.2.2 OpenMP Language Terminology 6867 // Structured block - An executable statement with a single entry at the 6868 // top and a single exit at the bottom. 6869 // The point of exit cannot be a branch out of the structured block. 6870 // longjmp() and throw() must not violate the entry/exit criteria. 6871 CS->getCapturedDecl()->setNothrow(); 6872 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 6873 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6874 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6875 // 1.2.2 OpenMP Language Terminology 6876 // Structured block - An executable statement with a single entry at the 6877 // top and a single exit at the bottom. 6878 // The point of exit cannot be a branch out of the structured block. 6879 // longjmp() and throw() must not violate the entry/exit criteria. 6880 CS->getCapturedDecl()->setNothrow(); 6881 } 6882 6883 // OpenMP [2.10.3, Restrictions, p. 102] 6884 // At least one map clause must appear on the directive. 6885 if (!hasClauses(Clauses, OMPC_map)) { 6886 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6887 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 6888 return StmtError(); 6889 } 6890 6891 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6892 AStmt); 6893 } 6894 6895 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 6896 SourceLocation StartLoc, 6897 SourceLocation EndLoc, 6898 Stmt *AStmt) { 6899 if (!AStmt) 6900 return StmtError(); 6901 6902 auto *CS = cast<CapturedStmt>(AStmt); 6903 // 1.2.2 OpenMP Language Terminology 6904 // Structured block - An executable statement with a single entry at the 6905 // top and a single exit at the bottom. 6906 // The point of exit cannot be a branch out of the structured block. 6907 // longjmp() and throw() must not violate the entry/exit criteria. 6908 CS->getCapturedDecl()->setNothrow(); 6909 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 6910 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6911 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6912 // 1.2.2 OpenMP Language Terminology 6913 // Structured block - An executable statement with a single entry at the 6914 // top and a single exit at the bottom. 6915 // The point of exit cannot be a branch out of the structured block. 6916 // longjmp() and throw() must not violate the entry/exit criteria. 6917 CS->getCapturedDecl()->setNothrow(); 6918 } 6919 6920 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 6921 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 6922 return StmtError(); 6923 } 6924 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 6925 AStmt); 6926 } 6927 6928 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6929 Stmt *AStmt, SourceLocation StartLoc, 6930 SourceLocation EndLoc) { 6931 if (!AStmt) 6932 return StmtError(); 6933 6934 auto *CS = cast<CapturedStmt>(AStmt); 6935 // 1.2.2 OpenMP Language Terminology 6936 // Structured block - An executable statement with a single entry at the 6937 // top and a single exit at the bottom. 6938 // The point of exit cannot be a branch out of the structured block. 6939 // longjmp() and throw() must not violate the entry/exit criteria. 6940 CS->getCapturedDecl()->setNothrow(); 6941 6942 setFunctionHasBranchProtectedScope(); 6943 6944 DSAStack->setParentTeamsRegionLoc(StartLoc); 6945 6946 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6947 } 6948 6949 StmtResult 6950 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6951 SourceLocation EndLoc, 6952 OpenMPDirectiveKind CancelRegion) { 6953 if (DSAStack->isParentNowaitRegion()) { 6954 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6955 return StmtError(); 6956 } 6957 if (DSAStack->isParentOrderedRegion()) { 6958 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6959 return StmtError(); 6960 } 6961 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6962 CancelRegion); 6963 } 6964 6965 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6966 SourceLocation StartLoc, 6967 SourceLocation EndLoc, 6968 OpenMPDirectiveKind CancelRegion) { 6969 if (DSAStack->isParentNowaitRegion()) { 6970 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6971 return StmtError(); 6972 } 6973 if (DSAStack->isParentOrderedRegion()) { 6974 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6975 return StmtError(); 6976 } 6977 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6978 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6979 CancelRegion); 6980 } 6981 6982 static bool checkGrainsizeNumTasksClauses(Sema &S, 6983 ArrayRef<OMPClause *> Clauses) { 6984 const OMPClause *PrevClause = nullptr; 6985 bool ErrorFound = false; 6986 for (const OMPClause *C : Clauses) { 6987 if (C->getClauseKind() == OMPC_grainsize || 6988 C->getClauseKind() == OMPC_num_tasks) { 6989 if (!PrevClause) 6990 PrevClause = C; 6991 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6992 S.Diag(C->getBeginLoc(), 6993 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6994 << getOpenMPClauseName(C->getClauseKind()) 6995 << getOpenMPClauseName(PrevClause->getClauseKind()); 6996 S.Diag(PrevClause->getBeginLoc(), 6997 diag::note_omp_previous_grainsize_num_tasks) 6998 << getOpenMPClauseName(PrevClause->getClauseKind()); 6999 ErrorFound = true; 7000 } 7001 } 7002 } 7003 return ErrorFound; 7004 } 7005 7006 static bool checkReductionClauseWithNogroup(Sema &S, 7007 ArrayRef<OMPClause *> Clauses) { 7008 const OMPClause *ReductionClause = nullptr; 7009 const OMPClause *NogroupClause = nullptr; 7010 for (const OMPClause *C : Clauses) { 7011 if (C->getClauseKind() == OMPC_reduction) { 7012 ReductionClause = C; 7013 if (NogroupClause) 7014 break; 7015 continue; 7016 } 7017 if (C->getClauseKind() == OMPC_nogroup) { 7018 NogroupClause = C; 7019 if (ReductionClause) 7020 break; 7021 continue; 7022 } 7023 } 7024 if (ReductionClause && NogroupClause) { 7025 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 7026 << SourceRange(NogroupClause->getBeginLoc(), 7027 NogroupClause->getEndLoc()); 7028 return true; 7029 } 7030 return false; 7031 } 7032 7033 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 7034 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7035 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7036 if (!AStmt) 7037 return StmtError(); 7038 7039 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7040 OMPLoopDirective::HelperExprs B; 7041 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7042 // define the nested loops number. 7043 unsigned NestedLoopCount = 7044 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 7045 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7046 VarsWithImplicitDSA, B); 7047 if (NestedLoopCount == 0) 7048 return StmtError(); 7049 7050 assert((CurContext->isDependentContext() || B.builtAll()) && 7051 "omp for loop exprs were not built"); 7052 7053 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7054 // The grainsize clause and num_tasks clause are mutually exclusive and may 7055 // not appear on the same taskloop directive. 7056 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7057 return StmtError(); 7058 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7059 // If a reduction clause is present on the taskloop directive, the nogroup 7060 // clause must not be specified. 7061 if (checkReductionClauseWithNogroup(*this, Clauses)) 7062 return StmtError(); 7063 7064 setFunctionHasBranchProtectedScope(); 7065 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 7066 NestedLoopCount, Clauses, AStmt, B); 7067 } 7068 7069 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 7070 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7071 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7072 if (!AStmt) 7073 return StmtError(); 7074 7075 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7076 OMPLoopDirective::HelperExprs B; 7077 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7078 // define the nested loops number. 7079 unsigned NestedLoopCount = 7080 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 7081 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7082 VarsWithImplicitDSA, B); 7083 if (NestedLoopCount == 0) 7084 return StmtError(); 7085 7086 assert((CurContext->isDependentContext() || B.builtAll()) && 7087 "omp for loop exprs were not built"); 7088 7089 if (!CurContext->isDependentContext()) { 7090 // Finalize the clauses that need pre-built expressions for CodeGen. 7091 for (OMPClause *C : Clauses) { 7092 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7093 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7094 B.NumIterations, *this, CurScope, 7095 DSAStack)) 7096 return StmtError(); 7097 } 7098 } 7099 7100 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7101 // The grainsize clause and num_tasks clause are mutually exclusive and may 7102 // not appear on the same taskloop directive. 7103 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7104 return StmtError(); 7105 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7106 // If a reduction clause is present on the taskloop directive, the nogroup 7107 // clause must not be specified. 7108 if (checkReductionClauseWithNogroup(*this, Clauses)) 7109 return StmtError(); 7110 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7111 return StmtError(); 7112 7113 setFunctionHasBranchProtectedScope(); 7114 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 7115 NestedLoopCount, Clauses, AStmt, B); 7116 } 7117 7118 StmtResult Sema::ActOnOpenMPDistributeDirective( 7119 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7120 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7121 if (!AStmt) 7122 return StmtError(); 7123 7124 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7125 OMPLoopDirective::HelperExprs B; 7126 // In presence of clause 'collapse' with number of loops, it will 7127 // define the nested loops number. 7128 unsigned NestedLoopCount = 7129 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 7130 nullptr /*ordered not a clause on distribute*/, AStmt, 7131 *this, *DSAStack, VarsWithImplicitDSA, B); 7132 if (NestedLoopCount == 0) 7133 return StmtError(); 7134 7135 assert((CurContext->isDependentContext() || B.builtAll()) && 7136 "omp for loop exprs were not built"); 7137 7138 setFunctionHasBranchProtectedScope(); 7139 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 7140 NestedLoopCount, Clauses, AStmt, B); 7141 } 7142 7143 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 7144 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7145 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7146 if (!AStmt) 7147 return StmtError(); 7148 7149 auto *CS = cast<CapturedStmt>(AStmt); 7150 // 1.2.2 OpenMP Language Terminology 7151 // Structured block - An executable statement with a single entry at the 7152 // top and a single exit at the bottom. 7153 // The point of exit cannot be a branch out of the structured block. 7154 // longjmp() and throw() must not violate the entry/exit criteria. 7155 CS->getCapturedDecl()->setNothrow(); 7156 for (int ThisCaptureLevel = 7157 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 7158 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7159 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7160 // 1.2.2 OpenMP Language Terminology 7161 // Structured block - An executable statement with a single entry at the 7162 // top and a single exit at the bottom. 7163 // The point of exit cannot be a branch out of the structured block. 7164 // longjmp() and throw() must not violate the entry/exit criteria. 7165 CS->getCapturedDecl()->setNothrow(); 7166 } 7167 7168 OMPLoopDirective::HelperExprs B; 7169 // In presence of clause 'collapse' with number of loops, it will 7170 // define the nested loops number. 7171 unsigned NestedLoopCount = checkOpenMPLoop( 7172 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7173 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7174 VarsWithImplicitDSA, B); 7175 if (NestedLoopCount == 0) 7176 return StmtError(); 7177 7178 assert((CurContext->isDependentContext() || B.builtAll()) && 7179 "omp for loop exprs were not built"); 7180 7181 setFunctionHasBranchProtectedScope(); 7182 return OMPDistributeParallelForDirective::Create( 7183 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7184 DSAStack->isCancelRegion()); 7185 } 7186 7187 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 7188 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7189 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 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 = 7201 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 7202 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7203 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7204 // 1.2.2 OpenMP Language Terminology 7205 // Structured block - An executable statement with a single entry at the 7206 // top and a single exit at the bottom. 7207 // The point of exit cannot be a branch out of the structured block. 7208 // longjmp() and throw() must not violate the entry/exit criteria. 7209 CS->getCapturedDecl()->setNothrow(); 7210 } 7211 7212 OMPLoopDirective::HelperExprs B; 7213 // In presence of clause 'collapse' with number of loops, it will 7214 // define the nested loops number. 7215 unsigned NestedLoopCount = checkOpenMPLoop( 7216 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7217 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7218 VarsWithImplicitDSA, B); 7219 if (NestedLoopCount == 0) 7220 return StmtError(); 7221 7222 assert((CurContext->isDependentContext() || B.builtAll()) && 7223 "omp for loop exprs were not built"); 7224 7225 if (!CurContext->isDependentContext()) { 7226 // Finalize the clauses that need pre-built expressions for CodeGen. 7227 for (OMPClause *C : Clauses) { 7228 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7229 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7230 B.NumIterations, *this, CurScope, 7231 DSAStack)) 7232 return StmtError(); 7233 } 7234 } 7235 7236 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7237 return StmtError(); 7238 7239 setFunctionHasBranchProtectedScope(); 7240 return OMPDistributeParallelForSimdDirective::Create( 7241 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7242 } 7243 7244 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 7245 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7246 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7247 if (!AStmt) 7248 return StmtError(); 7249 7250 auto *CS = cast<CapturedStmt>(AStmt); 7251 // 1.2.2 OpenMP Language Terminology 7252 // Structured block - An executable statement with a single entry at the 7253 // top and a single exit at the bottom. 7254 // The point of exit cannot be a branch out of the structured block. 7255 // longjmp() and throw() must not violate the entry/exit criteria. 7256 CS->getCapturedDecl()->setNothrow(); 7257 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 7258 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7259 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7260 // 1.2.2 OpenMP Language Terminology 7261 // Structured block - An executable statement with a single entry at the 7262 // top and a single exit at the bottom. 7263 // The point of exit cannot be a branch out of the structured block. 7264 // longjmp() and throw() must not violate the entry/exit criteria. 7265 CS->getCapturedDecl()->setNothrow(); 7266 } 7267 7268 OMPLoopDirective::HelperExprs B; 7269 // In presence of clause 'collapse' with number of loops, it will 7270 // define the nested loops number. 7271 unsigned NestedLoopCount = 7272 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 7273 nullptr /*ordered not a clause on distribute*/, CS, *this, 7274 *DSAStack, VarsWithImplicitDSA, B); 7275 if (NestedLoopCount == 0) 7276 return StmtError(); 7277 7278 assert((CurContext->isDependentContext() || B.builtAll()) && 7279 "omp for loop exprs were not built"); 7280 7281 if (!CurContext->isDependentContext()) { 7282 // Finalize the clauses that need pre-built expressions for CodeGen. 7283 for (OMPClause *C : Clauses) { 7284 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7285 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7286 B.NumIterations, *this, CurScope, 7287 DSAStack)) 7288 return StmtError(); 7289 } 7290 } 7291 7292 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7293 return StmtError(); 7294 7295 setFunctionHasBranchProtectedScope(); 7296 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 7297 NestedLoopCount, Clauses, AStmt, B); 7298 } 7299 7300 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 7301 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7302 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7303 if (!AStmt) 7304 return StmtError(); 7305 7306 auto *CS = cast<CapturedStmt>(AStmt); 7307 // 1.2.2 OpenMP Language Terminology 7308 // Structured block - An executable statement with a single entry at the 7309 // top and a single exit at the bottom. 7310 // The point of exit cannot be a branch out of the structured block. 7311 // longjmp() and throw() must not violate the entry/exit criteria. 7312 CS->getCapturedDecl()->setNothrow(); 7313 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7314 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7315 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7316 // 1.2.2 OpenMP Language Terminology 7317 // Structured block - An executable statement with a single entry at the 7318 // top and a single exit at the bottom. 7319 // The point of exit cannot be a branch out of the structured block. 7320 // longjmp() and throw() must not violate the entry/exit criteria. 7321 CS->getCapturedDecl()->setNothrow(); 7322 } 7323 7324 OMPLoopDirective::HelperExprs B; 7325 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7326 // define the nested loops number. 7327 unsigned NestedLoopCount = checkOpenMPLoop( 7328 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 7329 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7330 VarsWithImplicitDSA, B); 7331 if (NestedLoopCount == 0) 7332 return StmtError(); 7333 7334 assert((CurContext->isDependentContext() || B.builtAll()) && 7335 "omp target parallel for simd loop exprs were not built"); 7336 7337 if (!CurContext->isDependentContext()) { 7338 // Finalize the clauses that need pre-built expressions for CodeGen. 7339 for (OMPClause *C : Clauses) { 7340 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7341 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7342 B.NumIterations, *this, CurScope, 7343 DSAStack)) 7344 return StmtError(); 7345 } 7346 } 7347 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7348 return StmtError(); 7349 7350 setFunctionHasBranchProtectedScope(); 7351 return OMPTargetParallelForSimdDirective::Create( 7352 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7353 } 7354 7355 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 7356 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7357 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7358 if (!AStmt) 7359 return StmtError(); 7360 7361 auto *CS = cast<CapturedStmt>(AStmt); 7362 // 1.2.2 OpenMP Language Terminology 7363 // Structured block - An executable statement with a single entry at the 7364 // top and a single exit at the bottom. 7365 // The point of exit cannot be a branch out of the structured block. 7366 // longjmp() and throw() must not violate the entry/exit criteria. 7367 CS->getCapturedDecl()->setNothrow(); 7368 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 7369 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7370 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7371 // 1.2.2 OpenMP Language Terminology 7372 // Structured block - An executable statement with a single entry at the 7373 // top and a single exit at the bottom. 7374 // The point of exit cannot be a branch out of the structured block. 7375 // longjmp() and throw() must not violate the entry/exit criteria. 7376 CS->getCapturedDecl()->setNothrow(); 7377 } 7378 7379 OMPLoopDirective::HelperExprs B; 7380 // In presence of clause 'collapse' with number of loops, it will define the 7381 // nested loops number. 7382 unsigned NestedLoopCount = 7383 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 7384 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7385 VarsWithImplicitDSA, B); 7386 if (NestedLoopCount == 0) 7387 return StmtError(); 7388 7389 assert((CurContext->isDependentContext() || B.builtAll()) && 7390 "omp target simd loop exprs were not built"); 7391 7392 if (!CurContext->isDependentContext()) { 7393 // Finalize the clauses that need pre-built expressions for CodeGen. 7394 for (OMPClause *C : Clauses) { 7395 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7396 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7397 B.NumIterations, *this, CurScope, 7398 DSAStack)) 7399 return StmtError(); 7400 } 7401 } 7402 7403 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7404 return StmtError(); 7405 7406 setFunctionHasBranchProtectedScope(); 7407 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 7408 NestedLoopCount, Clauses, AStmt, B); 7409 } 7410 7411 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 7412 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7413 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 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_teams_distribute); 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 OMPLoopDirective::HelperExprs B; 7436 // In presence of clause 'collapse' with number of loops, it will 7437 // define the nested loops number. 7438 unsigned NestedLoopCount = 7439 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 7440 nullptr /*ordered not a clause on distribute*/, CS, *this, 7441 *DSAStack, VarsWithImplicitDSA, B); 7442 if (NestedLoopCount == 0) 7443 return StmtError(); 7444 7445 assert((CurContext->isDependentContext() || B.builtAll()) && 7446 "omp teams distribute loop exprs were not built"); 7447 7448 setFunctionHasBranchProtectedScope(); 7449 7450 DSAStack->setParentTeamsRegionLoc(StartLoc); 7451 7452 return OMPTeamsDistributeDirective::Create( 7453 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7454 } 7455 7456 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 7457 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7458 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7459 if (!AStmt) 7460 return StmtError(); 7461 7462 auto *CS = cast<CapturedStmt>(AStmt); 7463 // 1.2.2 OpenMP Language Terminology 7464 // Structured block - An executable statement with a single entry at the 7465 // top and a single exit at the bottom. 7466 // The point of exit cannot be a branch out of the structured block. 7467 // longjmp() and throw() must not violate the entry/exit criteria. 7468 CS->getCapturedDecl()->setNothrow(); 7469 for (int ThisCaptureLevel = 7470 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 7471 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7472 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7473 // 1.2.2 OpenMP Language Terminology 7474 // Structured block - An executable statement with a single entry at the 7475 // top and a single exit at the bottom. 7476 // The point of exit cannot be a branch out of the structured block. 7477 // longjmp() and throw() must not violate the entry/exit criteria. 7478 CS->getCapturedDecl()->setNothrow(); 7479 } 7480 7481 7482 OMPLoopDirective::HelperExprs B; 7483 // In presence of clause 'collapse' with number of loops, it will 7484 // define the nested loops number. 7485 unsigned NestedLoopCount = checkOpenMPLoop( 7486 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7487 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7488 VarsWithImplicitDSA, B); 7489 7490 if (NestedLoopCount == 0) 7491 return StmtError(); 7492 7493 assert((CurContext->isDependentContext() || B.builtAll()) && 7494 "omp teams distribute simd loop exprs were not built"); 7495 7496 if (!CurContext->isDependentContext()) { 7497 // Finalize the clauses that need pre-built expressions for CodeGen. 7498 for (OMPClause *C : Clauses) { 7499 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7500 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7501 B.NumIterations, *this, CurScope, 7502 DSAStack)) 7503 return StmtError(); 7504 } 7505 } 7506 7507 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7508 return StmtError(); 7509 7510 setFunctionHasBranchProtectedScope(); 7511 7512 DSAStack->setParentTeamsRegionLoc(StartLoc); 7513 7514 return OMPTeamsDistributeSimdDirective::Create( 7515 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7516 } 7517 7518 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 7519 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7520 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7521 if (!AStmt) 7522 return StmtError(); 7523 7524 auto *CS = cast<CapturedStmt>(AStmt); 7525 // 1.2.2 OpenMP Language Terminology 7526 // Structured block - An executable statement with a single entry at the 7527 // top and a single exit at the bottom. 7528 // The point of exit cannot be a branch out of the structured block. 7529 // longjmp() and throw() must not violate the entry/exit criteria. 7530 CS->getCapturedDecl()->setNothrow(); 7531 7532 for (int ThisCaptureLevel = 7533 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 7534 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7535 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7536 // 1.2.2 OpenMP Language Terminology 7537 // Structured block - An executable statement with a single entry at the 7538 // top and a single exit at the bottom. 7539 // The point of exit cannot be a branch out of the structured block. 7540 // longjmp() and throw() must not violate the entry/exit criteria. 7541 CS->getCapturedDecl()->setNothrow(); 7542 } 7543 7544 OMPLoopDirective::HelperExprs B; 7545 // In presence of clause 'collapse' with number of loops, it will 7546 // define the nested loops number. 7547 unsigned NestedLoopCount = checkOpenMPLoop( 7548 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7549 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7550 VarsWithImplicitDSA, B); 7551 7552 if (NestedLoopCount == 0) 7553 return StmtError(); 7554 7555 assert((CurContext->isDependentContext() || B.builtAll()) && 7556 "omp for loop exprs were not built"); 7557 7558 if (!CurContext->isDependentContext()) { 7559 // Finalize the clauses that need pre-built expressions for CodeGen. 7560 for (OMPClause *C : Clauses) { 7561 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7562 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7563 B.NumIterations, *this, CurScope, 7564 DSAStack)) 7565 return StmtError(); 7566 } 7567 } 7568 7569 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7570 return StmtError(); 7571 7572 setFunctionHasBranchProtectedScope(); 7573 7574 DSAStack->setParentTeamsRegionLoc(StartLoc); 7575 7576 return OMPTeamsDistributeParallelForSimdDirective::Create( 7577 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7578 } 7579 7580 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 7581 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7582 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7583 if (!AStmt) 7584 return StmtError(); 7585 7586 auto *CS = cast<CapturedStmt>(AStmt); 7587 // 1.2.2 OpenMP Language Terminology 7588 // Structured block - An executable statement with a single entry at the 7589 // top and a single exit at the bottom. 7590 // The point of exit cannot be a branch out of the structured block. 7591 // longjmp() and throw() must not violate the entry/exit criteria. 7592 CS->getCapturedDecl()->setNothrow(); 7593 7594 for (int ThisCaptureLevel = 7595 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 7596 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7597 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7598 // 1.2.2 OpenMP Language Terminology 7599 // Structured block - An executable statement with a single entry at the 7600 // top and a single exit at the bottom. 7601 // The point of exit cannot be a branch out of the structured block. 7602 // longjmp() and throw() must not violate the entry/exit criteria. 7603 CS->getCapturedDecl()->setNothrow(); 7604 } 7605 7606 OMPLoopDirective::HelperExprs B; 7607 // In presence of clause 'collapse' with number of loops, it will 7608 // define the nested loops number. 7609 unsigned NestedLoopCount = checkOpenMPLoop( 7610 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7611 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7612 VarsWithImplicitDSA, B); 7613 7614 if (NestedLoopCount == 0) 7615 return StmtError(); 7616 7617 assert((CurContext->isDependentContext() || B.builtAll()) && 7618 "omp for loop exprs were not built"); 7619 7620 setFunctionHasBranchProtectedScope(); 7621 7622 DSAStack->setParentTeamsRegionLoc(StartLoc); 7623 7624 return OMPTeamsDistributeParallelForDirective::Create( 7625 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7626 DSAStack->isCancelRegion()); 7627 } 7628 7629 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 7630 Stmt *AStmt, 7631 SourceLocation StartLoc, 7632 SourceLocation EndLoc) { 7633 if (!AStmt) 7634 return StmtError(); 7635 7636 auto *CS = cast<CapturedStmt>(AStmt); 7637 // 1.2.2 OpenMP Language Terminology 7638 // Structured block - An executable statement with a single entry at the 7639 // top and a single exit at the bottom. 7640 // The point of exit cannot be a branch out of the structured block. 7641 // longjmp() and throw() must not violate the entry/exit criteria. 7642 CS->getCapturedDecl()->setNothrow(); 7643 7644 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 7645 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7646 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7647 // 1.2.2 OpenMP Language Terminology 7648 // Structured block - An executable statement with a single entry at the 7649 // top and a single exit at the bottom. 7650 // The point of exit cannot be a branch out of the structured block. 7651 // longjmp() and throw() must not violate the entry/exit criteria. 7652 CS->getCapturedDecl()->setNothrow(); 7653 } 7654 setFunctionHasBranchProtectedScope(); 7655 7656 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 7657 AStmt); 7658 } 7659 7660 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 7661 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7662 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7663 if (!AStmt) 7664 return StmtError(); 7665 7666 auto *CS = cast<CapturedStmt>(AStmt); 7667 // 1.2.2 OpenMP Language Terminology 7668 // Structured block - An executable statement with a single entry at the 7669 // top and a single exit at the bottom. 7670 // The point of exit cannot be a branch out of the structured block. 7671 // longjmp() and throw() must not violate the entry/exit criteria. 7672 CS->getCapturedDecl()->setNothrow(); 7673 for (int ThisCaptureLevel = 7674 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 7675 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7676 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7677 // 1.2.2 OpenMP Language Terminology 7678 // Structured block - An executable statement with a single entry at the 7679 // top and a single exit at the bottom. 7680 // The point of exit cannot be a branch out of the structured block. 7681 // longjmp() and throw() must not violate the entry/exit criteria. 7682 CS->getCapturedDecl()->setNothrow(); 7683 } 7684 7685 OMPLoopDirective::HelperExprs B; 7686 // In presence of clause 'collapse' with number of loops, it will 7687 // define the nested loops number. 7688 unsigned NestedLoopCount = checkOpenMPLoop( 7689 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 7690 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7691 VarsWithImplicitDSA, B); 7692 if (NestedLoopCount == 0) 7693 return StmtError(); 7694 7695 assert((CurContext->isDependentContext() || B.builtAll()) && 7696 "omp target teams distribute loop exprs were not built"); 7697 7698 setFunctionHasBranchProtectedScope(); 7699 return OMPTargetTeamsDistributeDirective::Create( 7700 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7701 } 7702 7703 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 7704 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7705 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7706 if (!AStmt) 7707 return StmtError(); 7708 7709 auto *CS = cast<CapturedStmt>(AStmt); 7710 // 1.2.2 OpenMP Language Terminology 7711 // Structured block - An executable statement with a single entry at the 7712 // top and a single exit at the bottom. 7713 // The point of exit cannot be a branch out of the structured block. 7714 // longjmp() and throw() must not violate the entry/exit criteria. 7715 CS->getCapturedDecl()->setNothrow(); 7716 for (int ThisCaptureLevel = 7717 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 7718 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7719 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7720 // 1.2.2 OpenMP Language Terminology 7721 // Structured block - An executable statement with a single entry at the 7722 // top and a single exit at the bottom. 7723 // The point of exit cannot be a branch out of the structured block. 7724 // longjmp() and throw() must not violate the entry/exit criteria. 7725 CS->getCapturedDecl()->setNothrow(); 7726 } 7727 7728 OMPLoopDirective::HelperExprs B; 7729 // In presence of clause 'collapse' with number of loops, it will 7730 // define the nested loops number. 7731 unsigned NestedLoopCount = checkOpenMPLoop( 7732 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7733 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7734 VarsWithImplicitDSA, B); 7735 if (NestedLoopCount == 0) 7736 return StmtError(); 7737 7738 assert((CurContext->isDependentContext() || B.builtAll()) && 7739 "omp target teams distribute parallel for loop exprs were not built"); 7740 7741 if (!CurContext->isDependentContext()) { 7742 // Finalize the clauses that need pre-built expressions for CodeGen. 7743 for (OMPClause *C : Clauses) { 7744 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7745 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7746 B.NumIterations, *this, CurScope, 7747 DSAStack)) 7748 return StmtError(); 7749 } 7750 } 7751 7752 setFunctionHasBranchProtectedScope(); 7753 return OMPTargetTeamsDistributeParallelForDirective::Create( 7754 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7755 DSAStack->isCancelRegion()); 7756 } 7757 7758 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 7759 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7760 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7761 if (!AStmt) 7762 return StmtError(); 7763 7764 auto *CS = cast<CapturedStmt>(AStmt); 7765 // 1.2.2 OpenMP Language Terminology 7766 // Structured block - An executable statement with a single entry at the 7767 // top and a single exit at the bottom. 7768 // The point of exit cannot be a branch out of the structured block. 7769 // longjmp() and throw() must not violate the entry/exit criteria. 7770 CS->getCapturedDecl()->setNothrow(); 7771 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 7772 OMPD_target_teams_distribute_parallel_for_simd); 7773 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7774 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7775 // 1.2.2 OpenMP Language Terminology 7776 // Structured block - An executable statement with a single entry at the 7777 // top and a single exit at the bottom. 7778 // The point of exit cannot be a branch out of the structured block. 7779 // longjmp() and throw() must not violate the entry/exit criteria. 7780 CS->getCapturedDecl()->setNothrow(); 7781 } 7782 7783 OMPLoopDirective::HelperExprs B; 7784 // In presence of clause 'collapse' with number of loops, it will 7785 // define the nested loops number. 7786 unsigned NestedLoopCount = 7787 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 7788 getCollapseNumberExpr(Clauses), 7789 nullptr /*ordered not a clause on distribute*/, CS, *this, 7790 *DSAStack, VarsWithImplicitDSA, B); 7791 if (NestedLoopCount == 0) 7792 return StmtError(); 7793 7794 assert((CurContext->isDependentContext() || B.builtAll()) && 7795 "omp target teams distribute parallel for simd loop exprs were not " 7796 "built"); 7797 7798 if (!CurContext->isDependentContext()) { 7799 // Finalize the clauses that need pre-built expressions for CodeGen. 7800 for (OMPClause *C : Clauses) { 7801 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7802 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7803 B.NumIterations, *this, CurScope, 7804 DSAStack)) 7805 return StmtError(); 7806 } 7807 } 7808 7809 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7810 return StmtError(); 7811 7812 setFunctionHasBranchProtectedScope(); 7813 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 7814 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7815 } 7816 7817 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 7818 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7819 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7820 if (!AStmt) 7821 return StmtError(); 7822 7823 auto *CS = cast<CapturedStmt>(AStmt); 7824 // 1.2.2 OpenMP Language Terminology 7825 // Structured block - An executable statement with a single entry at the 7826 // top and a single exit at the bottom. 7827 // The point of exit cannot be a branch out of the structured block. 7828 // longjmp() and throw() must not violate the entry/exit criteria. 7829 CS->getCapturedDecl()->setNothrow(); 7830 for (int ThisCaptureLevel = 7831 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 7832 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7833 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7834 // 1.2.2 OpenMP Language Terminology 7835 // Structured block - An executable statement with a single entry at the 7836 // top and a single exit at the bottom. 7837 // The point of exit cannot be a branch out of the structured block. 7838 // longjmp() and throw() must not violate the entry/exit criteria. 7839 CS->getCapturedDecl()->setNothrow(); 7840 } 7841 7842 OMPLoopDirective::HelperExprs B; 7843 // In presence of clause 'collapse' with number of loops, it will 7844 // define the nested loops number. 7845 unsigned NestedLoopCount = checkOpenMPLoop( 7846 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7847 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7848 VarsWithImplicitDSA, B); 7849 if (NestedLoopCount == 0) 7850 return StmtError(); 7851 7852 assert((CurContext->isDependentContext() || B.builtAll()) && 7853 "omp target teams distribute simd loop exprs were not built"); 7854 7855 if (!CurContext->isDependentContext()) { 7856 // Finalize the clauses that need pre-built expressions for CodeGen. 7857 for (OMPClause *C : Clauses) { 7858 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7859 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7860 B.NumIterations, *this, CurScope, 7861 DSAStack)) 7862 return StmtError(); 7863 } 7864 } 7865 7866 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7867 return StmtError(); 7868 7869 setFunctionHasBranchProtectedScope(); 7870 return OMPTargetTeamsDistributeSimdDirective::Create( 7871 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7872 } 7873 7874 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 7875 SourceLocation StartLoc, 7876 SourceLocation LParenLoc, 7877 SourceLocation EndLoc) { 7878 OMPClause *Res = nullptr; 7879 switch (Kind) { 7880 case OMPC_final: 7881 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 7882 break; 7883 case OMPC_num_threads: 7884 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 7885 break; 7886 case OMPC_safelen: 7887 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 7888 break; 7889 case OMPC_simdlen: 7890 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 7891 break; 7892 case OMPC_collapse: 7893 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 7894 break; 7895 case OMPC_ordered: 7896 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 7897 break; 7898 case OMPC_device: 7899 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 7900 break; 7901 case OMPC_num_teams: 7902 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 7903 break; 7904 case OMPC_thread_limit: 7905 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 7906 break; 7907 case OMPC_priority: 7908 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 7909 break; 7910 case OMPC_grainsize: 7911 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 7912 break; 7913 case OMPC_num_tasks: 7914 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 7915 break; 7916 case OMPC_hint: 7917 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 7918 break; 7919 case OMPC_if: 7920 case OMPC_default: 7921 case OMPC_proc_bind: 7922 case OMPC_schedule: 7923 case OMPC_private: 7924 case OMPC_firstprivate: 7925 case OMPC_lastprivate: 7926 case OMPC_shared: 7927 case OMPC_reduction: 7928 case OMPC_task_reduction: 7929 case OMPC_in_reduction: 7930 case OMPC_linear: 7931 case OMPC_aligned: 7932 case OMPC_copyin: 7933 case OMPC_copyprivate: 7934 case OMPC_nowait: 7935 case OMPC_untied: 7936 case OMPC_mergeable: 7937 case OMPC_threadprivate: 7938 case OMPC_flush: 7939 case OMPC_read: 7940 case OMPC_write: 7941 case OMPC_update: 7942 case OMPC_capture: 7943 case OMPC_seq_cst: 7944 case OMPC_depend: 7945 case OMPC_threads: 7946 case OMPC_simd: 7947 case OMPC_map: 7948 case OMPC_nogroup: 7949 case OMPC_dist_schedule: 7950 case OMPC_defaultmap: 7951 case OMPC_unknown: 7952 case OMPC_uniform: 7953 case OMPC_to: 7954 case OMPC_from: 7955 case OMPC_use_device_ptr: 7956 case OMPC_is_device_ptr: 7957 llvm_unreachable("Clause is not allowed."); 7958 } 7959 return Res; 7960 } 7961 7962 // An OpenMP directive such as 'target parallel' has two captured regions: 7963 // for the 'target' and 'parallel' respectively. This function returns 7964 // the region in which to capture expressions associated with a clause. 7965 // A return value of OMPD_unknown signifies that the expression should not 7966 // be captured. 7967 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 7968 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 7969 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 7970 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7971 switch (CKind) { 7972 case OMPC_if: 7973 switch (DKind) { 7974 case OMPD_target_parallel: 7975 case OMPD_target_parallel_for: 7976 case OMPD_target_parallel_for_simd: 7977 // If this clause applies to the nested 'parallel' region, capture within 7978 // the 'target' region, otherwise do not capture. 7979 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 7980 CaptureRegion = OMPD_target; 7981 break; 7982 case OMPD_target_teams_distribute_parallel_for: 7983 case OMPD_target_teams_distribute_parallel_for_simd: 7984 // If this clause applies to the nested 'parallel' region, capture within 7985 // the 'teams' region, otherwise do not capture. 7986 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 7987 CaptureRegion = OMPD_teams; 7988 break; 7989 case OMPD_teams_distribute_parallel_for: 7990 case OMPD_teams_distribute_parallel_for_simd: 7991 CaptureRegion = OMPD_teams; 7992 break; 7993 case OMPD_target_update: 7994 case OMPD_target_enter_data: 7995 case OMPD_target_exit_data: 7996 CaptureRegion = OMPD_task; 7997 break; 7998 case OMPD_cancel: 7999 case OMPD_parallel: 8000 case OMPD_parallel_sections: 8001 case OMPD_parallel_for: 8002 case OMPD_parallel_for_simd: 8003 case OMPD_target: 8004 case OMPD_target_simd: 8005 case OMPD_target_teams: 8006 case OMPD_target_teams_distribute: 8007 case OMPD_target_teams_distribute_simd: 8008 case OMPD_distribute_parallel_for: 8009 case OMPD_distribute_parallel_for_simd: 8010 case OMPD_task: 8011 case OMPD_taskloop: 8012 case OMPD_taskloop_simd: 8013 case OMPD_target_data: 8014 // Do not capture if-clause expressions. 8015 break; 8016 case OMPD_threadprivate: 8017 case OMPD_taskyield: 8018 case OMPD_barrier: 8019 case OMPD_taskwait: 8020 case OMPD_cancellation_point: 8021 case OMPD_flush: 8022 case OMPD_declare_reduction: 8023 case OMPD_declare_simd: 8024 case OMPD_declare_target: 8025 case OMPD_end_declare_target: 8026 case OMPD_teams: 8027 case OMPD_simd: 8028 case OMPD_for: 8029 case OMPD_for_simd: 8030 case OMPD_sections: 8031 case OMPD_section: 8032 case OMPD_single: 8033 case OMPD_master: 8034 case OMPD_critical: 8035 case OMPD_taskgroup: 8036 case OMPD_distribute: 8037 case OMPD_ordered: 8038 case OMPD_atomic: 8039 case OMPD_distribute_simd: 8040 case OMPD_teams_distribute: 8041 case OMPD_teams_distribute_simd: 8042 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 8043 case OMPD_unknown: 8044 llvm_unreachable("Unknown OpenMP directive"); 8045 } 8046 break; 8047 case OMPC_num_threads: 8048 switch (DKind) { 8049 case OMPD_target_parallel: 8050 case OMPD_target_parallel_for: 8051 case OMPD_target_parallel_for_simd: 8052 CaptureRegion = OMPD_target; 8053 break; 8054 case OMPD_teams_distribute_parallel_for: 8055 case OMPD_teams_distribute_parallel_for_simd: 8056 case OMPD_target_teams_distribute_parallel_for: 8057 case OMPD_target_teams_distribute_parallel_for_simd: 8058 CaptureRegion = OMPD_teams; 8059 break; 8060 case OMPD_parallel: 8061 case OMPD_parallel_sections: 8062 case OMPD_parallel_for: 8063 case OMPD_parallel_for_simd: 8064 case OMPD_distribute_parallel_for: 8065 case OMPD_distribute_parallel_for_simd: 8066 // Do not capture num_threads-clause expressions. 8067 break; 8068 case OMPD_target_data: 8069 case OMPD_target_enter_data: 8070 case OMPD_target_exit_data: 8071 case OMPD_target_update: 8072 case OMPD_target: 8073 case OMPD_target_simd: 8074 case OMPD_target_teams: 8075 case OMPD_target_teams_distribute: 8076 case OMPD_target_teams_distribute_simd: 8077 case OMPD_cancel: 8078 case OMPD_task: 8079 case OMPD_taskloop: 8080 case OMPD_taskloop_simd: 8081 case OMPD_threadprivate: 8082 case OMPD_taskyield: 8083 case OMPD_barrier: 8084 case OMPD_taskwait: 8085 case OMPD_cancellation_point: 8086 case OMPD_flush: 8087 case OMPD_declare_reduction: 8088 case OMPD_declare_simd: 8089 case OMPD_declare_target: 8090 case OMPD_end_declare_target: 8091 case OMPD_teams: 8092 case OMPD_simd: 8093 case OMPD_for: 8094 case OMPD_for_simd: 8095 case OMPD_sections: 8096 case OMPD_section: 8097 case OMPD_single: 8098 case OMPD_master: 8099 case OMPD_critical: 8100 case OMPD_taskgroup: 8101 case OMPD_distribute: 8102 case OMPD_ordered: 8103 case OMPD_atomic: 8104 case OMPD_distribute_simd: 8105 case OMPD_teams_distribute: 8106 case OMPD_teams_distribute_simd: 8107 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 8108 case OMPD_unknown: 8109 llvm_unreachable("Unknown OpenMP directive"); 8110 } 8111 break; 8112 case OMPC_num_teams: 8113 switch (DKind) { 8114 case OMPD_target_teams: 8115 case OMPD_target_teams_distribute: 8116 case OMPD_target_teams_distribute_simd: 8117 case OMPD_target_teams_distribute_parallel_for: 8118 case OMPD_target_teams_distribute_parallel_for_simd: 8119 CaptureRegion = OMPD_target; 8120 break; 8121 case OMPD_teams_distribute_parallel_for: 8122 case OMPD_teams_distribute_parallel_for_simd: 8123 case OMPD_teams: 8124 case OMPD_teams_distribute: 8125 case OMPD_teams_distribute_simd: 8126 // Do not capture num_teams-clause expressions. 8127 break; 8128 case OMPD_distribute_parallel_for: 8129 case OMPD_distribute_parallel_for_simd: 8130 case OMPD_task: 8131 case OMPD_taskloop: 8132 case OMPD_taskloop_simd: 8133 case OMPD_target_data: 8134 case OMPD_target_enter_data: 8135 case OMPD_target_exit_data: 8136 case OMPD_target_update: 8137 case OMPD_cancel: 8138 case OMPD_parallel: 8139 case OMPD_parallel_sections: 8140 case OMPD_parallel_for: 8141 case OMPD_parallel_for_simd: 8142 case OMPD_target: 8143 case OMPD_target_simd: 8144 case OMPD_target_parallel: 8145 case OMPD_target_parallel_for: 8146 case OMPD_target_parallel_for_simd: 8147 case OMPD_threadprivate: 8148 case OMPD_taskyield: 8149 case OMPD_barrier: 8150 case OMPD_taskwait: 8151 case OMPD_cancellation_point: 8152 case OMPD_flush: 8153 case OMPD_declare_reduction: 8154 case OMPD_declare_simd: 8155 case OMPD_declare_target: 8156 case OMPD_end_declare_target: 8157 case OMPD_simd: 8158 case OMPD_for: 8159 case OMPD_for_simd: 8160 case OMPD_sections: 8161 case OMPD_section: 8162 case OMPD_single: 8163 case OMPD_master: 8164 case OMPD_critical: 8165 case OMPD_taskgroup: 8166 case OMPD_distribute: 8167 case OMPD_ordered: 8168 case OMPD_atomic: 8169 case OMPD_distribute_simd: 8170 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8171 case OMPD_unknown: 8172 llvm_unreachable("Unknown OpenMP directive"); 8173 } 8174 break; 8175 case OMPC_thread_limit: 8176 switch (DKind) { 8177 case OMPD_target_teams: 8178 case OMPD_target_teams_distribute: 8179 case OMPD_target_teams_distribute_simd: 8180 case OMPD_target_teams_distribute_parallel_for: 8181 case OMPD_target_teams_distribute_parallel_for_simd: 8182 CaptureRegion = OMPD_target; 8183 break; 8184 case OMPD_teams_distribute_parallel_for: 8185 case OMPD_teams_distribute_parallel_for_simd: 8186 case OMPD_teams: 8187 case OMPD_teams_distribute: 8188 case OMPD_teams_distribute_simd: 8189 // Do not capture thread_limit-clause expressions. 8190 break; 8191 case OMPD_distribute_parallel_for: 8192 case OMPD_distribute_parallel_for_simd: 8193 case OMPD_task: 8194 case OMPD_taskloop: 8195 case OMPD_taskloop_simd: 8196 case OMPD_target_data: 8197 case OMPD_target_enter_data: 8198 case OMPD_target_exit_data: 8199 case OMPD_target_update: 8200 case OMPD_cancel: 8201 case OMPD_parallel: 8202 case OMPD_parallel_sections: 8203 case OMPD_parallel_for: 8204 case OMPD_parallel_for_simd: 8205 case OMPD_target: 8206 case OMPD_target_simd: 8207 case OMPD_target_parallel: 8208 case OMPD_target_parallel_for: 8209 case OMPD_target_parallel_for_simd: 8210 case OMPD_threadprivate: 8211 case OMPD_taskyield: 8212 case OMPD_barrier: 8213 case OMPD_taskwait: 8214 case OMPD_cancellation_point: 8215 case OMPD_flush: 8216 case OMPD_declare_reduction: 8217 case OMPD_declare_simd: 8218 case OMPD_declare_target: 8219 case OMPD_end_declare_target: 8220 case OMPD_simd: 8221 case OMPD_for: 8222 case OMPD_for_simd: 8223 case OMPD_sections: 8224 case OMPD_section: 8225 case OMPD_single: 8226 case OMPD_master: 8227 case OMPD_critical: 8228 case OMPD_taskgroup: 8229 case OMPD_distribute: 8230 case OMPD_ordered: 8231 case OMPD_atomic: 8232 case OMPD_distribute_simd: 8233 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 8234 case OMPD_unknown: 8235 llvm_unreachable("Unknown OpenMP directive"); 8236 } 8237 break; 8238 case OMPC_schedule: 8239 switch (DKind) { 8240 case OMPD_parallel_for: 8241 case OMPD_parallel_for_simd: 8242 case OMPD_distribute_parallel_for: 8243 case OMPD_distribute_parallel_for_simd: 8244 case OMPD_teams_distribute_parallel_for: 8245 case OMPD_teams_distribute_parallel_for_simd: 8246 case OMPD_target_parallel_for: 8247 case OMPD_target_parallel_for_simd: 8248 case OMPD_target_teams_distribute_parallel_for: 8249 case OMPD_target_teams_distribute_parallel_for_simd: 8250 CaptureRegion = OMPD_parallel; 8251 break; 8252 case OMPD_for: 8253 case OMPD_for_simd: 8254 // Do not capture schedule-clause expressions. 8255 break; 8256 case OMPD_task: 8257 case OMPD_taskloop: 8258 case OMPD_taskloop_simd: 8259 case OMPD_target_data: 8260 case OMPD_target_enter_data: 8261 case OMPD_target_exit_data: 8262 case OMPD_target_update: 8263 case OMPD_teams: 8264 case OMPD_teams_distribute: 8265 case OMPD_teams_distribute_simd: 8266 case OMPD_target_teams_distribute: 8267 case OMPD_target_teams_distribute_simd: 8268 case OMPD_target: 8269 case OMPD_target_simd: 8270 case OMPD_target_parallel: 8271 case OMPD_cancel: 8272 case OMPD_parallel: 8273 case OMPD_parallel_sections: 8274 case OMPD_threadprivate: 8275 case OMPD_taskyield: 8276 case OMPD_barrier: 8277 case OMPD_taskwait: 8278 case OMPD_cancellation_point: 8279 case OMPD_flush: 8280 case OMPD_declare_reduction: 8281 case OMPD_declare_simd: 8282 case OMPD_declare_target: 8283 case OMPD_end_declare_target: 8284 case OMPD_simd: 8285 case OMPD_sections: 8286 case OMPD_section: 8287 case OMPD_single: 8288 case OMPD_master: 8289 case OMPD_critical: 8290 case OMPD_taskgroup: 8291 case OMPD_distribute: 8292 case OMPD_ordered: 8293 case OMPD_atomic: 8294 case OMPD_distribute_simd: 8295 case OMPD_target_teams: 8296 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8297 case OMPD_unknown: 8298 llvm_unreachable("Unknown OpenMP directive"); 8299 } 8300 break; 8301 case OMPC_dist_schedule: 8302 switch (DKind) { 8303 case OMPD_teams_distribute_parallel_for: 8304 case OMPD_teams_distribute_parallel_for_simd: 8305 case OMPD_teams_distribute: 8306 case OMPD_teams_distribute_simd: 8307 case OMPD_target_teams_distribute_parallel_for: 8308 case OMPD_target_teams_distribute_parallel_for_simd: 8309 case OMPD_target_teams_distribute: 8310 case OMPD_target_teams_distribute_simd: 8311 CaptureRegion = OMPD_teams; 8312 break; 8313 case OMPD_distribute_parallel_for: 8314 case OMPD_distribute_parallel_for_simd: 8315 case OMPD_distribute: 8316 case OMPD_distribute_simd: 8317 // Do not capture thread_limit-clause expressions. 8318 break; 8319 case OMPD_parallel_for: 8320 case OMPD_parallel_for_simd: 8321 case OMPD_target_parallel_for_simd: 8322 case OMPD_target_parallel_for: 8323 case OMPD_task: 8324 case OMPD_taskloop: 8325 case OMPD_taskloop_simd: 8326 case OMPD_target_data: 8327 case OMPD_target_enter_data: 8328 case OMPD_target_exit_data: 8329 case OMPD_target_update: 8330 case OMPD_teams: 8331 case OMPD_target: 8332 case OMPD_target_simd: 8333 case OMPD_target_parallel: 8334 case OMPD_cancel: 8335 case OMPD_parallel: 8336 case OMPD_parallel_sections: 8337 case OMPD_threadprivate: 8338 case OMPD_taskyield: 8339 case OMPD_barrier: 8340 case OMPD_taskwait: 8341 case OMPD_cancellation_point: 8342 case OMPD_flush: 8343 case OMPD_declare_reduction: 8344 case OMPD_declare_simd: 8345 case OMPD_declare_target: 8346 case OMPD_end_declare_target: 8347 case OMPD_simd: 8348 case OMPD_for: 8349 case OMPD_for_simd: 8350 case OMPD_sections: 8351 case OMPD_section: 8352 case OMPD_single: 8353 case OMPD_master: 8354 case OMPD_critical: 8355 case OMPD_taskgroup: 8356 case OMPD_ordered: 8357 case OMPD_atomic: 8358 case OMPD_target_teams: 8359 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8360 case OMPD_unknown: 8361 llvm_unreachable("Unknown OpenMP directive"); 8362 } 8363 break; 8364 case OMPC_device: 8365 switch (DKind) { 8366 case OMPD_target_update: 8367 case OMPD_target_enter_data: 8368 case OMPD_target_exit_data: 8369 case OMPD_target: 8370 case OMPD_target_simd: 8371 case OMPD_target_teams: 8372 case OMPD_target_parallel: 8373 case OMPD_target_teams_distribute: 8374 case OMPD_target_teams_distribute_simd: 8375 case OMPD_target_parallel_for: 8376 case OMPD_target_parallel_for_simd: 8377 case OMPD_target_teams_distribute_parallel_for: 8378 case OMPD_target_teams_distribute_parallel_for_simd: 8379 CaptureRegion = OMPD_task; 8380 break; 8381 case OMPD_target_data: 8382 // Do not capture device-clause expressions. 8383 break; 8384 case OMPD_teams_distribute_parallel_for: 8385 case OMPD_teams_distribute_parallel_for_simd: 8386 case OMPD_teams: 8387 case OMPD_teams_distribute: 8388 case OMPD_teams_distribute_simd: 8389 case OMPD_distribute_parallel_for: 8390 case OMPD_distribute_parallel_for_simd: 8391 case OMPD_task: 8392 case OMPD_taskloop: 8393 case OMPD_taskloop_simd: 8394 case OMPD_cancel: 8395 case OMPD_parallel: 8396 case OMPD_parallel_sections: 8397 case OMPD_parallel_for: 8398 case OMPD_parallel_for_simd: 8399 case OMPD_threadprivate: 8400 case OMPD_taskyield: 8401 case OMPD_barrier: 8402 case OMPD_taskwait: 8403 case OMPD_cancellation_point: 8404 case OMPD_flush: 8405 case OMPD_declare_reduction: 8406 case OMPD_declare_simd: 8407 case OMPD_declare_target: 8408 case OMPD_end_declare_target: 8409 case OMPD_simd: 8410 case OMPD_for: 8411 case OMPD_for_simd: 8412 case OMPD_sections: 8413 case OMPD_section: 8414 case OMPD_single: 8415 case OMPD_master: 8416 case OMPD_critical: 8417 case OMPD_taskgroup: 8418 case OMPD_distribute: 8419 case OMPD_ordered: 8420 case OMPD_atomic: 8421 case OMPD_distribute_simd: 8422 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8423 case OMPD_unknown: 8424 llvm_unreachable("Unknown OpenMP directive"); 8425 } 8426 break; 8427 case OMPC_firstprivate: 8428 case OMPC_lastprivate: 8429 case OMPC_reduction: 8430 case OMPC_task_reduction: 8431 case OMPC_in_reduction: 8432 case OMPC_linear: 8433 case OMPC_default: 8434 case OMPC_proc_bind: 8435 case OMPC_final: 8436 case OMPC_safelen: 8437 case OMPC_simdlen: 8438 case OMPC_collapse: 8439 case OMPC_private: 8440 case OMPC_shared: 8441 case OMPC_aligned: 8442 case OMPC_copyin: 8443 case OMPC_copyprivate: 8444 case OMPC_ordered: 8445 case OMPC_nowait: 8446 case OMPC_untied: 8447 case OMPC_mergeable: 8448 case OMPC_threadprivate: 8449 case OMPC_flush: 8450 case OMPC_read: 8451 case OMPC_write: 8452 case OMPC_update: 8453 case OMPC_capture: 8454 case OMPC_seq_cst: 8455 case OMPC_depend: 8456 case OMPC_threads: 8457 case OMPC_simd: 8458 case OMPC_map: 8459 case OMPC_priority: 8460 case OMPC_grainsize: 8461 case OMPC_nogroup: 8462 case OMPC_num_tasks: 8463 case OMPC_hint: 8464 case OMPC_defaultmap: 8465 case OMPC_unknown: 8466 case OMPC_uniform: 8467 case OMPC_to: 8468 case OMPC_from: 8469 case OMPC_use_device_ptr: 8470 case OMPC_is_device_ptr: 8471 llvm_unreachable("Unexpected OpenMP clause."); 8472 } 8473 return CaptureRegion; 8474 } 8475 8476 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 8477 Expr *Condition, SourceLocation StartLoc, 8478 SourceLocation LParenLoc, 8479 SourceLocation NameModifierLoc, 8480 SourceLocation ColonLoc, 8481 SourceLocation EndLoc) { 8482 Expr *ValExpr = Condition; 8483 Stmt *HelperValStmt = nullptr; 8484 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8485 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 8486 !Condition->isInstantiationDependent() && 8487 !Condition->containsUnexpandedParameterPack()) { 8488 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 8489 if (Val.isInvalid()) 8490 return nullptr; 8491 8492 ValExpr = Val.get(); 8493 8494 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8495 CaptureRegion = 8496 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 8497 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 8498 ValExpr = MakeFullExpr(ValExpr).get(); 8499 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8500 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8501 HelperValStmt = buildPreInits(Context, Captures); 8502 } 8503 } 8504 8505 return new (Context) 8506 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 8507 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 8508 } 8509 8510 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 8511 SourceLocation StartLoc, 8512 SourceLocation LParenLoc, 8513 SourceLocation EndLoc) { 8514 Expr *ValExpr = Condition; 8515 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 8516 !Condition->isInstantiationDependent() && 8517 !Condition->containsUnexpandedParameterPack()) { 8518 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 8519 if (Val.isInvalid()) 8520 return nullptr; 8521 8522 ValExpr = MakeFullExpr(Val.get()).get(); 8523 } 8524 8525 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 8526 } 8527 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 8528 Expr *Op) { 8529 if (!Op) 8530 return ExprError(); 8531 8532 class IntConvertDiagnoser : public ICEConvertDiagnoser { 8533 public: 8534 IntConvertDiagnoser() 8535 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 8536 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 8537 QualType T) override { 8538 return S.Diag(Loc, diag::err_omp_not_integral) << T; 8539 } 8540 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 8541 QualType T) override { 8542 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 8543 } 8544 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 8545 QualType T, 8546 QualType ConvTy) override { 8547 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 8548 } 8549 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 8550 QualType ConvTy) override { 8551 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 8552 << ConvTy->isEnumeralType() << ConvTy; 8553 } 8554 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 8555 QualType T) override { 8556 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 8557 } 8558 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 8559 QualType ConvTy) override { 8560 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 8561 << ConvTy->isEnumeralType() << ConvTy; 8562 } 8563 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 8564 QualType) override { 8565 llvm_unreachable("conversion functions are permitted"); 8566 } 8567 } ConvertDiagnoser; 8568 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 8569 } 8570 8571 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 8572 OpenMPClauseKind CKind, 8573 bool StrictlyPositive) { 8574 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 8575 !ValExpr->isInstantiationDependent()) { 8576 SourceLocation Loc = ValExpr->getExprLoc(); 8577 ExprResult Value = 8578 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 8579 if (Value.isInvalid()) 8580 return false; 8581 8582 ValExpr = Value.get(); 8583 // The expression must evaluate to a non-negative integer value. 8584 llvm::APSInt Result; 8585 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 8586 Result.isSigned() && 8587 !((!StrictlyPositive && Result.isNonNegative()) || 8588 (StrictlyPositive && Result.isStrictlyPositive()))) { 8589 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 8590 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 8591 << ValExpr->getSourceRange(); 8592 return false; 8593 } 8594 } 8595 return true; 8596 } 8597 8598 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 8599 SourceLocation StartLoc, 8600 SourceLocation LParenLoc, 8601 SourceLocation EndLoc) { 8602 Expr *ValExpr = NumThreads; 8603 Stmt *HelperValStmt = nullptr; 8604 8605 // OpenMP [2.5, Restrictions] 8606 // The num_threads expression must evaluate to a positive integer value. 8607 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 8608 /*StrictlyPositive=*/true)) 8609 return nullptr; 8610 8611 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8612 OpenMPDirectiveKind CaptureRegion = 8613 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 8614 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 8615 ValExpr = MakeFullExpr(ValExpr).get(); 8616 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8617 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8618 HelperValStmt = buildPreInits(Context, Captures); 8619 } 8620 8621 return new (Context) OMPNumThreadsClause( 8622 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 8623 } 8624 8625 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 8626 OpenMPClauseKind CKind, 8627 bool StrictlyPositive) { 8628 if (!E) 8629 return ExprError(); 8630 if (E->isValueDependent() || E->isTypeDependent() || 8631 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 8632 return E; 8633 llvm::APSInt Result; 8634 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 8635 if (ICE.isInvalid()) 8636 return ExprError(); 8637 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 8638 (!StrictlyPositive && !Result.isNonNegative())) { 8639 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 8640 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 8641 << E->getSourceRange(); 8642 return ExprError(); 8643 } 8644 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 8645 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 8646 << E->getSourceRange(); 8647 return ExprError(); 8648 } 8649 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 8650 DSAStack->setAssociatedLoops(Result.getExtValue()); 8651 else if (CKind == OMPC_ordered) 8652 DSAStack->setAssociatedLoops(Result.getExtValue()); 8653 return ICE; 8654 } 8655 8656 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 8657 SourceLocation LParenLoc, 8658 SourceLocation EndLoc) { 8659 // OpenMP [2.8.1, simd construct, Description] 8660 // The parameter of the safelen clause must be a constant 8661 // positive integer expression. 8662 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 8663 if (Safelen.isInvalid()) 8664 return nullptr; 8665 return new (Context) 8666 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 8667 } 8668 8669 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 8670 SourceLocation LParenLoc, 8671 SourceLocation EndLoc) { 8672 // OpenMP [2.8.1, simd construct, Description] 8673 // The parameter of the simdlen clause must be a constant 8674 // positive integer expression. 8675 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 8676 if (Simdlen.isInvalid()) 8677 return nullptr; 8678 return new (Context) 8679 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 8680 } 8681 8682 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 8683 SourceLocation StartLoc, 8684 SourceLocation LParenLoc, 8685 SourceLocation EndLoc) { 8686 // OpenMP [2.7.1, loop construct, Description] 8687 // OpenMP [2.8.1, simd construct, Description] 8688 // OpenMP [2.9.6, distribute construct, Description] 8689 // The parameter of the collapse clause must be a constant 8690 // positive integer expression. 8691 ExprResult NumForLoopsResult = 8692 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 8693 if (NumForLoopsResult.isInvalid()) 8694 return nullptr; 8695 return new (Context) 8696 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 8697 } 8698 8699 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 8700 SourceLocation EndLoc, 8701 SourceLocation LParenLoc, 8702 Expr *NumForLoops) { 8703 // OpenMP [2.7.1, loop construct, Description] 8704 // OpenMP [2.8.1, simd construct, Description] 8705 // OpenMP [2.9.6, distribute construct, Description] 8706 // The parameter of the ordered clause must be a constant 8707 // positive integer expression if any. 8708 if (NumForLoops && LParenLoc.isValid()) { 8709 ExprResult NumForLoopsResult = 8710 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 8711 if (NumForLoopsResult.isInvalid()) 8712 return nullptr; 8713 NumForLoops = NumForLoopsResult.get(); 8714 } else { 8715 NumForLoops = nullptr; 8716 } 8717 auto *Clause = OMPOrderedClause::Create( 8718 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 8719 StartLoc, LParenLoc, EndLoc); 8720 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 8721 return Clause; 8722 } 8723 8724 OMPClause *Sema::ActOnOpenMPSimpleClause( 8725 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 8726 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 8727 OMPClause *Res = nullptr; 8728 switch (Kind) { 8729 case OMPC_default: 8730 Res = 8731 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 8732 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 8733 break; 8734 case OMPC_proc_bind: 8735 Res = ActOnOpenMPProcBindClause( 8736 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 8737 LParenLoc, EndLoc); 8738 break; 8739 case OMPC_if: 8740 case OMPC_final: 8741 case OMPC_num_threads: 8742 case OMPC_safelen: 8743 case OMPC_simdlen: 8744 case OMPC_collapse: 8745 case OMPC_schedule: 8746 case OMPC_private: 8747 case OMPC_firstprivate: 8748 case OMPC_lastprivate: 8749 case OMPC_shared: 8750 case OMPC_reduction: 8751 case OMPC_task_reduction: 8752 case OMPC_in_reduction: 8753 case OMPC_linear: 8754 case OMPC_aligned: 8755 case OMPC_copyin: 8756 case OMPC_copyprivate: 8757 case OMPC_ordered: 8758 case OMPC_nowait: 8759 case OMPC_untied: 8760 case OMPC_mergeable: 8761 case OMPC_threadprivate: 8762 case OMPC_flush: 8763 case OMPC_read: 8764 case OMPC_write: 8765 case OMPC_update: 8766 case OMPC_capture: 8767 case OMPC_seq_cst: 8768 case OMPC_depend: 8769 case OMPC_device: 8770 case OMPC_threads: 8771 case OMPC_simd: 8772 case OMPC_map: 8773 case OMPC_num_teams: 8774 case OMPC_thread_limit: 8775 case OMPC_priority: 8776 case OMPC_grainsize: 8777 case OMPC_nogroup: 8778 case OMPC_num_tasks: 8779 case OMPC_hint: 8780 case OMPC_dist_schedule: 8781 case OMPC_defaultmap: 8782 case OMPC_unknown: 8783 case OMPC_uniform: 8784 case OMPC_to: 8785 case OMPC_from: 8786 case OMPC_use_device_ptr: 8787 case OMPC_is_device_ptr: 8788 llvm_unreachable("Clause is not allowed."); 8789 } 8790 return Res; 8791 } 8792 8793 static std::string 8794 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 8795 ArrayRef<unsigned> Exclude = llvm::None) { 8796 SmallString<256> Buffer; 8797 llvm::raw_svector_ostream Out(Buffer); 8798 unsigned Bound = Last >= 2 ? Last - 2 : 0; 8799 unsigned Skipped = Exclude.size(); 8800 auto S = Exclude.begin(), E = Exclude.end(); 8801 for (unsigned I = First; I < Last; ++I) { 8802 if (std::find(S, E, I) != E) { 8803 --Skipped; 8804 continue; 8805 } 8806 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 8807 if (I == Bound - Skipped) 8808 Out << " or "; 8809 else if (I != Bound + 1 - Skipped) 8810 Out << ", "; 8811 } 8812 return Out.str(); 8813 } 8814 8815 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 8816 SourceLocation KindKwLoc, 8817 SourceLocation StartLoc, 8818 SourceLocation LParenLoc, 8819 SourceLocation EndLoc) { 8820 if (Kind == OMPC_DEFAULT_unknown) { 8821 static_assert(OMPC_DEFAULT_unknown > 0, 8822 "OMPC_DEFAULT_unknown not greater than 0"); 8823 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 8824 << getListOfPossibleValues(OMPC_default, /*First=*/0, 8825 /*Last=*/OMPC_DEFAULT_unknown) 8826 << getOpenMPClauseName(OMPC_default); 8827 return nullptr; 8828 } 8829 switch (Kind) { 8830 case OMPC_DEFAULT_none: 8831 DSAStack->setDefaultDSANone(KindKwLoc); 8832 break; 8833 case OMPC_DEFAULT_shared: 8834 DSAStack->setDefaultDSAShared(KindKwLoc); 8835 break; 8836 case OMPC_DEFAULT_unknown: 8837 llvm_unreachable("Clause kind is not allowed."); 8838 break; 8839 } 8840 return new (Context) 8841 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 8842 } 8843 8844 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 8845 SourceLocation KindKwLoc, 8846 SourceLocation StartLoc, 8847 SourceLocation LParenLoc, 8848 SourceLocation EndLoc) { 8849 if (Kind == OMPC_PROC_BIND_unknown) { 8850 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 8851 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 8852 /*Last=*/OMPC_PROC_BIND_unknown) 8853 << getOpenMPClauseName(OMPC_proc_bind); 8854 return nullptr; 8855 } 8856 return new (Context) 8857 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 8858 } 8859 8860 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 8861 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 8862 SourceLocation StartLoc, SourceLocation LParenLoc, 8863 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 8864 SourceLocation EndLoc) { 8865 OMPClause *Res = nullptr; 8866 switch (Kind) { 8867 case OMPC_schedule: 8868 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 8869 assert(Argument.size() == NumberOfElements && 8870 ArgumentLoc.size() == NumberOfElements); 8871 Res = ActOnOpenMPScheduleClause( 8872 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 8873 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 8874 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 8875 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 8876 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 8877 break; 8878 case OMPC_if: 8879 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 8880 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 8881 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 8882 DelimLoc, EndLoc); 8883 break; 8884 case OMPC_dist_schedule: 8885 Res = ActOnOpenMPDistScheduleClause( 8886 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 8887 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 8888 break; 8889 case OMPC_defaultmap: 8890 enum { Modifier, DefaultmapKind }; 8891 Res = ActOnOpenMPDefaultmapClause( 8892 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 8893 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 8894 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 8895 EndLoc); 8896 break; 8897 case OMPC_final: 8898 case OMPC_num_threads: 8899 case OMPC_safelen: 8900 case OMPC_simdlen: 8901 case OMPC_collapse: 8902 case OMPC_default: 8903 case OMPC_proc_bind: 8904 case OMPC_private: 8905 case OMPC_firstprivate: 8906 case OMPC_lastprivate: 8907 case OMPC_shared: 8908 case OMPC_reduction: 8909 case OMPC_task_reduction: 8910 case OMPC_in_reduction: 8911 case OMPC_linear: 8912 case OMPC_aligned: 8913 case OMPC_copyin: 8914 case OMPC_copyprivate: 8915 case OMPC_ordered: 8916 case OMPC_nowait: 8917 case OMPC_untied: 8918 case OMPC_mergeable: 8919 case OMPC_threadprivate: 8920 case OMPC_flush: 8921 case OMPC_read: 8922 case OMPC_write: 8923 case OMPC_update: 8924 case OMPC_capture: 8925 case OMPC_seq_cst: 8926 case OMPC_depend: 8927 case OMPC_device: 8928 case OMPC_threads: 8929 case OMPC_simd: 8930 case OMPC_map: 8931 case OMPC_num_teams: 8932 case OMPC_thread_limit: 8933 case OMPC_priority: 8934 case OMPC_grainsize: 8935 case OMPC_nogroup: 8936 case OMPC_num_tasks: 8937 case OMPC_hint: 8938 case OMPC_unknown: 8939 case OMPC_uniform: 8940 case OMPC_to: 8941 case OMPC_from: 8942 case OMPC_use_device_ptr: 8943 case OMPC_is_device_ptr: 8944 llvm_unreachable("Clause is not allowed."); 8945 } 8946 return Res; 8947 } 8948 8949 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 8950 OpenMPScheduleClauseModifier M2, 8951 SourceLocation M1Loc, SourceLocation M2Loc) { 8952 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 8953 SmallVector<unsigned, 2> Excluded; 8954 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 8955 Excluded.push_back(M2); 8956 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 8957 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 8958 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 8959 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 8960 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 8961 << getListOfPossibleValues(OMPC_schedule, 8962 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 8963 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8964 Excluded) 8965 << getOpenMPClauseName(OMPC_schedule); 8966 return true; 8967 } 8968 return false; 8969 } 8970 8971 OMPClause *Sema::ActOnOpenMPScheduleClause( 8972 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 8973 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 8974 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 8975 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 8976 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 8977 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 8978 return nullptr; 8979 // OpenMP, 2.7.1, Loop Construct, Restrictions 8980 // Either the monotonic modifier or the nonmonotonic modifier can be specified 8981 // but not both. 8982 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 8983 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 8984 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 8985 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 8986 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 8987 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 8988 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 8989 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 8990 return nullptr; 8991 } 8992 if (Kind == OMPC_SCHEDULE_unknown) { 8993 std::string Values; 8994 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 8995 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 8996 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8997 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8998 Exclude); 8999 } else { 9000 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9001 /*Last=*/OMPC_SCHEDULE_unknown); 9002 } 9003 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 9004 << Values << getOpenMPClauseName(OMPC_schedule); 9005 return nullptr; 9006 } 9007 // OpenMP, 2.7.1, Loop Construct, Restrictions 9008 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 9009 // schedule(guided). 9010 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 9011 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 9012 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 9013 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 9014 diag::err_omp_schedule_nonmonotonic_static); 9015 return nullptr; 9016 } 9017 Expr *ValExpr = ChunkSize; 9018 Stmt *HelperValStmt = nullptr; 9019 if (ChunkSize) { 9020 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 9021 !ChunkSize->isInstantiationDependent() && 9022 !ChunkSize->containsUnexpandedParameterPack()) { 9023 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 9024 ExprResult Val = 9025 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 9026 if (Val.isInvalid()) 9027 return nullptr; 9028 9029 ValExpr = Val.get(); 9030 9031 // OpenMP [2.7.1, Restrictions] 9032 // chunk_size must be a loop invariant integer expression with a positive 9033 // value. 9034 llvm::APSInt Result; 9035 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 9036 if (Result.isSigned() && !Result.isStrictlyPositive()) { 9037 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 9038 << "schedule" << 1 << ChunkSize->getSourceRange(); 9039 return nullptr; 9040 } 9041 } else if (getOpenMPCaptureRegionForClause( 9042 DSAStack->getCurrentDirective(), OMPC_schedule) != 9043 OMPD_unknown && 9044 !CurContext->isDependentContext()) { 9045 ValExpr = MakeFullExpr(ValExpr).get(); 9046 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9047 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9048 HelperValStmt = buildPreInits(Context, Captures); 9049 } 9050 } 9051 } 9052 9053 return new (Context) 9054 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 9055 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 9056 } 9057 9058 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 9059 SourceLocation StartLoc, 9060 SourceLocation EndLoc) { 9061 OMPClause *Res = nullptr; 9062 switch (Kind) { 9063 case OMPC_ordered: 9064 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 9065 break; 9066 case OMPC_nowait: 9067 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 9068 break; 9069 case OMPC_untied: 9070 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 9071 break; 9072 case OMPC_mergeable: 9073 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 9074 break; 9075 case OMPC_read: 9076 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 9077 break; 9078 case OMPC_write: 9079 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 9080 break; 9081 case OMPC_update: 9082 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 9083 break; 9084 case OMPC_capture: 9085 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 9086 break; 9087 case OMPC_seq_cst: 9088 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 9089 break; 9090 case OMPC_threads: 9091 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 9092 break; 9093 case OMPC_simd: 9094 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 9095 break; 9096 case OMPC_nogroup: 9097 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 9098 break; 9099 case OMPC_if: 9100 case OMPC_final: 9101 case OMPC_num_threads: 9102 case OMPC_safelen: 9103 case OMPC_simdlen: 9104 case OMPC_collapse: 9105 case OMPC_schedule: 9106 case OMPC_private: 9107 case OMPC_firstprivate: 9108 case OMPC_lastprivate: 9109 case OMPC_shared: 9110 case OMPC_reduction: 9111 case OMPC_task_reduction: 9112 case OMPC_in_reduction: 9113 case OMPC_linear: 9114 case OMPC_aligned: 9115 case OMPC_copyin: 9116 case OMPC_copyprivate: 9117 case OMPC_default: 9118 case OMPC_proc_bind: 9119 case OMPC_threadprivate: 9120 case OMPC_flush: 9121 case OMPC_depend: 9122 case OMPC_device: 9123 case OMPC_map: 9124 case OMPC_num_teams: 9125 case OMPC_thread_limit: 9126 case OMPC_priority: 9127 case OMPC_grainsize: 9128 case OMPC_num_tasks: 9129 case OMPC_hint: 9130 case OMPC_dist_schedule: 9131 case OMPC_defaultmap: 9132 case OMPC_unknown: 9133 case OMPC_uniform: 9134 case OMPC_to: 9135 case OMPC_from: 9136 case OMPC_use_device_ptr: 9137 case OMPC_is_device_ptr: 9138 llvm_unreachable("Clause is not allowed."); 9139 } 9140 return Res; 9141 } 9142 9143 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 9144 SourceLocation EndLoc) { 9145 DSAStack->setNowaitRegion(); 9146 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 9147 } 9148 9149 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 9150 SourceLocation EndLoc) { 9151 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 9152 } 9153 9154 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 9155 SourceLocation EndLoc) { 9156 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 9157 } 9158 9159 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 9160 SourceLocation EndLoc) { 9161 return new (Context) OMPReadClause(StartLoc, EndLoc); 9162 } 9163 9164 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 9165 SourceLocation EndLoc) { 9166 return new (Context) OMPWriteClause(StartLoc, EndLoc); 9167 } 9168 9169 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 9170 SourceLocation EndLoc) { 9171 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 9172 } 9173 9174 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 9175 SourceLocation EndLoc) { 9176 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 9177 } 9178 9179 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 9180 SourceLocation EndLoc) { 9181 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 9182 } 9183 9184 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 9185 SourceLocation EndLoc) { 9186 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 9187 } 9188 9189 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 9190 SourceLocation EndLoc) { 9191 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 9192 } 9193 9194 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 9195 SourceLocation EndLoc) { 9196 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 9197 } 9198 9199 OMPClause *Sema::ActOnOpenMPVarListClause( 9200 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 9201 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 9202 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 9203 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 9204 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 9205 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 9206 SourceLocation DepLinMapLoc) { 9207 OMPClause *Res = nullptr; 9208 switch (Kind) { 9209 case OMPC_private: 9210 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9211 break; 9212 case OMPC_firstprivate: 9213 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9214 break; 9215 case OMPC_lastprivate: 9216 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9217 break; 9218 case OMPC_shared: 9219 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 9220 break; 9221 case OMPC_reduction: 9222 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9223 EndLoc, ReductionIdScopeSpec, ReductionId); 9224 break; 9225 case OMPC_task_reduction: 9226 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9227 EndLoc, ReductionIdScopeSpec, 9228 ReductionId); 9229 break; 9230 case OMPC_in_reduction: 9231 Res = 9232 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9233 EndLoc, ReductionIdScopeSpec, ReductionId); 9234 break; 9235 case OMPC_linear: 9236 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 9237 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 9238 break; 9239 case OMPC_aligned: 9240 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 9241 ColonLoc, EndLoc); 9242 break; 9243 case OMPC_copyin: 9244 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 9245 break; 9246 case OMPC_copyprivate: 9247 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9248 break; 9249 case OMPC_flush: 9250 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 9251 break; 9252 case OMPC_depend: 9253 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 9254 StartLoc, LParenLoc, EndLoc); 9255 break; 9256 case OMPC_map: 9257 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 9258 DepLinMapLoc, ColonLoc, VarList, StartLoc, 9259 LParenLoc, EndLoc); 9260 break; 9261 case OMPC_to: 9262 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 9263 break; 9264 case OMPC_from: 9265 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 9266 break; 9267 case OMPC_use_device_ptr: 9268 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 9269 break; 9270 case OMPC_is_device_ptr: 9271 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 9272 break; 9273 case OMPC_if: 9274 case OMPC_final: 9275 case OMPC_num_threads: 9276 case OMPC_safelen: 9277 case OMPC_simdlen: 9278 case OMPC_collapse: 9279 case OMPC_default: 9280 case OMPC_proc_bind: 9281 case OMPC_schedule: 9282 case OMPC_ordered: 9283 case OMPC_nowait: 9284 case OMPC_untied: 9285 case OMPC_mergeable: 9286 case OMPC_threadprivate: 9287 case OMPC_read: 9288 case OMPC_write: 9289 case OMPC_update: 9290 case OMPC_capture: 9291 case OMPC_seq_cst: 9292 case OMPC_device: 9293 case OMPC_threads: 9294 case OMPC_simd: 9295 case OMPC_num_teams: 9296 case OMPC_thread_limit: 9297 case OMPC_priority: 9298 case OMPC_grainsize: 9299 case OMPC_nogroup: 9300 case OMPC_num_tasks: 9301 case OMPC_hint: 9302 case OMPC_dist_schedule: 9303 case OMPC_defaultmap: 9304 case OMPC_unknown: 9305 case OMPC_uniform: 9306 llvm_unreachable("Clause is not allowed."); 9307 } 9308 return Res; 9309 } 9310 9311 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 9312 ExprObjectKind OK, SourceLocation Loc) { 9313 ExprResult Res = BuildDeclRefExpr( 9314 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 9315 if (!Res.isUsable()) 9316 return ExprError(); 9317 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 9318 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 9319 if (!Res.isUsable()) 9320 return ExprError(); 9321 } 9322 if (VK != VK_LValue && Res.get()->isGLValue()) { 9323 Res = DefaultLvalueConversion(Res.get()); 9324 if (!Res.isUsable()) 9325 return ExprError(); 9326 } 9327 return Res; 9328 } 9329 9330 static std::pair<ValueDecl *, bool> 9331 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 9332 SourceRange &ERange, bool AllowArraySection = false) { 9333 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 9334 RefExpr->containsUnexpandedParameterPack()) 9335 return std::make_pair(nullptr, true); 9336 9337 // OpenMP [3.1, C/C++] 9338 // A list item is a variable name. 9339 // OpenMP [2.9.3.3, Restrictions, p.1] 9340 // A variable that is part of another variable (as an array or 9341 // structure element) cannot appear in a private clause. 9342 RefExpr = RefExpr->IgnoreParens(); 9343 enum { 9344 NoArrayExpr = -1, 9345 ArraySubscript = 0, 9346 OMPArraySection = 1 9347 } IsArrayExpr = NoArrayExpr; 9348 if (AllowArraySection) { 9349 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 9350 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 9351 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 9352 Base = TempASE->getBase()->IgnoreParenImpCasts(); 9353 RefExpr = Base; 9354 IsArrayExpr = ArraySubscript; 9355 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 9356 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 9357 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 9358 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 9359 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 9360 Base = TempASE->getBase()->IgnoreParenImpCasts(); 9361 RefExpr = Base; 9362 IsArrayExpr = OMPArraySection; 9363 } 9364 } 9365 ELoc = RefExpr->getExprLoc(); 9366 ERange = RefExpr->getSourceRange(); 9367 RefExpr = RefExpr->IgnoreParenImpCasts(); 9368 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 9369 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 9370 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 9371 (S.getCurrentThisType().isNull() || !ME || 9372 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 9373 !isa<FieldDecl>(ME->getMemberDecl()))) { 9374 if (IsArrayExpr != NoArrayExpr) { 9375 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 9376 << ERange; 9377 } else { 9378 S.Diag(ELoc, 9379 AllowArraySection 9380 ? diag::err_omp_expected_var_name_member_expr_or_array_item 9381 : diag::err_omp_expected_var_name_member_expr) 9382 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 9383 } 9384 return std::make_pair(nullptr, false); 9385 } 9386 return std::make_pair( 9387 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 9388 } 9389 9390 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 9391 SourceLocation StartLoc, 9392 SourceLocation LParenLoc, 9393 SourceLocation EndLoc) { 9394 SmallVector<Expr *, 8> Vars; 9395 SmallVector<Expr *, 8> PrivateCopies; 9396 for (Expr *RefExpr : VarList) { 9397 assert(RefExpr && "NULL expr in OpenMP private clause."); 9398 SourceLocation ELoc; 9399 SourceRange ERange; 9400 Expr *SimpleRefExpr = RefExpr; 9401 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9402 if (Res.second) { 9403 // It will be analyzed later. 9404 Vars.push_back(RefExpr); 9405 PrivateCopies.push_back(nullptr); 9406 } 9407 ValueDecl *D = Res.first; 9408 if (!D) 9409 continue; 9410 9411 QualType Type = D->getType(); 9412 auto *VD = dyn_cast<VarDecl>(D); 9413 9414 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9415 // A variable that appears in a private clause must not have an incomplete 9416 // type or a reference type. 9417 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 9418 continue; 9419 Type = Type.getNonReferenceType(); 9420 9421 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9422 // in a Construct] 9423 // Variables with the predetermined data-sharing attributes may not be 9424 // listed in data-sharing attributes clauses, except for the cases 9425 // listed below. For these exceptions only, listing a predetermined 9426 // variable in a data-sharing attribute clause is allowed and overrides 9427 // the variable's predetermined data-sharing attributes. 9428 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 9429 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 9430 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9431 << getOpenMPClauseName(OMPC_private); 9432 reportOriginalDsa(*this, DSAStack, D, DVar); 9433 continue; 9434 } 9435 9436 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9437 // Variably modified types are not supported for tasks. 9438 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 9439 isOpenMPTaskingDirective(CurrDir)) { 9440 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9441 << getOpenMPClauseName(OMPC_private) << Type 9442 << getOpenMPDirectiveName(CurrDir); 9443 bool IsDecl = 9444 !VD || 9445 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9446 Diag(D->getLocation(), 9447 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9448 << D; 9449 continue; 9450 } 9451 9452 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9453 // A list item cannot appear in both a map clause and a data-sharing 9454 // attribute clause on the same construct 9455 if (isOpenMPTargetExecutionDirective(CurrDir)) { 9456 OpenMPClauseKind ConflictKind; 9457 if (DSAStack->checkMappableExprComponentListsForDecl( 9458 VD, /*CurrentRegionOnly=*/true, 9459 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 9460 OpenMPClauseKind WhereFoundClauseKind) -> bool { 9461 ConflictKind = WhereFoundClauseKind; 9462 return true; 9463 })) { 9464 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 9465 << getOpenMPClauseName(OMPC_private) 9466 << getOpenMPClauseName(ConflictKind) 9467 << getOpenMPDirectiveName(CurrDir); 9468 reportOriginalDsa(*this, DSAStack, D, DVar); 9469 continue; 9470 } 9471 } 9472 9473 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 9474 // A variable of class type (or array thereof) that appears in a private 9475 // clause requires an accessible, unambiguous default constructor for the 9476 // class type. 9477 // Generate helper private variable and initialize it with the default 9478 // value. The address of the original variable is replaced by the address of 9479 // the new private variable in CodeGen. This new variable is not added to 9480 // IdResolver, so the code in the OpenMP region uses original variable for 9481 // proper diagnostics. 9482 Type = Type.getUnqualifiedType(); 9483 VarDecl *VDPrivate = 9484 buildVarDecl(*this, ELoc, Type, D->getName(), 9485 D->hasAttrs() ? &D->getAttrs() : nullptr, 9486 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 9487 ActOnUninitializedDecl(VDPrivate); 9488 if (VDPrivate->isInvalidDecl()) 9489 continue; 9490 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 9491 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 9492 9493 DeclRefExpr *Ref = nullptr; 9494 if (!VD && !CurContext->isDependentContext()) 9495 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9496 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 9497 Vars.push_back((VD || CurContext->isDependentContext()) 9498 ? RefExpr->IgnoreParens() 9499 : Ref); 9500 PrivateCopies.push_back(VDPrivateRefExpr); 9501 } 9502 9503 if (Vars.empty()) 9504 return nullptr; 9505 9506 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9507 PrivateCopies); 9508 } 9509 9510 namespace { 9511 class DiagsUninitializedSeveretyRAII { 9512 private: 9513 DiagnosticsEngine &Diags; 9514 SourceLocation SavedLoc; 9515 bool IsIgnored = false; 9516 9517 public: 9518 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 9519 bool IsIgnored) 9520 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 9521 if (!IsIgnored) { 9522 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 9523 /*Map*/ diag::Severity::Ignored, Loc); 9524 } 9525 } 9526 ~DiagsUninitializedSeveretyRAII() { 9527 if (!IsIgnored) 9528 Diags.popMappings(SavedLoc); 9529 } 9530 }; 9531 } 9532 9533 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 9534 SourceLocation StartLoc, 9535 SourceLocation LParenLoc, 9536 SourceLocation EndLoc) { 9537 SmallVector<Expr *, 8> Vars; 9538 SmallVector<Expr *, 8> PrivateCopies; 9539 SmallVector<Expr *, 8> Inits; 9540 SmallVector<Decl *, 4> ExprCaptures; 9541 bool IsImplicitClause = 9542 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 9543 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 9544 9545 for (Expr *RefExpr : VarList) { 9546 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 9547 SourceLocation ELoc; 9548 SourceRange ERange; 9549 Expr *SimpleRefExpr = RefExpr; 9550 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9551 if (Res.second) { 9552 // It will be analyzed later. 9553 Vars.push_back(RefExpr); 9554 PrivateCopies.push_back(nullptr); 9555 Inits.push_back(nullptr); 9556 } 9557 ValueDecl *D = Res.first; 9558 if (!D) 9559 continue; 9560 9561 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 9562 QualType Type = D->getType(); 9563 auto *VD = dyn_cast<VarDecl>(D); 9564 9565 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9566 // A variable that appears in a private clause must not have an incomplete 9567 // type or a reference type. 9568 if (RequireCompleteType(ELoc, Type, 9569 diag::err_omp_firstprivate_incomplete_type)) 9570 continue; 9571 Type = Type.getNonReferenceType(); 9572 9573 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 9574 // A variable of class type (or array thereof) that appears in a private 9575 // clause requires an accessible, unambiguous copy constructor for the 9576 // class type. 9577 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 9578 9579 // If an implicit firstprivate variable found it was checked already. 9580 DSAStackTy::DSAVarData TopDVar; 9581 if (!IsImplicitClause) { 9582 DSAStackTy::DSAVarData DVar = 9583 DSAStack->getTopDSA(D, /*FromParent=*/false); 9584 TopDVar = DVar; 9585 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9586 bool IsConstant = ElemType.isConstant(Context); 9587 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 9588 // A list item that specifies a given variable may not appear in more 9589 // than one clause on the same directive, except that a variable may be 9590 // specified in both firstprivate and lastprivate clauses. 9591 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 9592 // A list item may appear in a firstprivate or lastprivate clause but not 9593 // both. 9594 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 9595 (isOpenMPDistributeDirective(CurrDir) || 9596 DVar.CKind != OMPC_lastprivate) && 9597 DVar.RefExpr) { 9598 Diag(ELoc, diag::err_omp_wrong_dsa) 9599 << getOpenMPClauseName(DVar.CKind) 9600 << getOpenMPClauseName(OMPC_firstprivate); 9601 reportOriginalDsa(*this, DSAStack, D, DVar); 9602 continue; 9603 } 9604 9605 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9606 // in a Construct] 9607 // Variables with the predetermined data-sharing attributes may not be 9608 // listed in data-sharing attributes clauses, except for the cases 9609 // listed below. For these exceptions only, listing a predetermined 9610 // variable in a data-sharing attribute clause is allowed and overrides 9611 // the variable's predetermined data-sharing attributes. 9612 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9613 // in a Construct, C/C++, p.2] 9614 // Variables with const-qualified type having no mutable member may be 9615 // listed in a firstprivate clause, even if they are static data members. 9616 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 9617 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 9618 Diag(ELoc, diag::err_omp_wrong_dsa) 9619 << getOpenMPClauseName(DVar.CKind) 9620 << getOpenMPClauseName(OMPC_firstprivate); 9621 reportOriginalDsa(*this, DSAStack, D, DVar); 9622 continue; 9623 } 9624 9625 // OpenMP [2.9.3.4, Restrictions, p.2] 9626 // A list item that is private within a parallel region must not appear 9627 // in a firstprivate clause on a worksharing construct if any of the 9628 // worksharing regions arising from the worksharing construct ever bind 9629 // to any of the parallel regions arising from the parallel construct. 9630 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 9631 // A list item that is private within a teams region must not appear in a 9632 // firstprivate clause on a distribute construct if any of the distribute 9633 // regions arising from the distribute construct ever bind to any of the 9634 // teams regions arising from the teams construct. 9635 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 9636 // A list item that appears in a reduction clause of a teams construct 9637 // must not appear in a firstprivate clause on a distribute construct if 9638 // any of the distribute regions arising from the distribute construct 9639 // ever bind to any of the teams regions arising from the teams construct. 9640 if ((isOpenMPWorksharingDirective(CurrDir) || 9641 isOpenMPDistributeDirective(CurrDir)) && 9642 !isOpenMPParallelDirective(CurrDir) && 9643 !isOpenMPTeamsDirective(CurrDir)) { 9644 DVar = DSAStack->getImplicitDSA(D, true); 9645 if (DVar.CKind != OMPC_shared && 9646 (isOpenMPParallelDirective(DVar.DKind) || 9647 isOpenMPTeamsDirective(DVar.DKind) || 9648 DVar.DKind == OMPD_unknown)) { 9649 Diag(ELoc, diag::err_omp_required_access) 9650 << getOpenMPClauseName(OMPC_firstprivate) 9651 << getOpenMPClauseName(OMPC_shared); 9652 reportOriginalDsa(*this, DSAStack, D, DVar); 9653 continue; 9654 } 9655 } 9656 // OpenMP [2.9.3.4, Restrictions, p.3] 9657 // A list item that appears in a reduction clause of a parallel construct 9658 // must not appear in a firstprivate clause on a worksharing or task 9659 // construct if any of the worksharing or task regions arising from the 9660 // worksharing or task construct ever bind to any of the parallel regions 9661 // arising from the parallel construct. 9662 // OpenMP [2.9.3.4, Restrictions, p.4] 9663 // A list item that appears in a reduction clause in worksharing 9664 // construct must not appear in a firstprivate clause in a task construct 9665 // encountered during execution of any of the worksharing regions arising 9666 // from the worksharing construct. 9667 if (isOpenMPTaskingDirective(CurrDir)) { 9668 DVar = DSAStack->hasInnermostDSA( 9669 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 9670 [](OpenMPDirectiveKind K) { 9671 return isOpenMPParallelDirective(K) || 9672 isOpenMPWorksharingDirective(K) || 9673 isOpenMPTeamsDirective(K); 9674 }, 9675 /*FromParent=*/true); 9676 if (DVar.CKind == OMPC_reduction && 9677 (isOpenMPParallelDirective(DVar.DKind) || 9678 isOpenMPWorksharingDirective(DVar.DKind) || 9679 isOpenMPTeamsDirective(DVar.DKind))) { 9680 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 9681 << getOpenMPDirectiveName(DVar.DKind); 9682 reportOriginalDsa(*this, DSAStack, D, DVar); 9683 continue; 9684 } 9685 } 9686 9687 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9688 // A list item cannot appear in both a map clause and a data-sharing 9689 // attribute clause on the same construct 9690 if (isOpenMPTargetExecutionDirective(CurrDir)) { 9691 OpenMPClauseKind ConflictKind; 9692 if (DSAStack->checkMappableExprComponentListsForDecl( 9693 VD, /*CurrentRegionOnly=*/true, 9694 [&ConflictKind]( 9695 OMPClauseMappableExprCommon::MappableExprComponentListRef, 9696 OpenMPClauseKind WhereFoundClauseKind) { 9697 ConflictKind = WhereFoundClauseKind; 9698 return true; 9699 })) { 9700 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 9701 << getOpenMPClauseName(OMPC_firstprivate) 9702 << getOpenMPClauseName(ConflictKind) 9703 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9704 reportOriginalDsa(*this, DSAStack, D, DVar); 9705 continue; 9706 } 9707 } 9708 } 9709 9710 // Variably modified types are not supported for tasks. 9711 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 9712 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 9713 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9714 << getOpenMPClauseName(OMPC_firstprivate) << Type 9715 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9716 bool IsDecl = 9717 !VD || 9718 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9719 Diag(D->getLocation(), 9720 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9721 << D; 9722 continue; 9723 } 9724 9725 Type = Type.getUnqualifiedType(); 9726 VarDecl *VDPrivate = 9727 buildVarDecl(*this, ELoc, Type, D->getName(), 9728 D->hasAttrs() ? &D->getAttrs() : nullptr, 9729 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 9730 // Generate helper private variable and initialize it with the value of the 9731 // original variable. The address of the original variable is replaced by 9732 // the address of the new private variable in the CodeGen. This new variable 9733 // is not added to IdResolver, so the code in the OpenMP region uses 9734 // original variable for proper diagnostics and variable capturing. 9735 Expr *VDInitRefExpr = nullptr; 9736 // For arrays generate initializer for single element and replace it by the 9737 // original array element in CodeGen. 9738 if (Type->isArrayType()) { 9739 VarDecl *VDInit = 9740 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 9741 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 9742 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 9743 ElemType = ElemType.getUnqualifiedType(); 9744 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 9745 ".firstprivate.temp"); 9746 InitializedEntity Entity = 9747 InitializedEntity::InitializeVariable(VDInitTemp); 9748 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 9749 9750 InitializationSequence InitSeq(*this, Entity, Kind, Init); 9751 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 9752 if (Result.isInvalid()) 9753 VDPrivate->setInvalidDecl(); 9754 else 9755 VDPrivate->setInit(Result.getAs<Expr>()); 9756 // Remove temp variable declaration. 9757 Context.Deallocate(VDInitTemp); 9758 } else { 9759 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 9760 ".firstprivate.temp"); 9761 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 9762 RefExpr->getExprLoc()); 9763 AddInitializerToDecl(VDPrivate, 9764 DefaultLvalueConversion(VDInitRefExpr).get(), 9765 /*DirectInit=*/false); 9766 } 9767 if (VDPrivate->isInvalidDecl()) { 9768 if (IsImplicitClause) { 9769 Diag(RefExpr->getExprLoc(), 9770 diag::note_omp_task_predetermined_firstprivate_here); 9771 } 9772 continue; 9773 } 9774 CurContext->addDecl(VDPrivate); 9775 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 9776 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 9777 RefExpr->getExprLoc()); 9778 DeclRefExpr *Ref = nullptr; 9779 if (!VD && !CurContext->isDependentContext()) { 9780 if (TopDVar.CKind == OMPC_lastprivate) { 9781 Ref = TopDVar.PrivateCopy; 9782 } else { 9783 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9784 if (!isOpenMPCapturedDecl(D)) 9785 ExprCaptures.push_back(Ref->getDecl()); 9786 } 9787 } 9788 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 9789 Vars.push_back((VD || CurContext->isDependentContext()) 9790 ? RefExpr->IgnoreParens() 9791 : Ref); 9792 PrivateCopies.push_back(VDPrivateRefExpr); 9793 Inits.push_back(VDInitRefExpr); 9794 } 9795 9796 if (Vars.empty()) 9797 return nullptr; 9798 9799 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9800 Vars, PrivateCopies, Inits, 9801 buildPreInits(Context, ExprCaptures)); 9802 } 9803 9804 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 9805 SourceLocation StartLoc, 9806 SourceLocation LParenLoc, 9807 SourceLocation EndLoc) { 9808 SmallVector<Expr *, 8> Vars; 9809 SmallVector<Expr *, 8> SrcExprs; 9810 SmallVector<Expr *, 8> DstExprs; 9811 SmallVector<Expr *, 8> AssignmentOps; 9812 SmallVector<Decl *, 4> ExprCaptures; 9813 SmallVector<Expr *, 4> ExprPostUpdates; 9814 for (Expr *RefExpr : VarList) { 9815 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9816 SourceLocation ELoc; 9817 SourceRange ERange; 9818 Expr *SimpleRefExpr = RefExpr; 9819 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9820 if (Res.second) { 9821 // It will be analyzed later. 9822 Vars.push_back(RefExpr); 9823 SrcExprs.push_back(nullptr); 9824 DstExprs.push_back(nullptr); 9825 AssignmentOps.push_back(nullptr); 9826 } 9827 ValueDecl *D = Res.first; 9828 if (!D) 9829 continue; 9830 9831 QualType Type = D->getType(); 9832 auto *VD = dyn_cast<VarDecl>(D); 9833 9834 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 9835 // A variable that appears in a lastprivate clause must not have an 9836 // incomplete type or a reference type. 9837 if (RequireCompleteType(ELoc, Type, 9838 diag::err_omp_lastprivate_incomplete_type)) 9839 continue; 9840 Type = Type.getNonReferenceType(); 9841 9842 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9843 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 9844 // in a Construct] 9845 // Variables with the predetermined data-sharing attributes may not be 9846 // listed in data-sharing attributes clauses, except for the cases 9847 // listed below. 9848 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 9849 // A list item may appear in a firstprivate or lastprivate clause but not 9850 // both. 9851 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 9852 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 9853 (isOpenMPDistributeDirective(CurrDir) || 9854 DVar.CKind != OMPC_firstprivate) && 9855 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 9856 Diag(ELoc, diag::err_omp_wrong_dsa) 9857 << getOpenMPClauseName(DVar.CKind) 9858 << getOpenMPClauseName(OMPC_lastprivate); 9859 reportOriginalDsa(*this, DSAStack, D, DVar); 9860 continue; 9861 } 9862 9863 // OpenMP [2.14.3.5, Restrictions, p.2] 9864 // A list item that is private within a parallel region, or that appears in 9865 // the reduction clause of a parallel construct, must not appear in a 9866 // lastprivate clause on a worksharing construct if any of the corresponding 9867 // worksharing regions ever binds to any of the corresponding parallel 9868 // regions. 9869 DSAStackTy::DSAVarData TopDVar = DVar; 9870 if (isOpenMPWorksharingDirective(CurrDir) && 9871 !isOpenMPParallelDirective(CurrDir) && 9872 !isOpenMPTeamsDirective(CurrDir)) { 9873 DVar = DSAStack->getImplicitDSA(D, true); 9874 if (DVar.CKind != OMPC_shared) { 9875 Diag(ELoc, diag::err_omp_required_access) 9876 << getOpenMPClauseName(OMPC_lastprivate) 9877 << getOpenMPClauseName(OMPC_shared); 9878 reportOriginalDsa(*this, DSAStack, D, DVar); 9879 continue; 9880 } 9881 } 9882 9883 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 9884 // A variable of class type (or array thereof) that appears in a 9885 // lastprivate clause requires an accessible, unambiguous default 9886 // constructor for the class type, unless the list item is also specified 9887 // in a firstprivate clause. 9888 // A variable of class type (or array thereof) that appears in a 9889 // lastprivate clause requires an accessible, unambiguous copy assignment 9890 // operator for the class type. 9891 Type = Context.getBaseElementType(Type).getNonReferenceType(); 9892 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 9893 Type.getUnqualifiedType(), ".lastprivate.src", 9894 D->hasAttrs() ? &D->getAttrs() : nullptr); 9895 DeclRefExpr *PseudoSrcExpr = 9896 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 9897 VarDecl *DstVD = 9898 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 9899 D->hasAttrs() ? &D->getAttrs() : nullptr); 9900 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 9901 // For arrays generate assignment operation for single element and replace 9902 // it by the original array element in CodeGen. 9903 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 9904 PseudoDstExpr, PseudoSrcExpr); 9905 if (AssignmentOp.isInvalid()) 9906 continue; 9907 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9908 /*DiscardedValue=*/true); 9909 if (AssignmentOp.isInvalid()) 9910 continue; 9911 9912 DeclRefExpr *Ref = nullptr; 9913 if (!VD && !CurContext->isDependentContext()) { 9914 if (TopDVar.CKind == OMPC_firstprivate) { 9915 Ref = TopDVar.PrivateCopy; 9916 } else { 9917 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9918 if (!isOpenMPCapturedDecl(D)) 9919 ExprCaptures.push_back(Ref->getDecl()); 9920 } 9921 if (TopDVar.CKind == OMPC_firstprivate || 9922 (!isOpenMPCapturedDecl(D) && 9923 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 9924 ExprResult RefRes = DefaultLvalueConversion(Ref); 9925 if (!RefRes.isUsable()) 9926 continue; 9927 ExprResult PostUpdateRes = 9928 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 9929 RefRes.get()); 9930 if (!PostUpdateRes.isUsable()) 9931 continue; 9932 ExprPostUpdates.push_back( 9933 IgnoredValueConversions(PostUpdateRes.get()).get()); 9934 } 9935 } 9936 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 9937 Vars.push_back((VD || CurContext->isDependentContext()) 9938 ? RefExpr->IgnoreParens() 9939 : Ref); 9940 SrcExprs.push_back(PseudoSrcExpr); 9941 DstExprs.push_back(PseudoDstExpr); 9942 AssignmentOps.push_back(AssignmentOp.get()); 9943 } 9944 9945 if (Vars.empty()) 9946 return nullptr; 9947 9948 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9949 Vars, SrcExprs, DstExprs, AssignmentOps, 9950 buildPreInits(Context, ExprCaptures), 9951 buildPostUpdate(*this, ExprPostUpdates)); 9952 } 9953 9954 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 9955 SourceLocation StartLoc, 9956 SourceLocation LParenLoc, 9957 SourceLocation EndLoc) { 9958 SmallVector<Expr *, 8> Vars; 9959 for (Expr *RefExpr : VarList) { 9960 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9961 SourceLocation ELoc; 9962 SourceRange ERange; 9963 Expr *SimpleRefExpr = RefExpr; 9964 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9965 if (Res.second) { 9966 // It will be analyzed later. 9967 Vars.push_back(RefExpr); 9968 } 9969 ValueDecl *D = Res.first; 9970 if (!D) 9971 continue; 9972 9973 auto *VD = dyn_cast<VarDecl>(D); 9974 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9975 // in a Construct] 9976 // Variables with the predetermined data-sharing attributes may not be 9977 // listed in data-sharing attributes clauses, except for the cases 9978 // listed below. For these exceptions only, listing a predetermined 9979 // variable in a data-sharing attribute clause is allowed and overrides 9980 // the variable's predetermined data-sharing attributes. 9981 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 9982 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 9983 DVar.RefExpr) { 9984 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9985 << getOpenMPClauseName(OMPC_shared); 9986 reportOriginalDsa(*this, DSAStack, D, DVar); 9987 continue; 9988 } 9989 9990 DeclRefExpr *Ref = nullptr; 9991 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 9992 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9993 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 9994 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 9995 ? RefExpr->IgnoreParens() 9996 : Ref); 9997 } 9998 9999 if (Vars.empty()) 10000 return nullptr; 10001 10002 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 10003 } 10004 10005 namespace { 10006 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 10007 DSAStackTy *Stack; 10008 10009 public: 10010 bool VisitDeclRefExpr(DeclRefExpr *E) { 10011 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 10012 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 10013 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 10014 return false; 10015 if (DVar.CKind != OMPC_unknown) 10016 return true; 10017 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 10018 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 10019 /*FromParent=*/true); 10020 return DVarPrivate.CKind != OMPC_unknown; 10021 } 10022 return false; 10023 } 10024 bool VisitStmt(Stmt *S) { 10025 for (Stmt *Child : S->children()) { 10026 if (Child && Visit(Child)) 10027 return true; 10028 } 10029 return false; 10030 } 10031 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 10032 }; 10033 } // namespace 10034 10035 namespace { 10036 // Transform MemberExpression for specified FieldDecl of current class to 10037 // DeclRefExpr to specified OMPCapturedExprDecl. 10038 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 10039 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 10040 ValueDecl *Field = nullptr; 10041 DeclRefExpr *CapturedExpr = nullptr; 10042 10043 public: 10044 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 10045 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 10046 10047 ExprResult TransformMemberExpr(MemberExpr *E) { 10048 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 10049 E->getMemberDecl() == Field) { 10050 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 10051 return CapturedExpr; 10052 } 10053 return BaseTransform::TransformMemberExpr(E); 10054 } 10055 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 10056 }; 10057 } // namespace 10058 10059 template <typename T, typename U> 10060 static T filterLookupForUDR(SmallVectorImpl<U> &Lookups, 10061 const llvm::function_ref<T(ValueDecl *)> Gen) { 10062 for (U &Set : Lookups) { 10063 for (auto *D : Set) { 10064 if (T Res = Gen(cast<ValueDecl>(D))) 10065 return Res; 10066 } 10067 } 10068 return T(); 10069 } 10070 10071 static ExprResult 10072 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 10073 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 10074 const DeclarationNameInfo &ReductionId, QualType Ty, 10075 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 10076 if (ReductionIdScopeSpec.isInvalid()) 10077 return ExprError(); 10078 SmallVector<UnresolvedSet<8>, 4> Lookups; 10079 if (S) { 10080 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10081 Lookup.suppressDiagnostics(); 10082 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 10083 NamedDecl *D = Lookup.getRepresentativeDecl(); 10084 do { 10085 S = S->getParent(); 10086 } while (S && !S->isDeclScope(D)); 10087 if (S) 10088 S = S->getParent(); 10089 Lookups.push_back(UnresolvedSet<8>()); 10090 Lookups.back().append(Lookup.begin(), Lookup.end()); 10091 Lookup.clear(); 10092 } 10093 } else if (auto *ULE = 10094 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 10095 Lookups.push_back(UnresolvedSet<8>()); 10096 Decl *PrevD = nullptr; 10097 for (NamedDecl *D : ULE->decls()) { 10098 if (D == PrevD) 10099 Lookups.push_back(UnresolvedSet<8>()); 10100 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 10101 Lookups.back().addDecl(DRD); 10102 PrevD = D; 10103 } 10104 } 10105 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 10106 Ty->isInstantiationDependentType() || 10107 Ty->containsUnexpandedParameterPack() || 10108 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) { 10109 return !D->isInvalidDecl() && 10110 (D->getType()->isDependentType() || 10111 D->getType()->isInstantiationDependentType() || 10112 D->getType()->containsUnexpandedParameterPack()); 10113 })) { 10114 UnresolvedSet<8> ResSet; 10115 for (const UnresolvedSet<8> &Set : Lookups) { 10116 ResSet.append(Set.begin(), Set.end()); 10117 // The last item marks the end of all declarations at the specified scope. 10118 ResSet.addDecl(Set[Set.size() - 1]); 10119 } 10120 return UnresolvedLookupExpr::Create( 10121 SemaRef.Context, /*NamingClass=*/nullptr, 10122 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 10123 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 10124 } 10125 if (auto *VD = filterLookupForUDR<ValueDecl *>( 10126 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 10127 if (!D->isInvalidDecl() && 10128 SemaRef.Context.hasSameType(D->getType(), Ty)) 10129 return D; 10130 return nullptr; 10131 })) 10132 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 10133 if (auto *VD = filterLookupForUDR<ValueDecl *>( 10134 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 10135 if (!D->isInvalidDecl() && 10136 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 10137 !Ty.isMoreQualifiedThan(D->getType())) 10138 return D; 10139 return nullptr; 10140 })) { 10141 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 10142 /*DetectVirtual=*/false); 10143 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 10144 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 10145 VD->getType().getUnqualifiedType()))) { 10146 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 10147 /*DiagID=*/0) != 10148 Sema::AR_inaccessible) { 10149 SemaRef.BuildBasePathArray(Paths, BasePath); 10150 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 10151 } 10152 } 10153 } 10154 } 10155 if (ReductionIdScopeSpec.isSet()) { 10156 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 10157 return ExprError(); 10158 } 10159 return ExprEmpty(); 10160 } 10161 10162 namespace { 10163 /// Data for the reduction-based clauses. 10164 struct ReductionData { 10165 /// List of original reduction items. 10166 SmallVector<Expr *, 8> Vars; 10167 /// List of private copies of the reduction items. 10168 SmallVector<Expr *, 8> Privates; 10169 /// LHS expressions for the reduction_op expressions. 10170 SmallVector<Expr *, 8> LHSs; 10171 /// RHS expressions for the reduction_op expressions. 10172 SmallVector<Expr *, 8> RHSs; 10173 /// Reduction operation expression. 10174 SmallVector<Expr *, 8> ReductionOps; 10175 /// Taskgroup descriptors for the corresponding reduction items in 10176 /// in_reduction clauses. 10177 SmallVector<Expr *, 8> TaskgroupDescriptors; 10178 /// List of captures for clause. 10179 SmallVector<Decl *, 4> ExprCaptures; 10180 /// List of postupdate expressions. 10181 SmallVector<Expr *, 4> ExprPostUpdates; 10182 ReductionData() = delete; 10183 /// Reserves required memory for the reduction data. 10184 ReductionData(unsigned Size) { 10185 Vars.reserve(Size); 10186 Privates.reserve(Size); 10187 LHSs.reserve(Size); 10188 RHSs.reserve(Size); 10189 ReductionOps.reserve(Size); 10190 TaskgroupDescriptors.reserve(Size); 10191 ExprCaptures.reserve(Size); 10192 ExprPostUpdates.reserve(Size); 10193 } 10194 /// Stores reduction item and reduction operation only (required for dependent 10195 /// reduction item). 10196 void push(Expr *Item, Expr *ReductionOp) { 10197 Vars.emplace_back(Item); 10198 Privates.emplace_back(nullptr); 10199 LHSs.emplace_back(nullptr); 10200 RHSs.emplace_back(nullptr); 10201 ReductionOps.emplace_back(ReductionOp); 10202 TaskgroupDescriptors.emplace_back(nullptr); 10203 } 10204 /// Stores reduction data. 10205 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 10206 Expr *TaskgroupDescriptor) { 10207 Vars.emplace_back(Item); 10208 Privates.emplace_back(Private); 10209 LHSs.emplace_back(LHS); 10210 RHSs.emplace_back(RHS); 10211 ReductionOps.emplace_back(ReductionOp); 10212 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 10213 } 10214 }; 10215 } // namespace 10216 10217 static bool checkOMPArraySectionConstantForReduction( 10218 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 10219 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 10220 const Expr *Length = OASE->getLength(); 10221 if (Length == nullptr) { 10222 // For array sections of the form [1:] or [:], we would need to analyze 10223 // the lower bound... 10224 if (OASE->getColonLoc().isValid()) 10225 return false; 10226 10227 // This is an array subscript which has implicit length 1! 10228 SingleElement = true; 10229 ArraySizes.push_back(llvm::APSInt::get(1)); 10230 } else { 10231 llvm::APSInt ConstantLengthValue; 10232 if (!Length->EvaluateAsInt(ConstantLengthValue, Context)) 10233 return false; 10234 10235 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 10236 ArraySizes.push_back(ConstantLengthValue); 10237 } 10238 10239 // Get the base of this array section and walk up from there. 10240 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 10241 10242 // We require length = 1 for all array sections except the right-most to 10243 // guarantee that the memory region is contiguous and has no holes in it. 10244 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 10245 Length = TempOASE->getLength(); 10246 if (Length == nullptr) { 10247 // For array sections of the form [1:] or [:], we would need to analyze 10248 // the lower bound... 10249 if (OASE->getColonLoc().isValid()) 10250 return false; 10251 10252 // This is an array subscript which has implicit length 1! 10253 ArraySizes.push_back(llvm::APSInt::get(1)); 10254 } else { 10255 llvm::APSInt ConstantLengthValue; 10256 if (!Length->EvaluateAsInt(ConstantLengthValue, Context) || 10257 ConstantLengthValue.getSExtValue() != 1) 10258 return false; 10259 10260 ArraySizes.push_back(ConstantLengthValue); 10261 } 10262 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 10263 } 10264 10265 // If we have a single element, we don't need to add the implicit lengths. 10266 if (!SingleElement) { 10267 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 10268 // Has implicit length 1! 10269 ArraySizes.push_back(llvm::APSInt::get(1)); 10270 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10271 } 10272 } 10273 10274 // This array section can be privatized as a single value or as a constant 10275 // sized array. 10276 return true; 10277 } 10278 10279 static bool actOnOMPReductionKindClause( 10280 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 10281 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10282 SourceLocation ColonLoc, SourceLocation EndLoc, 10283 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10284 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 10285 DeclarationName DN = ReductionId.getName(); 10286 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 10287 BinaryOperatorKind BOK = BO_Comma; 10288 10289 ASTContext &Context = S.Context; 10290 // OpenMP [2.14.3.6, reduction clause] 10291 // C 10292 // reduction-identifier is either an identifier or one of the following 10293 // operators: +, -, *, &, |, ^, && and || 10294 // C++ 10295 // reduction-identifier is either an id-expression or one of the following 10296 // operators: +, -, *, &, |, ^, && and || 10297 switch (OOK) { 10298 case OO_Plus: 10299 case OO_Minus: 10300 BOK = BO_Add; 10301 break; 10302 case OO_Star: 10303 BOK = BO_Mul; 10304 break; 10305 case OO_Amp: 10306 BOK = BO_And; 10307 break; 10308 case OO_Pipe: 10309 BOK = BO_Or; 10310 break; 10311 case OO_Caret: 10312 BOK = BO_Xor; 10313 break; 10314 case OO_AmpAmp: 10315 BOK = BO_LAnd; 10316 break; 10317 case OO_PipePipe: 10318 BOK = BO_LOr; 10319 break; 10320 case OO_New: 10321 case OO_Delete: 10322 case OO_Array_New: 10323 case OO_Array_Delete: 10324 case OO_Slash: 10325 case OO_Percent: 10326 case OO_Tilde: 10327 case OO_Exclaim: 10328 case OO_Equal: 10329 case OO_Less: 10330 case OO_Greater: 10331 case OO_LessEqual: 10332 case OO_GreaterEqual: 10333 case OO_PlusEqual: 10334 case OO_MinusEqual: 10335 case OO_StarEqual: 10336 case OO_SlashEqual: 10337 case OO_PercentEqual: 10338 case OO_CaretEqual: 10339 case OO_AmpEqual: 10340 case OO_PipeEqual: 10341 case OO_LessLess: 10342 case OO_GreaterGreater: 10343 case OO_LessLessEqual: 10344 case OO_GreaterGreaterEqual: 10345 case OO_EqualEqual: 10346 case OO_ExclaimEqual: 10347 case OO_Spaceship: 10348 case OO_PlusPlus: 10349 case OO_MinusMinus: 10350 case OO_Comma: 10351 case OO_ArrowStar: 10352 case OO_Arrow: 10353 case OO_Call: 10354 case OO_Subscript: 10355 case OO_Conditional: 10356 case OO_Coawait: 10357 case NUM_OVERLOADED_OPERATORS: 10358 llvm_unreachable("Unexpected reduction identifier"); 10359 case OO_None: 10360 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 10361 if (II->isStr("max")) 10362 BOK = BO_GT; 10363 else if (II->isStr("min")) 10364 BOK = BO_LT; 10365 } 10366 break; 10367 } 10368 SourceRange ReductionIdRange; 10369 if (ReductionIdScopeSpec.isValid()) 10370 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 10371 else 10372 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 10373 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 10374 10375 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 10376 bool FirstIter = true; 10377 for (Expr *RefExpr : VarList) { 10378 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 10379 // OpenMP [2.1, C/C++] 10380 // A list item is a variable or array section, subject to the restrictions 10381 // specified in Section 2.4 on page 42 and in each of the sections 10382 // describing clauses and directives for which a list appears. 10383 // OpenMP [2.14.3.3, Restrictions, p.1] 10384 // A variable that is part of another variable (as an array or 10385 // structure element) cannot appear in a private clause. 10386 if (!FirstIter && IR != ER) 10387 ++IR; 10388 FirstIter = false; 10389 SourceLocation ELoc; 10390 SourceRange ERange; 10391 Expr *SimpleRefExpr = RefExpr; 10392 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 10393 /*AllowArraySection=*/true); 10394 if (Res.second) { 10395 // Try to find 'declare reduction' corresponding construct before using 10396 // builtin/overloaded operators. 10397 QualType Type = Context.DependentTy; 10398 CXXCastPath BasePath; 10399 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10400 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10401 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10402 Expr *ReductionOp = nullptr; 10403 if (S.CurContext->isDependentContext() && 10404 (DeclareReductionRef.isUnset() || 10405 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 10406 ReductionOp = DeclareReductionRef.get(); 10407 // It will be analyzed later. 10408 RD.push(RefExpr, ReductionOp); 10409 } 10410 ValueDecl *D = Res.first; 10411 if (!D) 10412 continue; 10413 10414 Expr *TaskgroupDescriptor = nullptr; 10415 QualType Type; 10416 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 10417 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 10418 if (ASE) { 10419 Type = ASE->getType().getNonReferenceType(); 10420 } else if (OASE) { 10421 QualType BaseType = 10422 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 10423 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 10424 Type = ATy->getElementType(); 10425 else 10426 Type = BaseType->getPointeeType(); 10427 Type = Type.getNonReferenceType(); 10428 } else { 10429 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 10430 } 10431 auto *VD = dyn_cast<VarDecl>(D); 10432 10433 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10434 // A variable that appears in a private clause must not have an incomplete 10435 // type or a reference type. 10436 if (S.RequireCompleteType(ELoc, D->getType(), 10437 diag::err_omp_reduction_incomplete_type)) 10438 continue; 10439 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10440 // A list item that appears in a reduction clause must not be 10441 // const-qualified. 10442 if (Type.getNonReferenceType().isConstant(Context)) { 10443 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange; 10444 if (!ASE && !OASE) { 10445 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10446 VarDecl::DeclarationOnly; 10447 S.Diag(D->getLocation(), 10448 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10449 << D; 10450 } 10451 continue; 10452 } 10453 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 10454 // If a list-item is a reference type then it must bind to the same object 10455 // for all threads of the team. 10456 if (!ASE && !OASE && VD) { 10457 VarDecl *VDDef = VD->getDefinition(); 10458 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 10459 DSARefChecker Check(Stack); 10460 if (Check.Visit(VDDef->getInit())) { 10461 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 10462 << getOpenMPClauseName(ClauseKind) << ERange; 10463 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 10464 continue; 10465 } 10466 } 10467 } 10468 10469 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10470 // in a Construct] 10471 // Variables with the predetermined data-sharing attributes may not be 10472 // listed in data-sharing attributes clauses, except for the cases 10473 // listed below. For these exceptions only, listing a predetermined 10474 // variable in a data-sharing attribute clause is allowed and overrides 10475 // the variable's predetermined data-sharing attributes. 10476 // OpenMP [2.14.3.6, Restrictions, p.3] 10477 // Any number of reduction clauses can be specified on the directive, 10478 // but a list item can appear only once in the reduction clauses for that 10479 // directive. 10480 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 10481 if (DVar.CKind == OMPC_reduction) { 10482 S.Diag(ELoc, diag::err_omp_once_referenced) 10483 << getOpenMPClauseName(ClauseKind); 10484 if (DVar.RefExpr) 10485 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 10486 continue; 10487 } 10488 if (DVar.CKind != OMPC_unknown) { 10489 S.Diag(ELoc, diag::err_omp_wrong_dsa) 10490 << getOpenMPClauseName(DVar.CKind) 10491 << getOpenMPClauseName(OMPC_reduction); 10492 reportOriginalDsa(S, Stack, D, DVar); 10493 continue; 10494 } 10495 10496 // OpenMP [2.14.3.6, Restrictions, p.1] 10497 // A list item that appears in a reduction clause of a worksharing 10498 // construct must be shared in the parallel regions to which any of the 10499 // worksharing regions arising from the worksharing construct bind. 10500 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 10501 if (isOpenMPWorksharingDirective(CurrDir) && 10502 !isOpenMPParallelDirective(CurrDir) && 10503 !isOpenMPTeamsDirective(CurrDir)) { 10504 DVar = Stack->getImplicitDSA(D, true); 10505 if (DVar.CKind != OMPC_shared) { 10506 S.Diag(ELoc, diag::err_omp_required_access) 10507 << getOpenMPClauseName(OMPC_reduction) 10508 << getOpenMPClauseName(OMPC_shared); 10509 reportOriginalDsa(S, Stack, D, DVar); 10510 continue; 10511 } 10512 } 10513 10514 // Try to find 'declare reduction' corresponding construct before using 10515 // builtin/overloaded operators. 10516 CXXCastPath BasePath; 10517 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10518 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10519 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10520 if (DeclareReductionRef.isInvalid()) 10521 continue; 10522 if (S.CurContext->isDependentContext() && 10523 (DeclareReductionRef.isUnset() || 10524 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 10525 RD.push(RefExpr, DeclareReductionRef.get()); 10526 continue; 10527 } 10528 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 10529 // Not allowed reduction identifier is found. 10530 S.Diag(ReductionId.getBeginLoc(), 10531 diag::err_omp_unknown_reduction_identifier) 10532 << Type << ReductionIdRange; 10533 continue; 10534 } 10535 10536 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10537 // The type of a list item that appears in a reduction clause must be valid 10538 // for the reduction-identifier. For a max or min reduction in C, the type 10539 // of the list item must be an allowed arithmetic data type: char, int, 10540 // float, double, or _Bool, possibly modified with long, short, signed, or 10541 // unsigned. For a max or min reduction in C++, the type of the list item 10542 // must be an allowed arithmetic data type: char, wchar_t, int, float, 10543 // double, or bool, possibly modified with long, short, signed, or unsigned. 10544 if (DeclareReductionRef.isUnset()) { 10545 if ((BOK == BO_GT || BOK == BO_LT) && 10546 !(Type->isScalarType() || 10547 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 10548 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 10549 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 10550 if (!ASE && !OASE) { 10551 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10552 VarDecl::DeclarationOnly; 10553 S.Diag(D->getLocation(), 10554 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10555 << D; 10556 } 10557 continue; 10558 } 10559 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 10560 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 10561 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 10562 << getOpenMPClauseName(ClauseKind); 10563 if (!ASE && !OASE) { 10564 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10565 VarDecl::DeclarationOnly; 10566 S.Diag(D->getLocation(), 10567 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10568 << D; 10569 } 10570 continue; 10571 } 10572 } 10573 10574 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 10575 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 10576 D->hasAttrs() ? &D->getAttrs() : nullptr); 10577 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 10578 D->hasAttrs() ? &D->getAttrs() : nullptr); 10579 QualType PrivateTy = Type; 10580 10581 // Try if we can determine constant lengths for all array sections and avoid 10582 // the VLA. 10583 bool ConstantLengthOASE = false; 10584 if (OASE) { 10585 bool SingleElement; 10586 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 10587 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 10588 Context, OASE, SingleElement, ArraySizes); 10589 10590 // If we don't have a single element, we must emit a constant array type. 10591 if (ConstantLengthOASE && !SingleElement) { 10592 for (llvm::APSInt &Size : ArraySizes) 10593 PrivateTy = Context.getConstantArrayType( 10594 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 10595 } 10596 } 10597 10598 if ((OASE && !ConstantLengthOASE) || 10599 (!OASE && !ASE && 10600 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 10601 if (!Context.getTargetInfo().isVLASupported() && 10602 S.shouldDiagnoseTargetSupportFromOpenMP()) { 10603 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 10604 S.Diag(ELoc, diag::note_vla_unsupported); 10605 continue; 10606 } 10607 // For arrays/array sections only: 10608 // Create pseudo array type for private copy. The size for this array will 10609 // be generated during codegen. 10610 // For array subscripts or single variables Private Ty is the same as Type 10611 // (type of the variable or single array element). 10612 PrivateTy = Context.getVariableArrayType( 10613 Type, 10614 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 10615 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 10616 } else if (!ASE && !OASE && 10617 Context.getAsArrayType(D->getType().getNonReferenceType())) { 10618 PrivateTy = D->getType().getNonReferenceType(); 10619 } 10620 // Private copy. 10621 VarDecl *PrivateVD = 10622 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 10623 D->hasAttrs() ? &D->getAttrs() : nullptr, 10624 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10625 // Add initializer for private variable. 10626 Expr *Init = nullptr; 10627 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 10628 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 10629 if (DeclareReductionRef.isUsable()) { 10630 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 10631 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 10632 if (DRD->getInitializer()) { 10633 Init = DRDRef; 10634 RHSVD->setInit(DRDRef); 10635 RHSVD->setInitStyle(VarDecl::CallInit); 10636 } 10637 } else { 10638 switch (BOK) { 10639 case BO_Add: 10640 case BO_Xor: 10641 case BO_Or: 10642 case BO_LOr: 10643 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 10644 if (Type->isScalarType() || Type->isAnyComplexType()) 10645 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 10646 break; 10647 case BO_Mul: 10648 case BO_LAnd: 10649 if (Type->isScalarType() || Type->isAnyComplexType()) { 10650 // '*' and '&&' reduction ops - initializer is '1'. 10651 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 10652 } 10653 break; 10654 case BO_And: { 10655 // '&' reduction op - initializer is '~0'. 10656 QualType OrigType = Type; 10657 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 10658 Type = ComplexTy->getElementType(); 10659 if (Type->isRealFloatingType()) { 10660 llvm::APFloat InitValue = 10661 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 10662 /*isIEEE=*/true); 10663 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 10664 Type, ELoc); 10665 } else if (Type->isScalarType()) { 10666 uint64_t Size = Context.getTypeSize(Type); 10667 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 10668 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 10669 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 10670 } 10671 if (Init && OrigType->isAnyComplexType()) { 10672 // Init = 0xFFFF + 0xFFFFi; 10673 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 10674 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 10675 } 10676 Type = OrigType; 10677 break; 10678 } 10679 case BO_LT: 10680 case BO_GT: { 10681 // 'min' reduction op - initializer is 'Largest representable number in 10682 // the reduction list item type'. 10683 // 'max' reduction op - initializer is 'Least representable number in 10684 // the reduction list item type'. 10685 if (Type->isIntegerType() || Type->isPointerType()) { 10686 bool IsSigned = Type->hasSignedIntegerRepresentation(); 10687 uint64_t Size = Context.getTypeSize(Type); 10688 QualType IntTy = 10689 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 10690 llvm::APInt InitValue = 10691 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 10692 : llvm::APInt::getMinValue(Size) 10693 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 10694 : llvm::APInt::getMaxValue(Size); 10695 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 10696 if (Type->isPointerType()) { 10697 // Cast to pointer type. 10698 ExprResult CastExpr = S.BuildCStyleCastExpr( 10699 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 10700 if (CastExpr.isInvalid()) 10701 continue; 10702 Init = CastExpr.get(); 10703 } 10704 } else if (Type->isRealFloatingType()) { 10705 llvm::APFloat InitValue = llvm::APFloat::getLargest( 10706 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 10707 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 10708 Type, ELoc); 10709 } 10710 break; 10711 } 10712 case BO_PtrMemD: 10713 case BO_PtrMemI: 10714 case BO_MulAssign: 10715 case BO_Div: 10716 case BO_Rem: 10717 case BO_Sub: 10718 case BO_Shl: 10719 case BO_Shr: 10720 case BO_LE: 10721 case BO_GE: 10722 case BO_EQ: 10723 case BO_NE: 10724 case BO_Cmp: 10725 case BO_AndAssign: 10726 case BO_XorAssign: 10727 case BO_OrAssign: 10728 case BO_Assign: 10729 case BO_AddAssign: 10730 case BO_SubAssign: 10731 case BO_DivAssign: 10732 case BO_RemAssign: 10733 case BO_ShlAssign: 10734 case BO_ShrAssign: 10735 case BO_Comma: 10736 llvm_unreachable("Unexpected reduction operation"); 10737 } 10738 } 10739 if (Init && DeclareReductionRef.isUnset()) 10740 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 10741 else if (!Init) 10742 S.ActOnUninitializedDecl(RHSVD); 10743 if (RHSVD->isInvalidDecl()) 10744 continue; 10745 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 10746 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 10747 << Type << ReductionIdRange; 10748 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10749 VarDecl::DeclarationOnly; 10750 S.Diag(D->getLocation(), 10751 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10752 << D; 10753 continue; 10754 } 10755 // Store initializer for single element in private copy. Will be used during 10756 // codegen. 10757 PrivateVD->setInit(RHSVD->getInit()); 10758 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 10759 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 10760 ExprResult ReductionOp; 10761 if (DeclareReductionRef.isUsable()) { 10762 QualType RedTy = DeclareReductionRef.get()->getType(); 10763 QualType PtrRedTy = Context.getPointerType(RedTy); 10764 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 10765 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 10766 if (!BasePath.empty()) { 10767 LHS = S.DefaultLvalueConversion(LHS.get()); 10768 RHS = S.DefaultLvalueConversion(RHS.get()); 10769 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 10770 CK_UncheckedDerivedToBase, LHS.get(), 10771 &BasePath, LHS.get()->getValueKind()); 10772 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 10773 CK_UncheckedDerivedToBase, RHS.get(), 10774 &BasePath, RHS.get()->getValueKind()); 10775 } 10776 FunctionProtoType::ExtProtoInfo EPI; 10777 QualType Params[] = {PtrRedTy, PtrRedTy}; 10778 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 10779 auto *OVE = new (Context) OpaqueValueExpr( 10780 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 10781 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 10782 Expr *Args[] = {LHS.get(), RHS.get()}; 10783 ReductionOp = new (Context) 10784 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 10785 } else { 10786 ReductionOp = S.BuildBinOp( 10787 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 10788 if (ReductionOp.isUsable()) { 10789 if (BOK != BO_LT && BOK != BO_GT) { 10790 ReductionOp = 10791 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 10792 BO_Assign, LHSDRE, ReductionOp.get()); 10793 } else { 10794 auto *ConditionalOp = new (Context) 10795 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 10796 Type, VK_LValue, OK_Ordinary); 10797 ReductionOp = 10798 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 10799 BO_Assign, LHSDRE, ConditionalOp); 10800 } 10801 if (ReductionOp.isUsable()) 10802 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); 10803 } 10804 if (!ReductionOp.isUsable()) 10805 continue; 10806 } 10807 10808 // OpenMP [2.15.4.6, Restrictions, p.2] 10809 // A list item that appears in an in_reduction clause of a task construct 10810 // must appear in a task_reduction clause of a construct associated with a 10811 // taskgroup region that includes the participating task in its taskgroup 10812 // set. The construct associated with the innermost region that meets this 10813 // condition must specify the same reduction-identifier as the in_reduction 10814 // clause. 10815 if (ClauseKind == OMPC_in_reduction) { 10816 SourceRange ParentSR; 10817 BinaryOperatorKind ParentBOK; 10818 const Expr *ParentReductionOp; 10819 Expr *ParentBOKTD, *ParentReductionOpTD; 10820 DSAStackTy::DSAVarData ParentBOKDSA = 10821 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 10822 ParentBOKTD); 10823 DSAStackTy::DSAVarData ParentReductionOpDSA = 10824 Stack->getTopMostTaskgroupReductionData( 10825 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 10826 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 10827 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 10828 if (!IsParentBOK && !IsParentReductionOp) { 10829 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 10830 continue; 10831 } 10832 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 10833 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 10834 IsParentReductionOp) { 10835 bool EmitError = true; 10836 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 10837 llvm::FoldingSetNodeID RedId, ParentRedId; 10838 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 10839 DeclareReductionRef.get()->Profile(RedId, Context, 10840 /*Canonical=*/true); 10841 EmitError = RedId != ParentRedId; 10842 } 10843 if (EmitError) { 10844 S.Diag(ReductionId.getBeginLoc(), 10845 diag::err_omp_reduction_identifier_mismatch) 10846 << ReductionIdRange << RefExpr->getSourceRange(); 10847 S.Diag(ParentSR.getBegin(), 10848 diag::note_omp_previous_reduction_identifier) 10849 << ParentSR 10850 << (IsParentBOK ? ParentBOKDSA.RefExpr 10851 : ParentReductionOpDSA.RefExpr) 10852 ->getSourceRange(); 10853 continue; 10854 } 10855 } 10856 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 10857 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 10858 } 10859 10860 DeclRefExpr *Ref = nullptr; 10861 Expr *VarsExpr = RefExpr->IgnoreParens(); 10862 if (!VD && !S.CurContext->isDependentContext()) { 10863 if (ASE || OASE) { 10864 TransformExprToCaptures RebuildToCapture(S, D); 10865 VarsExpr = 10866 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 10867 Ref = RebuildToCapture.getCapturedExpr(); 10868 } else { 10869 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 10870 } 10871 if (!S.isOpenMPCapturedDecl(D)) { 10872 RD.ExprCaptures.emplace_back(Ref->getDecl()); 10873 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 10874 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 10875 if (!RefRes.isUsable()) 10876 continue; 10877 ExprResult PostUpdateRes = 10878 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10879 RefRes.get()); 10880 if (!PostUpdateRes.isUsable()) 10881 continue; 10882 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 10883 Stack->getCurrentDirective() == OMPD_taskgroup) { 10884 S.Diag(RefExpr->getExprLoc(), 10885 diag::err_omp_reduction_non_addressable_expression) 10886 << RefExpr->getSourceRange(); 10887 continue; 10888 } 10889 RD.ExprPostUpdates.emplace_back( 10890 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 10891 } 10892 } 10893 } 10894 // All reduction items are still marked as reduction (to do not increase 10895 // code base size). 10896 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 10897 if (CurrDir == OMPD_taskgroup) { 10898 if (DeclareReductionRef.isUsable()) 10899 Stack->addTaskgroupReductionData(D, ReductionIdRange, 10900 DeclareReductionRef.get()); 10901 else 10902 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 10903 } 10904 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 10905 TaskgroupDescriptor); 10906 } 10907 return RD.Vars.empty(); 10908 } 10909 10910 OMPClause *Sema::ActOnOpenMPReductionClause( 10911 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10912 SourceLocation ColonLoc, SourceLocation EndLoc, 10913 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10914 ArrayRef<Expr *> UnresolvedReductions) { 10915 ReductionData RD(VarList.size()); 10916 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 10917 StartLoc, LParenLoc, ColonLoc, EndLoc, 10918 ReductionIdScopeSpec, ReductionId, 10919 UnresolvedReductions, RD)) 10920 return nullptr; 10921 10922 return OMPReductionClause::Create( 10923 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 10924 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 10925 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 10926 buildPreInits(Context, RD.ExprCaptures), 10927 buildPostUpdate(*this, RD.ExprPostUpdates)); 10928 } 10929 10930 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 10931 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10932 SourceLocation ColonLoc, SourceLocation EndLoc, 10933 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10934 ArrayRef<Expr *> UnresolvedReductions) { 10935 ReductionData RD(VarList.size()); 10936 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 10937 StartLoc, LParenLoc, ColonLoc, EndLoc, 10938 ReductionIdScopeSpec, ReductionId, 10939 UnresolvedReductions, RD)) 10940 return nullptr; 10941 10942 return OMPTaskReductionClause::Create( 10943 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 10944 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 10945 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 10946 buildPreInits(Context, RD.ExprCaptures), 10947 buildPostUpdate(*this, RD.ExprPostUpdates)); 10948 } 10949 10950 OMPClause *Sema::ActOnOpenMPInReductionClause( 10951 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10952 SourceLocation ColonLoc, SourceLocation EndLoc, 10953 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10954 ArrayRef<Expr *> UnresolvedReductions) { 10955 ReductionData RD(VarList.size()); 10956 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 10957 StartLoc, LParenLoc, ColonLoc, EndLoc, 10958 ReductionIdScopeSpec, ReductionId, 10959 UnresolvedReductions, RD)) 10960 return nullptr; 10961 10962 return OMPInReductionClause::Create( 10963 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 10964 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 10965 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 10966 buildPreInits(Context, RD.ExprCaptures), 10967 buildPostUpdate(*this, RD.ExprPostUpdates)); 10968 } 10969 10970 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 10971 SourceLocation LinLoc) { 10972 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 10973 LinKind == OMPC_LINEAR_unknown) { 10974 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 10975 return true; 10976 } 10977 return false; 10978 } 10979 10980 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 10981 OpenMPLinearClauseKind LinKind, 10982 QualType Type) { 10983 const auto *VD = dyn_cast_or_null<VarDecl>(D); 10984 // A variable must not have an incomplete type or a reference type. 10985 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 10986 return true; 10987 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 10988 !Type->isReferenceType()) { 10989 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 10990 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 10991 return true; 10992 } 10993 Type = Type.getNonReferenceType(); 10994 10995 // A list item must not be const-qualified. 10996 if (Type.isConstant(Context)) { 10997 Diag(ELoc, diag::err_omp_const_variable) 10998 << getOpenMPClauseName(OMPC_linear); 10999 if (D) { 11000 bool IsDecl = 11001 !VD || 11002 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11003 Diag(D->getLocation(), 11004 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11005 << D; 11006 } 11007 return true; 11008 } 11009 11010 // A list item must be of integral or pointer type. 11011 Type = Type.getUnqualifiedType().getCanonicalType(); 11012 const auto *Ty = Type.getTypePtrOrNull(); 11013 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 11014 !Ty->isPointerType())) { 11015 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 11016 if (D) { 11017 bool IsDecl = 11018 !VD || 11019 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11020 Diag(D->getLocation(), 11021 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11022 << D; 11023 } 11024 return true; 11025 } 11026 return false; 11027 } 11028 11029 OMPClause *Sema::ActOnOpenMPLinearClause( 11030 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 11031 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 11032 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11033 SmallVector<Expr *, 8> Vars; 11034 SmallVector<Expr *, 8> Privates; 11035 SmallVector<Expr *, 8> Inits; 11036 SmallVector<Decl *, 4> ExprCaptures; 11037 SmallVector<Expr *, 4> ExprPostUpdates; 11038 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 11039 LinKind = OMPC_LINEAR_val; 11040 for (Expr *RefExpr : VarList) { 11041 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11042 SourceLocation ELoc; 11043 SourceRange ERange; 11044 Expr *SimpleRefExpr = RefExpr; 11045 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 11046 /*AllowArraySection=*/false); 11047 if (Res.second) { 11048 // It will be analyzed later. 11049 Vars.push_back(RefExpr); 11050 Privates.push_back(nullptr); 11051 Inits.push_back(nullptr); 11052 } 11053 ValueDecl *D = Res.first; 11054 if (!D) 11055 continue; 11056 11057 QualType Type = D->getType(); 11058 auto *VD = dyn_cast<VarDecl>(D); 11059 11060 // OpenMP [2.14.3.7, linear clause] 11061 // A list-item cannot appear in more than one linear clause. 11062 // A list-item that appears in a linear clause cannot appear in any 11063 // other data-sharing attribute clause. 11064 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11065 if (DVar.RefExpr) { 11066 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11067 << getOpenMPClauseName(OMPC_linear); 11068 reportOriginalDsa(*this, DSAStack, D, DVar); 11069 continue; 11070 } 11071 11072 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 11073 continue; 11074 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11075 11076 // Build private copy of original var. 11077 VarDecl *Private = 11078 buildVarDecl(*this, ELoc, Type, D->getName(), 11079 D->hasAttrs() ? &D->getAttrs() : nullptr, 11080 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11081 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 11082 // Build var to save initial value. 11083 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 11084 Expr *InitExpr; 11085 DeclRefExpr *Ref = nullptr; 11086 if (!VD && !CurContext->isDependentContext()) { 11087 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11088 if (!isOpenMPCapturedDecl(D)) { 11089 ExprCaptures.push_back(Ref->getDecl()); 11090 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11091 ExprResult RefRes = DefaultLvalueConversion(Ref); 11092 if (!RefRes.isUsable()) 11093 continue; 11094 ExprResult PostUpdateRes = 11095 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 11096 SimpleRefExpr, RefRes.get()); 11097 if (!PostUpdateRes.isUsable()) 11098 continue; 11099 ExprPostUpdates.push_back( 11100 IgnoredValueConversions(PostUpdateRes.get()).get()); 11101 } 11102 } 11103 } 11104 if (LinKind == OMPC_LINEAR_uval) 11105 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 11106 else 11107 InitExpr = VD ? SimpleRefExpr : Ref; 11108 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 11109 /*DirectInit=*/false); 11110 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 11111 11112 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 11113 Vars.push_back((VD || CurContext->isDependentContext()) 11114 ? RefExpr->IgnoreParens() 11115 : Ref); 11116 Privates.push_back(PrivateRef); 11117 Inits.push_back(InitRef); 11118 } 11119 11120 if (Vars.empty()) 11121 return nullptr; 11122 11123 Expr *StepExpr = Step; 11124 Expr *CalcStepExpr = nullptr; 11125 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 11126 !Step->isInstantiationDependent() && 11127 !Step->containsUnexpandedParameterPack()) { 11128 SourceLocation StepLoc = Step->getBeginLoc(); 11129 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 11130 if (Val.isInvalid()) 11131 return nullptr; 11132 StepExpr = Val.get(); 11133 11134 // Build var to save the step value. 11135 VarDecl *SaveVar = 11136 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 11137 ExprResult SaveRef = 11138 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 11139 ExprResult CalcStep = 11140 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 11141 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 11142 11143 // Warn about zero linear step (it would be probably better specified as 11144 // making corresponding variables 'const'). 11145 llvm::APSInt Result; 11146 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 11147 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 11148 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 11149 << (Vars.size() > 1); 11150 if (!IsConstant && CalcStep.isUsable()) { 11151 // Calculate the step beforehand instead of doing this on each iteration. 11152 // (This is not used if the number of iterations may be kfold-ed). 11153 CalcStepExpr = CalcStep.get(); 11154 } 11155 } 11156 11157 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 11158 ColonLoc, EndLoc, Vars, Privates, Inits, 11159 StepExpr, CalcStepExpr, 11160 buildPreInits(Context, ExprCaptures), 11161 buildPostUpdate(*this, ExprPostUpdates)); 11162 } 11163 11164 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 11165 Expr *NumIterations, Sema &SemaRef, 11166 Scope *S, DSAStackTy *Stack) { 11167 // Walk the vars and build update/final expressions for the CodeGen. 11168 SmallVector<Expr *, 8> Updates; 11169 SmallVector<Expr *, 8> Finals; 11170 Expr *Step = Clause.getStep(); 11171 Expr *CalcStep = Clause.getCalcStep(); 11172 // OpenMP [2.14.3.7, linear clause] 11173 // If linear-step is not specified it is assumed to be 1. 11174 if (!Step) 11175 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 11176 else if (CalcStep) 11177 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 11178 bool HasErrors = false; 11179 auto CurInit = Clause.inits().begin(); 11180 auto CurPrivate = Clause.privates().begin(); 11181 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 11182 for (Expr *RefExpr : Clause.varlists()) { 11183 SourceLocation ELoc; 11184 SourceRange ERange; 11185 Expr *SimpleRefExpr = RefExpr; 11186 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 11187 /*AllowArraySection=*/false); 11188 ValueDecl *D = Res.first; 11189 if (Res.second || !D) { 11190 Updates.push_back(nullptr); 11191 Finals.push_back(nullptr); 11192 HasErrors = true; 11193 continue; 11194 } 11195 auto &&Info = Stack->isLoopControlVariable(D); 11196 // OpenMP [2.15.11, distribute simd Construct] 11197 // A list item may not appear in a linear clause, unless it is the loop 11198 // iteration variable. 11199 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 11200 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 11201 SemaRef.Diag(ELoc, 11202 diag::err_omp_linear_distribute_var_non_loop_iteration); 11203 Updates.push_back(nullptr); 11204 Finals.push_back(nullptr); 11205 HasErrors = true; 11206 continue; 11207 } 11208 Expr *InitExpr = *CurInit; 11209 11210 // Build privatized reference to the current linear var. 11211 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 11212 Expr *CapturedRef; 11213 if (LinKind == OMPC_LINEAR_uval) 11214 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 11215 else 11216 CapturedRef = 11217 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 11218 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 11219 /*RefersToCapture=*/true); 11220 11221 // Build update: Var = InitExpr + IV * Step 11222 ExprResult Update; 11223 if (!Info.first) 11224 Update = 11225 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 11226 InitExpr, IV, Step, /* Subtract */ false); 11227 else 11228 Update = *CurPrivate; 11229 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 11230 /*DiscardedValue=*/true); 11231 11232 // Build final: Var = InitExpr + NumIterations * Step 11233 ExprResult Final; 11234 if (!Info.first) 11235 Final = 11236 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 11237 InitExpr, NumIterations, Step, /*Subtract=*/false); 11238 else 11239 Final = *CurPrivate; 11240 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 11241 /*DiscardedValue=*/true); 11242 11243 if (!Update.isUsable() || !Final.isUsable()) { 11244 Updates.push_back(nullptr); 11245 Finals.push_back(nullptr); 11246 HasErrors = true; 11247 } else { 11248 Updates.push_back(Update.get()); 11249 Finals.push_back(Final.get()); 11250 } 11251 ++CurInit; 11252 ++CurPrivate; 11253 } 11254 Clause.setUpdates(Updates); 11255 Clause.setFinals(Finals); 11256 return HasErrors; 11257 } 11258 11259 OMPClause *Sema::ActOnOpenMPAlignedClause( 11260 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 11261 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11262 SmallVector<Expr *, 8> Vars; 11263 for (Expr *RefExpr : VarList) { 11264 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11265 SourceLocation ELoc; 11266 SourceRange ERange; 11267 Expr *SimpleRefExpr = RefExpr; 11268 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 11269 /*AllowArraySection=*/false); 11270 if (Res.second) { 11271 // It will be analyzed later. 11272 Vars.push_back(RefExpr); 11273 } 11274 ValueDecl *D = Res.first; 11275 if (!D) 11276 continue; 11277 11278 QualType QType = D->getType(); 11279 auto *VD = dyn_cast<VarDecl>(D); 11280 11281 // OpenMP [2.8.1, simd construct, Restrictions] 11282 // The type of list items appearing in the aligned clause must be 11283 // array, pointer, reference to array, or reference to pointer. 11284 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11285 const Type *Ty = QType.getTypePtrOrNull(); 11286 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 11287 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 11288 << QType << getLangOpts().CPlusPlus << ERange; 11289 bool IsDecl = 11290 !VD || 11291 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11292 Diag(D->getLocation(), 11293 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11294 << D; 11295 continue; 11296 } 11297 11298 // OpenMP [2.8.1, simd construct, Restrictions] 11299 // A list-item cannot appear in more than one aligned clause. 11300 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 11301 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 11302 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 11303 << getOpenMPClauseName(OMPC_aligned); 11304 continue; 11305 } 11306 11307 DeclRefExpr *Ref = nullptr; 11308 if (!VD && isOpenMPCapturedDecl(D)) 11309 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11310 Vars.push_back(DefaultFunctionArrayConversion( 11311 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 11312 .get()); 11313 } 11314 11315 // OpenMP [2.8.1, simd construct, Description] 11316 // The parameter of the aligned clause, alignment, must be a constant 11317 // positive integer expression. 11318 // If no optional parameter is specified, implementation-defined default 11319 // alignments for SIMD instructions on the target platforms are assumed. 11320 if (Alignment != nullptr) { 11321 ExprResult AlignResult = 11322 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 11323 if (AlignResult.isInvalid()) 11324 return nullptr; 11325 Alignment = AlignResult.get(); 11326 } 11327 if (Vars.empty()) 11328 return nullptr; 11329 11330 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 11331 EndLoc, Vars, Alignment); 11332 } 11333 11334 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 11335 SourceLocation StartLoc, 11336 SourceLocation LParenLoc, 11337 SourceLocation EndLoc) { 11338 SmallVector<Expr *, 8> Vars; 11339 SmallVector<Expr *, 8> SrcExprs; 11340 SmallVector<Expr *, 8> DstExprs; 11341 SmallVector<Expr *, 8> AssignmentOps; 11342 for (Expr *RefExpr : VarList) { 11343 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 11344 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 11345 // It will be analyzed later. 11346 Vars.push_back(RefExpr); 11347 SrcExprs.push_back(nullptr); 11348 DstExprs.push_back(nullptr); 11349 AssignmentOps.push_back(nullptr); 11350 continue; 11351 } 11352 11353 SourceLocation ELoc = RefExpr->getExprLoc(); 11354 // OpenMP [2.1, C/C++] 11355 // A list item is a variable name. 11356 // OpenMP [2.14.4.1, Restrictions, p.1] 11357 // A list item that appears in a copyin clause must be threadprivate. 11358 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 11359 if (!DE || !isa<VarDecl>(DE->getDecl())) { 11360 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 11361 << 0 << RefExpr->getSourceRange(); 11362 continue; 11363 } 11364 11365 Decl *D = DE->getDecl(); 11366 auto *VD = cast<VarDecl>(D); 11367 11368 QualType Type = VD->getType(); 11369 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 11370 // It will be analyzed later. 11371 Vars.push_back(DE); 11372 SrcExprs.push_back(nullptr); 11373 DstExprs.push_back(nullptr); 11374 AssignmentOps.push_back(nullptr); 11375 continue; 11376 } 11377 11378 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 11379 // A list item that appears in a copyin clause must be threadprivate. 11380 if (!DSAStack->isThreadPrivate(VD)) { 11381 Diag(ELoc, diag::err_omp_required_access) 11382 << getOpenMPClauseName(OMPC_copyin) 11383 << getOpenMPDirectiveName(OMPD_threadprivate); 11384 continue; 11385 } 11386 11387 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11388 // A variable of class type (or array thereof) that appears in a 11389 // copyin clause requires an accessible, unambiguous copy assignment 11390 // operator for the class type. 11391 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11392 VarDecl *SrcVD = 11393 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 11394 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11395 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 11396 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 11397 VarDecl *DstVD = 11398 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 11399 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11400 DeclRefExpr *PseudoDstExpr = 11401 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 11402 // For arrays generate assignment operation for single element and replace 11403 // it by the original array element in CodeGen. 11404 ExprResult AssignmentOp = 11405 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 11406 PseudoSrcExpr); 11407 if (AssignmentOp.isInvalid()) 11408 continue; 11409 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 11410 /*DiscardedValue=*/true); 11411 if (AssignmentOp.isInvalid()) 11412 continue; 11413 11414 DSAStack->addDSA(VD, DE, OMPC_copyin); 11415 Vars.push_back(DE); 11416 SrcExprs.push_back(PseudoSrcExpr); 11417 DstExprs.push_back(PseudoDstExpr); 11418 AssignmentOps.push_back(AssignmentOp.get()); 11419 } 11420 11421 if (Vars.empty()) 11422 return nullptr; 11423 11424 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11425 SrcExprs, DstExprs, AssignmentOps); 11426 } 11427 11428 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 11429 SourceLocation StartLoc, 11430 SourceLocation LParenLoc, 11431 SourceLocation EndLoc) { 11432 SmallVector<Expr *, 8> Vars; 11433 SmallVector<Expr *, 8> SrcExprs; 11434 SmallVector<Expr *, 8> DstExprs; 11435 SmallVector<Expr *, 8> AssignmentOps; 11436 for (Expr *RefExpr : VarList) { 11437 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11438 SourceLocation ELoc; 11439 SourceRange ERange; 11440 Expr *SimpleRefExpr = RefExpr; 11441 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 11442 /*AllowArraySection=*/false); 11443 if (Res.second) { 11444 // It will be analyzed later. 11445 Vars.push_back(RefExpr); 11446 SrcExprs.push_back(nullptr); 11447 DstExprs.push_back(nullptr); 11448 AssignmentOps.push_back(nullptr); 11449 } 11450 ValueDecl *D = Res.first; 11451 if (!D) 11452 continue; 11453 11454 QualType Type = D->getType(); 11455 auto *VD = dyn_cast<VarDecl>(D); 11456 11457 // OpenMP [2.14.4.2, Restrictions, p.2] 11458 // A list item that appears in a copyprivate clause may not appear in a 11459 // private or firstprivate clause on the single construct. 11460 if (!VD || !DSAStack->isThreadPrivate(VD)) { 11461 DSAStackTy::DSAVarData DVar = 11462 DSAStack->getTopDSA(D, /*FromParent=*/false); 11463 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 11464 DVar.RefExpr) { 11465 Diag(ELoc, diag::err_omp_wrong_dsa) 11466 << getOpenMPClauseName(DVar.CKind) 11467 << getOpenMPClauseName(OMPC_copyprivate); 11468 reportOriginalDsa(*this, DSAStack, D, DVar); 11469 continue; 11470 } 11471 11472 // OpenMP [2.11.4.2, Restrictions, p.1] 11473 // All list items that appear in a copyprivate clause must be either 11474 // threadprivate or private in the enclosing context. 11475 if (DVar.CKind == OMPC_unknown) { 11476 DVar = DSAStack->getImplicitDSA(D, false); 11477 if (DVar.CKind == OMPC_shared) { 11478 Diag(ELoc, diag::err_omp_required_access) 11479 << getOpenMPClauseName(OMPC_copyprivate) 11480 << "threadprivate or private in the enclosing context"; 11481 reportOriginalDsa(*this, DSAStack, D, DVar); 11482 continue; 11483 } 11484 } 11485 } 11486 11487 // Variably modified types are not supported. 11488 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 11489 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11490 << getOpenMPClauseName(OMPC_copyprivate) << Type 11491 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11492 bool IsDecl = 11493 !VD || 11494 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11495 Diag(D->getLocation(), 11496 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11497 << D; 11498 continue; 11499 } 11500 11501 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11502 // A variable of class type (or array thereof) that appears in a 11503 // copyin clause requires an accessible, unambiguous copy assignment 11504 // operator for the class type. 11505 Type = Context.getBaseElementType(Type.getNonReferenceType()) 11506 .getUnqualifiedType(); 11507 VarDecl *SrcVD = 11508 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 11509 D->hasAttrs() ? &D->getAttrs() : nullptr); 11510 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 11511 VarDecl *DstVD = 11512 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 11513 D->hasAttrs() ? &D->getAttrs() : nullptr); 11514 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11515 ExprResult AssignmentOp = BuildBinOp( 11516 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 11517 if (AssignmentOp.isInvalid()) 11518 continue; 11519 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 11520 /*DiscardedValue=*/true); 11521 if (AssignmentOp.isInvalid()) 11522 continue; 11523 11524 // No need to mark vars as copyprivate, they are already threadprivate or 11525 // implicitly private. 11526 assert(VD || isOpenMPCapturedDecl(D)); 11527 Vars.push_back( 11528 VD ? RefExpr->IgnoreParens() 11529 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 11530 SrcExprs.push_back(PseudoSrcExpr); 11531 DstExprs.push_back(PseudoDstExpr); 11532 AssignmentOps.push_back(AssignmentOp.get()); 11533 } 11534 11535 if (Vars.empty()) 11536 return nullptr; 11537 11538 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11539 Vars, SrcExprs, DstExprs, AssignmentOps); 11540 } 11541 11542 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 11543 SourceLocation StartLoc, 11544 SourceLocation LParenLoc, 11545 SourceLocation EndLoc) { 11546 if (VarList.empty()) 11547 return nullptr; 11548 11549 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 11550 } 11551 11552 OMPClause * 11553 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 11554 SourceLocation DepLoc, SourceLocation ColonLoc, 11555 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 11556 SourceLocation LParenLoc, SourceLocation EndLoc) { 11557 if (DSAStack->getCurrentDirective() == OMPD_ordered && 11558 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 11559 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 11560 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 11561 return nullptr; 11562 } 11563 if (DSAStack->getCurrentDirective() != OMPD_ordered && 11564 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 11565 DepKind == OMPC_DEPEND_sink)) { 11566 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 11567 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 11568 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 11569 /*Last=*/OMPC_DEPEND_unknown, Except) 11570 << getOpenMPClauseName(OMPC_depend); 11571 return nullptr; 11572 } 11573 SmallVector<Expr *, 8> Vars; 11574 DSAStackTy::OperatorOffsetTy OpsOffs; 11575 llvm::APSInt DepCounter(/*BitWidth=*/32); 11576 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 11577 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 11578 if (const Expr *OrderedCountExpr = 11579 DSAStack->getParentOrderedRegionParam().first) { 11580 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 11581 TotalDepCount.setIsUnsigned(/*Val=*/true); 11582 } 11583 } 11584 for (Expr *RefExpr : VarList) { 11585 assert(RefExpr && "NULL expr in OpenMP shared clause."); 11586 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 11587 // It will be analyzed later. 11588 Vars.push_back(RefExpr); 11589 continue; 11590 } 11591 11592 SourceLocation ELoc = RefExpr->getExprLoc(); 11593 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 11594 if (DepKind == OMPC_DEPEND_sink) { 11595 if (DSAStack->getParentOrderedRegionParam().first && 11596 DepCounter >= TotalDepCount) { 11597 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 11598 continue; 11599 } 11600 ++DepCounter; 11601 // OpenMP [2.13.9, Summary] 11602 // depend(dependence-type : vec), where dependence-type is: 11603 // 'sink' and where vec is the iteration vector, which has the form: 11604 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 11605 // where n is the value specified by the ordered clause in the loop 11606 // directive, xi denotes the loop iteration variable of the i-th nested 11607 // loop associated with the loop directive, and di is a constant 11608 // non-negative integer. 11609 if (CurContext->isDependentContext()) { 11610 // It will be analyzed later. 11611 Vars.push_back(RefExpr); 11612 continue; 11613 } 11614 SimpleExpr = SimpleExpr->IgnoreImplicit(); 11615 OverloadedOperatorKind OOK = OO_None; 11616 SourceLocation OOLoc; 11617 Expr *LHS = SimpleExpr; 11618 Expr *RHS = nullptr; 11619 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 11620 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 11621 OOLoc = BO->getOperatorLoc(); 11622 LHS = BO->getLHS()->IgnoreParenImpCasts(); 11623 RHS = BO->getRHS()->IgnoreParenImpCasts(); 11624 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 11625 OOK = OCE->getOperator(); 11626 OOLoc = OCE->getOperatorLoc(); 11627 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 11628 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 11629 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 11630 OOK = MCE->getMethodDecl() 11631 ->getNameInfo() 11632 .getName() 11633 .getCXXOverloadedOperator(); 11634 OOLoc = MCE->getCallee()->getExprLoc(); 11635 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 11636 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 11637 } 11638 SourceLocation ELoc; 11639 SourceRange ERange; 11640 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 11641 /*AllowArraySection=*/false); 11642 if (Res.second) { 11643 // It will be analyzed later. 11644 Vars.push_back(RefExpr); 11645 } 11646 ValueDecl *D = Res.first; 11647 if (!D) 11648 continue; 11649 11650 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 11651 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 11652 continue; 11653 } 11654 if (RHS) { 11655 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 11656 RHS, OMPC_depend, /*StrictlyPositive=*/false); 11657 if (RHSRes.isInvalid()) 11658 continue; 11659 } 11660 if (!CurContext->isDependentContext() && 11661 DSAStack->getParentOrderedRegionParam().first && 11662 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 11663 const ValueDecl *VD = 11664 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 11665 if (VD) 11666 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 11667 << 1 << VD; 11668 else 11669 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 11670 continue; 11671 } 11672 OpsOffs.emplace_back(RHS, OOK); 11673 } else { 11674 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 11675 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 11676 (ASE && 11677 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 11678 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 11679 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 11680 << RefExpr->getSourceRange(); 11681 continue; 11682 } 11683 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 11684 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 11685 ExprResult Res = 11686 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 11687 getDiagnostics().setSuppressAllDiagnostics(Suppress); 11688 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 11689 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 11690 << RefExpr->getSourceRange(); 11691 continue; 11692 } 11693 } 11694 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 11695 } 11696 11697 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 11698 TotalDepCount > VarList.size() && 11699 DSAStack->getParentOrderedRegionParam().first && 11700 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 11701 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 11702 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 11703 } 11704 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 11705 Vars.empty()) 11706 return nullptr; 11707 11708 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11709 DepKind, DepLoc, ColonLoc, Vars, 11710 TotalDepCount.getZExtValue()); 11711 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 11712 DSAStack->isParentOrderedRegion()) 11713 DSAStack->addDoacrossDependClause(C, OpsOffs); 11714 return C; 11715 } 11716 11717 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 11718 SourceLocation LParenLoc, 11719 SourceLocation EndLoc) { 11720 Expr *ValExpr = Device; 11721 Stmt *HelperValStmt = nullptr; 11722 11723 // OpenMP [2.9.1, Restrictions] 11724 // The device expression must evaluate to a non-negative integer value. 11725 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 11726 /*StrictlyPositive=*/false)) 11727 return nullptr; 11728 11729 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11730 OpenMPDirectiveKind CaptureRegion = 11731 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 11732 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11733 ValExpr = MakeFullExpr(ValExpr).get(); 11734 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11735 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11736 HelperValStmt = buildPreInits(Context, Captures); 11737 } 11738 11739 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 11740 StartLoc, LParenLoc, EndLoc); 11741 } 11742 11743 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 11744 DSAStackTy *Stack, QualType QTy, 11745 bool FullCheck = true) { 11746 NamedDecl *ND; 11747 if (QTy->isIncompleteType(&ND)) { 11748 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 11749 return false; 11750 } 11751 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 11752 !QTy.isTrivialType(SemaRef.Context)) 11753 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 11754 return true; 11755 } 11756 11757 /// Return true if it can be proven that the provided array expression 11758 /// (array section or array subscript) does NOT specify the whole size of the 11759 /// array whose base type is \a BaseQTy. 11760 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 11761 const Expr *E, 11762 QualType BaseQTy) { 11763 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 11764 11765 // If this is an array subscript, it refers to the whole size if the size of 11766 // the dimension is constant and equals 1. Also, an array section assumes the 11767 // format of an array subscript if no colon is used. 11768 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 11769 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 11770 return ATy->getSize().getSExtValue() != 1; 11771 // Size can't be evaluated statically. 11772 return false; 11773 } 11774 11775 assert(OASE && "Expecting array section if not an array subscript."); 11776 const Expr *LowerBound = OASE->getLowerBound(); 11777 const Expr *Length = OASE->getLength(); 11778 11779 // If there is a lower bound that does not evaluates to zero, we are not 11780 // covering the whole dimension. 11781 if (LowerBound) { 11782 llvm::APSInt ConstLowerBound; 11783 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 11784 return false; // Can't get the integer value as a constant. 11785 if (ConstLowerBound.getSExtValue()) 11786 return true; 11787 } 11788 11789 // If we don't have a length we covering the whole dimension. 11790 if (!Length) 11791 return false; 11792 11793 // If the base is a pointer, we don't have a way to get the size of the 11794 // pointee. 11795 if (BaseQTy->isPointerType()) 11796 return false; 11797 11798 // We can only check if the length is the same as the size of the dimension 11799 // if we have a constant array. 11800 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 11801 if (!CATy) 11802 return false; 11803 11804 llvm::APSInt ConstLength; 11805 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 11806 return false; // Can't get the integer value as a constant. 11807 11808 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 11809 } 11810 11811 // Return true if it can be proven that the provided array expression (array 11812 // section or array subscript) does NOT specify a single element of the array 11813 // whose base type is \a BaseQTy. 11814 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 11815 const Expr *E, 11816 QualType BaseQTy) { 11817 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 11818 11819 // An array subscript always refer to a single element. Also, an array section 11820 // assumes the format of an array subscript if no colon is used. 11821 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 11822 return false; 11823 11824 assert(OASE && "Expecting array section if not an array subscript."); 11825 const Expr *Length = OASE->getLength(); 11826 11827 // If we don't have a length we have to check if the array has unitary size 11828 // for this dimension. Also, we should always expect a length if the base type 11829 // is pointer. 11830 if (!Length) { 11831 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 11832 return ATy->getSize().getSExtValue() != 1; 11833 // We cannot assume anything. 11834 return false; 11835 } 11836 11837 // Check if the length evaluates to 1. 11838 llvm::APSInt ConstLength; 11839 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 11840 return false; // Can't get the integer value as a constant. 11841 11842 return ConstLength.getSExtValue() != 1; 11843 } 11844 11845 // Return the expression of the base of the mappable expression or null if it 11846 // cannot be determined and do all the necessary checks to see if the expression 11847 // is valid as a standalone mappable expression. In the process, record all the 11848 // components of the expression. 11849 static const Expr *checkMapClauseExpressionBase( 11850 Sema &SemaRef, Expr *E, 11851 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 11852 OpenMPClauseKind CKind, bool NoDiagnose) { 11853 SourceLocation ELoc = E->getExprLoc(); 11854 SourceRange ERange = E->getSourceRange(); 11855 11856 // The base of elements of list in a map clause have to be either: 11857 // - a reference to variable or field. 11858 // - a member expression. 11859 // - an array expression. 11860 // 11861 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 11862 // reference to 'r'. 11863 // 11864 // If we have: 11865 // 11866 // struct SS { 11867 // Bla S; 11868 // foo() { 11869 // #pragma omp target map (S.Arr[:12]); 11870 // } 11871 // } 11872 // 11873 // We want to retrieve the member expression 'this->S'; 11874 11875 const Expr *RelevantExpr = nullptr; 11876 11877 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 11878 // If a list item is an array section, it must specify contiguous storage. 11879 // 11880 // For this restriction it is sufficient that we make sure only references 11881 // to variables or fields and array expressions, and that no array sections 11882 // exist except in the rightmost expression (unless they cover the whole 11883 // dimension of the array). E.g. these would be invalid: 11884 // 11885 // r.ArrS[3:5].Arr[6:7] 11886 // 11887 // r.ArrS[3:5].x 11888 // 11889 // but these would be valid: 11890 // r.ArrS[3].Arr[6:7] 11891 // 11892 // r.ArrS[3].x 11893 11894 bool AllowUnitySizeArraySection = true; 11895 bool AllowWholeSizeArraySection = true; 11896 11897 while (!RelevantExpr) { 11898 E = E->IgnoreParenImpCasts(); 11899 11900 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 11901 if (!isa<VarDecl>(CurE->getDecl())) 11902 return nullptr; 11903 11904 RelevantExpr = CurE; 11905 11906 // If we got a reference to a declaration, we should not expect any array 11907 // section before that. 11908 AllowUnitySizeArraySection = false; 11909 AllowWholeSizeArraySection = false; 11910 11911 // Record the component. 11912 CurComponents.emplace_back(CurE, CurE->getDecl()); 11913 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 11914 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 11915 11916 if (isa<CXXThisExpr>(BaseE)) 11917 // We found a base expression: this->Val. 11918 RelevantExpr = CurE; 11919 else 11920 E = BaseE; 11921 11922 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 11923 if (!NoDiagnose) { 11924 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 11925 << CurE->getSourceRange(); 11926 return nullptr; 11927 } 11928 if (RelevantExpr) 11929 return nullptr; 11930 continue; 11931 } 11932 11933 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 11934 11935 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 11936 // A bit-field cannot appear in a map clause. 11937 // 11938 if (FD->isBitField()) { 11939 if (!NoDiagnose) { 11940 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 11941 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 11942 return nullptr; 11943 } 11944 if (RelevantExpr) 11945 return nullptr; 11946 continue; 11947 } 11948 11949 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11950 // If the type of a list item is a reference to a type T then the type 11951 // will be considered to be T for all purposes of this clause. 11952 QualType CurType = BaseE->getType().getNonReferenceType(); 11953 11954 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 11955 // A list item cannot be a variable that is a member of a structure with 11956 // a union type. 11957 // 11958 if (CurType->isUnionType()) { 11959 if (!NoDiagnose) { 11960 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 11961 << CurE->getSourceRange(); 11962 return nullptr; 11963 } 11964 continue; 11965 } 11966 11967 // If we got a member expression, we should not expect any array section 11968 // before that: 11969 // 11970 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 11971 // If a list item is an element of a structure, only the rightmost symbol 11972 // of the variable reference can be an array section. 11973 // 11974 AllowUnitySizeArraySection = false; 11975 AllowWholeSizeArraySection = false; 11976 11977 // Record the component. 11978 CurComponents.emplace_back(CurE, FD); 11979 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 11980 E = CurE->getBase()->IgnoreParenImpCasts(); 11981 11982 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 11983 if (!NoDiagnose) { 11984 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 11985 << 0 << CurE->getSourceRange(); 11986 return nullptr; 11987 } 11988 continue; 11989 } 11990 11991 // If we got an array subscript that express the whole dimension we 11992 // can have any array expressions before. If it only expressing part of 11993 // the dimension, we can only have unitary-size array expressions. 11994 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 11995 E->getType())) 11996 AllowWholeSizeArraySection = false; 11997 11998 // Record the component - we don't have any declaration associated. 11999 CurComponents.emplace_back(CurE, nullptr); 12000 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 12001 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 12002 E = CurE->getBase()->IgnoreParenImpCasts(); 12003 12004 QualType CurType = 12005 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12006 12007 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12008 // If the type of a list item is a reference to a type T then the type 12009 // will be considered to be T for all purposes of this clause. 12010 if (CurType->isReferenceType()) 12011 CurType = CurType->getPointeeType(); 12012 12013 bool IsPointer = CurType->isAnyPointerType(); 12014 12015 if (!IsPointer && !CurType->isArrayType()) { 12016 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12017 << 0 << CurE->getSourceRange(); 12018 return nullptr; 12019 } 12020 12021 bool NotWhole = 12022 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 12023 bool NotUnity = 12024 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 12025 12026 if (AllowWholeSizeArraySection) { 12027 // Any array section is currently allowed. Allowing a whole size array 12028 // section implies allowing a unity array section as well. 12029 // 12030 // If this array section refers to the whole dimension we can still 12031 // accept other array sections before this one, except if the base is a 12032 // pointer. Otherwise, only unitary sections are accepted. 12033 if (NotWhole || IsPointer) 12034 AllowWholeSizeArraySection = false; 12035 } else if (AllowUnitySizeArraySection && NotUnity) { 12036 // A unity or whole array section is not allowed and that is not 12037 // compatible with the properties of the current array section. 12038 SemaRef.Diag( 12039 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 12040 << CurE->getSourceRange(); 12041 return nullptr; 12042 } 12043 12044 // Record the component - we don't have any declaration associated. 12045 CurComponents.emplace_back(CurE, nullptr); 12046 } else { 12047 if (!NoDiagnose) { 12048 // If nothing else worked, this is not a valid map clause expression. 12049 SemaRef.Diag( 12050 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 12051 << ERange; 12052 } 12053 return nullptr; 12054 } 12055 } 12056 12057 return RelevantExpr; 12058 } 12059 12060 // Return true if expression E associated with value VD has conflicts with other 12061 // map information. 12062 static bool checkMapConflicts( 12063 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 12064 bool CurrentRegionOnly, 12065 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 12066 OpenMPClauseKind CKind) { 12067 assert(VD && E); 12068 SourceLocation ELoc = E->getExprLoc(); 12069 SourceRange ERange = E->getSourceRange(); 12070 12071 // In order to easily check the conflicts we need to match each component of 12072 // the expression under test with the components of the expressions that are 12073 // already in the stack. 12074 12075 assert(!CurComponents.empty() && "Map clause expression with no components!"); 12076 assert(CurComponents.back().getAssociatedDeclaration() == VD && 12077 "Map clause expression with unexpected base!"); 12078 12079 // Variables to help detecting enclosing problems in data environment nests. 12080 bool IsEnclosedByDataEnvironmentExpr = false; 12081 const Expr *EnclosingExpr = nullptr; 12082 12083 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 12084 VD, CurrentRegionOnly, 12085 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 12086 ERange, CKind, &EnclosingExpr, 12087 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 12088 StackComponents, 12089 OpenMPClauseKind) { 12090 assert(!StackComponents.empty() && 12091 "Map clause expression with no components!"); 12092 assert(StackComponents.back().getAssociatedDeclaration() == VD && 12093 "Map clause expression with unexpected base!"); 12094 (void)VD; 12095 12096 // The whole expression in the stack. 12097 const Expr *RE = StackComponents.front().getAssociatedExpression(); 12098 12099 // Expressions must start from the same base. Here we detect at which 12100 // point both expressions diverge from each other and see if we can 12101 // detect if the memory referred to both expressions is contiguous and 12102 // do not overlap. 12103 auto CI = CurComponents.rbegin(); 12104 auto CE = CurComponents.rend(); 12105 auto SI = StackComponents.rbegin(); 12106 auto SE = StackComponents.rend(); 12107 for (; CI != CE && SI != SE; ++CI, ++SI) { 12108 12109 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 12110 // At most one list item can be an array item derived from a given 12111 // variable in map clauses of the same construct. 12112 if (CurrentRegionOnly && 12113 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 12114 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 12115 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 12116 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 12117 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 12118 diag::err_omp_multiple_array_items_in_map_clause) 12119 << CI->getAssociatedExpression()->getSourceRange(); 12120 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 12121 diag::note_used_here) 12122 << SI->getAssociatedExpression()->getSourceRange(); 12123 return true; 12124 } 12125 12126 // Do both expressions have the same kind? 12127 if (CI->getAssociatedExpression()->getStmtClass() != 12128 SI->getAssociatedExpression()->getStmtClass()) 12129 break; 12130 12131 // Are we dealing with different variables/fields? 12132 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 12133 break; 12134 } 12135 // Check if the extra components of the expressions in the enclosing 12136 // data environment are redundant for the current base declaration. 12137 // If they are, the maps completely overlap, which is legal. 12138 for (; SI != SE; ++SI) { 12139 QualType Type; 12140 if (const auto *ASE = 12141 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 12142 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 12143 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 12144 SI->getAssociatedExpression())) { 12145 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 12146 Type = 12147 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12148 } 12149 if (Type.isNull() || Type->isAnyPointerType() || 12150 checkArrayExpressionDoesNotReferToWholeSize( 12151 SemaRef, SI->getAssociatedExpression(), Type)) 12152 break; 12153 } 12154 12155 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 12156 // List items of map clauses in the same construct must not share 12157 // original storage. 12158 // 12159 // If the expressions are exactly the same or one is a subset of the 12160 // other, it means they are sharing storage. 12161 if (CI == CE && SI == SE) { 12162 if (CurrentRegionOnly) { 12163 if (CKind == OMPC_map) { 12164 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 12165 } else { 12166 assert(CKind == OMPC_to || CKind == OMPC_from); 12167 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 12168 << ERange; 12169 } 12170 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12171 << RE->getSourceRange(); 12172 return true; 12173 } 12174 // If we find the same expression in the enclosing data environment, 12175 // that is legal. 12176 IsEnclosedByDataEnvironmentExpr = true; 12177 return false; 12178 } 12179 12180 QualType DerivedType = 12181 std::prev(CI)->getAssociatedDeclaration()->getType(); 12182 SourceLocation DerivedLoc = 12183 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 12184 12185 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12186 // If the type of a list item is a reference to a type T then the type 12187 // will be considered to be T for all purposes of this clause. 12188 DerivedType = DerivedType.getNonReferenceType(); 12189 12190 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 12191 // A variable for which the type is pointer and an array section 12192 // derived from that variable must not appear as list items of map 12193 // clauses of the same construct. 12194 // 12195 // Also, cover one of the cases in: 12196 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 12197 // If any part of the original storage of a list item has corresponding 12198 // storage in the device data environment, all of the original storage 12199 // must have corresponding storage in the device data environment. 12200 // 12201 if (DerivedType->isAnyPointerType()) { 12202 if (CI == CE || SI == SE) { 12203 SemaRef.Diag( 12204 DerivedLoc, 12205 diag::err_omp_pointer_mapped_along_with_derived_section) 12206 << DerivedLoc; 12207 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12208 << RE->getSourceRange(); 12209 return true; 12210 } 12211 if (CI->getAssociatedExpression()->getStmtClass() != 12212 SI->getAssociatedExpression()->getStmtClass() || 12213 CI->getAssociatedDeclaration()->getCanonicalDecl() == 12214 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 12215 assert(CI != CE && SI != SE); 12216 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 12217 << DerivedLoc; 12218 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12219 << RE->getSourceRange(); 12220 return true; 12221 } 12222 } 12223 12224 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 12225 // List items of map clauses in the same construct must not share 12226 // original storage. 12227 // 12228 // An expression is a subset of the other. 12229 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 12230 if (CKind == OMPC_map) { 12231 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 12232 } else { 12233 assert(CKind == OMPC_to || CKind == OMPC_from); 12234 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 12235 << ERange; 12236 } 12237 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12238 << RE->getSourceRange(); 12239 return true; 12240 } 12241 12242 // The current expression uses the same base as other expression in the 12243 // data environment but does not contain it completely. 12244 if (!CurrentRegionOnly && SI != SE) 12245 EnclosingExpr = RE; 12246 12247 // The current expression is a subset of the expression in the data 12248 // environment. 12249 IsEnclosedByDataEnvironmentExpr |= 12250 (!CurrentRegionOnly && CI != CE && SI == SE); 12251 12252 return false; 12253 }); 12254 12255 if (CurrentRegionOnly) 12256 return FoundError; 12257 12258 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 12259 // If any part of the original storage of a list item has corresponding 12260 // storage in the device data environment, all of the original storage must 12261 // have corresponding storage in the device data environment. 12262 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 12263 // If a list item is an element of a structure, and a different element of 12264 // the structure has a corresponding list item in the device data environment 12265 // prior to a task encountering the construct associated with the map clause, 12266 // then the list item must also have a corresponding list item in the device 12267 // data environment prior to the task encountering the construct. 12268 // 12269 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 12270 SemaRef.Diag(ELoc, 12271 diag::err_omp_original_storage_is_shared_and_does_not_contain) 12272 << ERange; 12273 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 12274 << EnclosingExpr->getSourceRange(); 12275 return true; 12276 } 12277 12278 return FoundError; 12279 } 12280 12281 namespace { 12282 // Utility struct that gathers all the related lists associated with a mappable 12283 // expression. 12284 struct MappableVarListInfo { 12285 // The list of expressions. 12286 ArrayRef<Expr *> VarList; 12287 // The list of processed expressions. 12288 SmallVector<Expr *, 16> ProcessedVarList; 12289 // The mappble components for each expression. 12290 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 12291 // The base declaration of the variable. 12292 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 12293 12294 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 12295 // We have a list of components and base declarations for each entry in the 12296 // variable list. 12297 VarComponents.reserve(VarList.size()); 12298 VarBaseDeclarations.reserve(VarList.size()); 12299 } 12300 }; 12301 } 12302 12303 // Check the validity of the provided variable list for the provided clause kind 12304 // \a CKind. In the check process the valid expressions, and mappable expression 12305 // components and variables are extracted and used to fill \a Vars, 12306 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 12307 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 12308 static void 12309 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 12310 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 12311 SourceLocation StartLoc, 12312 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 12313 bool IsMapTypeImplicit = false) { 12314 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 12315 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 12316 "Unexpected clause kind with mappable expressions!"); 12317 12318 // Keep track of the mappable components and base declarations in this clause. 12319 // Each entry in the list is going to have a list of components associated. We 12320 // record each set of the components so that we can build the clause later on. 12321 // In the end we should have the same amount of declarations and component 12322 // lists. 12323 12324 for (Expr *RE : MVLI.VarList) { 12325 assert(RE && "Null expr in omp to/from/map clause"); 12326 SourceLocation ELoc = RE->getExprLoc(); 12327 12328 const Expr *VE = RE->IgnoreParenLValueCasts(); 12329 12330 if (VE->isValueDependent() || VE->isTypeDependent() || 12331 VE->isInstantiationDependent() || 12332 VE->containsUnexpandedParameterPack()) { 12333 // We can only analyze this information once the missing information is 12334 // resolved. 12335 MVLI.ProcessedVarList.push_back(RE); 12336 continue; 12337 } 12338 12339 Expr *SimpleExpr = RE->IgnoreParenCasts(); 12340 12341 if (!RE->IgnoreParenImpCasts()->isLValue()) { 12342 SemaRef.Diag(ELoc, 12343 diag::err_omp_expected_named_var_member_or_array_expression) 12344 << RE->getSourceRange(); 12345 continue; 12346 } 12347 12348 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 12349 ValueDecl *CurDeclaration = nullptr; 12350 12351 // Obtain the array or member expression bases if required. Also, fill the 12352 // components array with all the components identified in the process. 12353 const Expr *BE = checkMapClauseExpressionBase( 12354 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 12355 if (!BE) 12356 continue; 12357 12358 assert(!CurComponents.empty() && 12359 "Invalid mappable expression information."); 12360 12361 // For the following checks, we rely on the base declaration which is 12362 // expected to be associated with the last component. The declaration is 12363 // expected to be a variable or a field (if 'this' is being mapped). 12364 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 12365 assert(CurDeclaration && "Null decl on map clause."); 12366 assert( 12367 CurDeclaration->isCanonicalDecl() && 12368 "Expecting components to have associated only canonical declarations."); 12369 12370 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 12371 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 12372 12373 assert((VD || FD) && "Only variables or fields are expected here!"); 12374 (void)FD; 12375 12376 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 12377 // threadprivate variables cannot appear in a map clause. 12378 // OpenMP 4.5 [2.10.5, target update Construct] 12379 // threadprivate variables cannot appear in a from clause. 12380 if (VD && DSAS->isThreadPrivate(VD)) { 12381 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 12382 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 12383 << getOpenMPClauseName(CKind); 12384 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 12385 continue; 12386 } 12387 12388 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12389 // A list item cannot appear in both a map clause and a data-sharing 12390 // attribute clause on the same construct. 12391 12392 // Check conflicts with other map clause expressions. We check the conflicts 12393 // with the current construct separately from the enclosing data 12394 // environment, because the restrictions are different. We only have to 12395 // check conflicts across regions for the map clauses. 12396 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12397 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 12398 break; 12399 if (CKind == OMPC_map && 12400 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12401 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 12402 break; 12403 12404 // OpenMP 4.5 [2.10.5, target update Construct] 12405 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12406 // If the type of a list item is a reference to a type T then the type will 12407 // be considered to be T for all purposes of this clause. 12408 auto I = llvm::find_if( 12409 CurComponents, 12410 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 12411 return MC.getAssociatedDeclaration(); 12412 }); 12413 assert(I != CurComponents.end() && "Null decl on map clause."); 12414 QualType Type = 12415 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 12416 12417 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 12418 // A list item in a to or from clause must have a mappable type. 12419 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12420 // A list item must have a mappable type. 12421 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 12422 DSAS, Type)) 12423 continue; 12424 12425 if (CKind == OMPC_map) { 12426 // target enter data 12427 // OpenMP [2.10.2, Restrictions, p. 99] 12428 // A map-type must be specified in all map clauses and must be either 12429 // to or alloc. 12430 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 12431 if (DKind == OMPD_target_enter_data && 12432 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 12433 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 12434 << (IsMapTypeImplicit ? 1 : 0) 12435 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 12436 << getOpenMPDirectiveName(DKind); 12437 continue; 12438 } 12439 12440 // target exit_data 12441 // OpenMP [2.10.3, Restrictions, p. 102] 12442 // A map-type must be specified in all map clauses and must be either 12443 // from, release, or delete. 12444 if (DKind == OMPD_target_exit_data && 12445 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 12446 MapType == OMPC_MAP_delete)) { 12447 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 12448 << (IsMapTypeImplicit ? 1 : 0) 12449 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 12450 << getOpenMPDirectiveName(DKind); 12451 continue; 12452 } 12453 12454 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12455 // A list item cannot appear in both a map clause and a data-sharing 12456 // attribute clause on the same construct 12457 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 12458 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 12459 if (isOpenMPPrivate(DVar.CKind)) { 12460 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12461 << getOpenMPClauseName(DVar.CKind) 12462 << getOpenMPClauseName(OMPC_map) 12463 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 12464 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 12465 continue; 12466 } 12467 } 12468 } 12469 12470 // Save the current expression. 12471 MVLI.ProcessedVarList.push_back(RE); 12472 12473 // Store the components in the stack so that they can be used to check 12474 // against other clauses later on. 12475 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 12476 /*WhereFoundClauseKind=*/OMPC_map); 12477 12478 // Save the components and declaration to create the clause. For purposes of 12479 // the clause creation, any component list that has has base 'this' uses 12480 // null as base declaration. 12481 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12482 MVLI.VarComponents.back().append(CurComponents.begin(), 12483 CurComponents.end()); 12484 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 12485 : CurDeclaration); 12486 } 12487 } 12488 12489 OMPClause * 12490 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 12491 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 12492 SourceLocation MapLoc, SourceLocation ColonLoc, 12493 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12494 SourceLocation LParenLoc, SourceLocation EndLoc) { 12495 MappableVarListInfo MVLI(VarList); 12496 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 12497 MapType, IsMapTypeImplicit); 12498 12499 // We need to produce a map clause even if we don't have variables so that 12500 // other diagnostics related with non-existing map clauses are accurate. 12501 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12502 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12503 MVLI.VarComponents, MapTypeModifier, MapType, 12504 IsMapTypeImplicit, MapLoc); 12505 } 12506 12507 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 12508 TypeResult ParsedType) { 12509 assert(ParsedType.isUsable()); 12510 12511 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 12512 if (ReductionType.isNull()) 12513 return QualType(); 12514 12515 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 12516 // A type name in a declare reduction directive cannot be a function type, an 12517 // array type, a reference type, or a type qualified with const, volatile or 12518 // restrict. 12519 if (ReductionType.hasQualifiers()) { 12520 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 12521 return QualType(); 12522 } 12523 12524 if (ReductionType->isFunctionType()) { 12525 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 12526 return QualType(); 12527 } 12528 if (ReductionType->isReferenceType()) { 12529 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 12530 return QualType(); 12531 } 12532 if (ReductionType->isArrayType()) { 12533 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 12534 return QualType(); 12535 } 12536 return ReductionType; 12537 } 12538 12539 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 12540 Scope *S, DeclContext *DC, DeclarationName Name, 12541 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 12542 AccessSpecifier AS, Decl *PrevDeclInScope) { 12543 SmallVector<Decl *, 8> Decls; 12544 Decls.reserve(ReductionTypes.size()); 12545 12546 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 12547 forRedeclarationInCurContext()); 12548 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 12549 // A reduction-identifier may not be re-declared in the current scope for the 12550 // same type or for a type that is compatible according to the base language 12551 // rules. 12552 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 12553 OMPDeclareReductionDecl *PrevDRD = nullptr; 12554 bool InCompoundScope = true; 12555 if (S != nullptr) { 12556 // Find previous declaration with the same name not referenced in other 12557 // declarations. 12558 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 12559 InCompoundScope = 12560 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 12561 LookupName(Lookup, S); 12562 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 12563 /*AllowInlineNamespace=*/false); 12564 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 12565 LookupResult::Filter Filter = Lookup.makeFilter(); 12566 while (Filter.hasNext()) { 12567 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 12568 if (InCompoundScope) { 12569 auto I = UsedAsPrevious.find(PrevDecl); 12570 if (I == UsedAsPrevious.end()) 12571 UsedAsPrevious[PrevDecl] = false; 12572 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 12573 UsedAsPrevious[D] = true; 12574 } 12575 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 12576 PrevDecl->getLocation(); 12577 } 12578 Filter.done(); 12579 if (InCompoundScope) { 12580 for (const auto &PrevData : UsedAsPrevious) { 12581 if (!PrevData.second) { 12582 PrevDRD = PrevData.first; 12583 break; 12584 } 12585 } 12586 } 12587 } else if (PrevDeclInScope != nullptr) { 12588 auto *PrevDRDInScope = PrevDRD = 12589 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 12590 do { 12591 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 12592 PrevDRDInScope->getLocation(); 12593 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 12594 } while (PrevDRDInScope != nullptr); 12595 } 12596 for (const auto &TyData : ReductionTypes) { 12597 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 12598 bool Invalid = false; 12599 if (I != PreviousRedeclTypes.end()) { 12600 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 12601 << TyData.first; 12602 Diag(I->second, diag::note_previous_definition); 12603 Invalid = true; 12604 } 12605 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 12606 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 12607 Name, TyData.first, PrevDRD); 12608 DC->addDecl(DRD); 12609 DRD->setAccess(AS); 12610 Decls.push_back(DRD); 12611 if (Invalid) 12612 DRD->setInvalidDecl(); 12613 else 12614 PrevDRD = DRD; 12615 } 12616 12617 return DeclGroupPtrTy::make( 12618 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 12619 } 12620 12621 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 12622 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12623 12624 // Enter new function scope. 12625 PushFunctionScope(); 12626 setFunctionHasBranchProtectedScope(); 12627 getCurFunction()->setHasOMPDeclareReductionCombiner(); 12628 12629 if (S != nullptr) 12630 PushDeclContext(S, DRD); 12631 else 12632 CurContext = DRD; 12633 12634 PushExpressionEvaluationContext( 12635 ExpressionEvaluationContext::PotentiallyEvaluated); 12636 12637 QualType ReductionType = DRD->getType(); 12638 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 12639 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 12640 // uses semantics of argument handles by value, but it should be passed by 12641 // reference. C lang does not support references, so pass all parameters as 12642 // pointers. 12643 // Create 'T omp_in;' variable. 12644 VarDecl *OmpInParm = 12645 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 12646 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 12647 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 12648 // uses semantics of argument handles by value, but it should be passed by 12649 // reference. C lang does not support references, so pass all parameters as 12650 // pointers. 12651 // Create 'T omp_out;' variable. 12652 VarDecl *OmpOutParm = 12653 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 12654 if (S != nullptr) { 12655 PushOnScopeChains(OmpInParm, S); 12656 PushOnScopeChains(OmpOutParm, S); 12657 } else { 12658 DRD->addDecl(OmpInParm); 12659 DRD->addDecl(OmpOutParm); 12660 } 12661 } 12662 12663 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 12664 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12665 DiscardCleanupsInEvaluationContext(); 12666 PopExpressionEvaluationContext(); 12667 12668 PopDeclContext(); 12669 PopFunctionScopeInfo(); 12670 12671 if (Combiner != nullptr) 12672 DRD->setCombiner(Combiner); 12673 else 12674 DRD->setInvalidDecl(); 12675 } 12676 12677 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 12678 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12679 12680 // Enter new function scope. 12681 PushFunctionScope(); 12682 setFunctionHasBranchProtectedScope(); 12683 12684 if (S != nullptr) 12685 PushDeclContext(S, DRD); 12686 else 12687 CurContext = DRD; 12688 12689 PushExpressionEvaluationContext( 12690 ExpressionEvaluationContext::PotentiallyEvaluated); 12691 12692 QualType ReductionType = DRD->getType(); 12693 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 12694 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 12695 // uses semantics of argument handles by value, but it should be passed by 12696 // reference. C lang does not support references, so pass all parameters as 12697 // pointers. 12698 // Create 'T omp_priv;' variable. 12699 VarDecl *OmpPrivParm = 12700 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 12701 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 12702 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 12703 // uses semantics of argument handles by value, but it should be passed by 12704 // reference. C lang does not support references, so pass all parameters as 12705 // pointers. 12706 // Create 'T omp_orig;' variable. 12707 VarDecl *OmpOrigParm = 12708 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 12709 if (S != nullptr) { 12710 PushOnScopeChains(OmpPrivParm, S); 12711 PushOnScopeChains(OmpOrigParm, S); 12712 } else { 12713 DRD->addDecl(OmpPrivParm); 12714 DRD->addDecl(OmpOrigParm); 12715 } 12716 return OmpPrivParm; 12717 } 12718 12719 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 12720 VarDecl *OmpPrivParm) { 12721 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12722 DiscardCleanupsInEvaluationContext(); 12723 PopExpressionEvaluationContext(); 12724 12725 PopDeclContext(); 12726 PopFunctionScopeInfo(); 12727 12728 if (Initializer != nullptr) { 12729 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 12730 } else if (OmpPrivParm->hasInit()) { 12731 DRD->setInitializer(OmpPrivParm->getInit(), 12732 OmpPrivParm->isDirectInit() 12733 ? OMPDeclareReductionDecl::DirectInit 12734 : OMPDeclareReductionDecl::CopyInit); 12735 } else { 12736 DRD->setInvalidDecl(); 12737 } 12738 } 12739 12740 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 12741 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 12742 for (Decl *D : DeclReductions.get()) { 12743 if (IsValid) { 12744 if (S) 12745 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 12746 /*AddToContext=*/false); 12747 } else { 12748 D->setInvalidDecl(); 12749 } 12750 } 12751 return DeclReductions; 12752 } 12753 12754 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 12755 SourceLocation StartLoc, 12756 SourceLocation LParenLoc, 12757 SourceLocation EndLoc) { 12758 Expr *ValExpr = NumTeams; 12759 Stmt *HelperValStmt = nullptr; 12760 12761 // OpenMP [teams Constrcut, Restrictions] 12762 // The num_teams expression must evaluate to a positive integer value. 12763 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 12764 /*StrictlyPositive=*/true)) 12765 return nullptr; 12766 12767 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12768 OpenMPDirectiveKind CaptureRegion = 12769 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 12770 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12771 ValExpr = MakeFullExpr(ValExpr).get(); 12772 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12773 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12774 HelperValStmt = buildPreInits(Context, Captures); 12775 } 12776 12777 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 12778 StartLoc, LParenLoc, EndLoc); 12779 } 12780 12781 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 12782 SourceLocation StartLoc, 12783 SourceLocation LParenLoc, 12784 SourceLocation EndLoc) { 12785 Expr *ValExpr = ThreadLimit; 12786 Stmt *HelperValStmt = nullptr; 12787 12788 // OpenMP [teams Constrcut, Restrictions] 12789 // The thread_limit expression must evaluate to a positive integer value. 12790 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 12791 /*StrictlyPositive=*/true)) 12792 return nullptr; 12793 12794 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12795 OpenMPDirectiveKind CaptureRegion = 12796 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 12797 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12798 ValExpr = MakeFullExpr(ValExpr).get(); 12799 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12800 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12801 HelperValStmt = buildPreInits(Context, Captures); 12802 } 12803 12804 return new (Context) OMPThreadLimitClause( 12805 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12806 } 12807 12808 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 12809 SourceLocation StartLoc, 12810 SourceLocation LParenLoc, 12811 SourceLocation EndLoc) { 12812 Expr *ValExpr = Priority; 12813 12814 // OpenMP [2.9.1, task Constrcut] 12815 // The priority-value is a non-negative numerical scalar expression. 12816 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 12817 /*StrictlyPositive=*/false)) 12818 return nullptr; 12819 12820 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12821 } 12822 12823 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 12824 SourceLocation StartLoc, 12825 SourceLocation LParenLoc, 12826 SourceLocation EndLoc) { 12827 Expr *ValExpr = Grainsize; 12828 12829 // OpenMP [2.9.2, taskloop Constrcut] 12830 // The parameter of the grainsize clause must be a positive integer 12831 // expression. 12832 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 12833 /*StrictlyPositive=*/true)) 12834 return nullptr; 12835 12836 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12837 } 12838 12839 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 12840 SourceLocation StartLoc, 12841 SourceLocation LParenLoc, 12842 SourceLocation EndLoc) { 12843 Expr *ValExpr = NumTasks; 12844 12845 // OpenMP [2.9.2, taskloop Constrcut] 12846 // The parameter of the num_tasks clause must be a positive integer 12847 // expression. 12848 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 12849 /*StrictlyPositive=*/true)) 12850 return nullptr; 12851 12852 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12853 } 12854 12855 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 12856 SourceLocation LParenLoc, 12857 SourceLocation EndLoc) { 12858 // OpenMP [2.13.2, critical construct, Description] 12859 // ... where hint-expression is an integer constant expression that evaluates 12860 // to a valid lock hint. 12861 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 12862 if (HintExpr.isInvalid()) 12863 return nullptr; 12864 return new (Context) 12865 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 12866 } 12867 12868 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 12869 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12870 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 12871 SourceLocation EndLoc) { 12872 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 12873 std::string Values; 12874 Values += "'"; 12875 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 12876 Values += "'"; 12877 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12878 << Values << getOpenMPClauseName(OMPC_dist_schedule); 12879 return nullptr; 12880 } 12881 Expr *ValExpr = ChunkSize; 12882 Stmt *HelperValStmt = nullptr; 12883 if (ChunkSize) { 12884 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12885 !ChunkSize->isInstantiationDependent() && 12886 !ChunkSize->containsUnexpandedParameterPack()) { 12887 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12888 ExprResult Val = 12889 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12890 if (Val.isInvalid()) 12891 return nullptr; 12892 12893 ValExpr = Val.get(); 12894 12895 // OpenMP [2.7.1, Restrictions] 12896 // chunk_size must be a loop invariant integer expression with a positive 12897 // value. 12898 llvm::APSInt Result; 12899 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12900 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12901 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12902 << "dist_schedule" << ChunkSize->getSourceRange(); 12903 return nullptr; 12904 } 12905 } else if (getOpenMPCaptureRegionForClause( 12906 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 12907 OMPD_unknown && 12908 !CurContext->isDependentContext()) { 12909 ValExpr = MakeFullExpr(ValExpr).get(); 12910 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12911 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12912 HelperValStmt = buildPreInits(Context, Captures); 12913 } 12914 } 12915 } 12916 12917 return new (Context) 12918 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 12919 Kind, ValExpr, HelperValStmt); 12920 } 12921 12922 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 12923 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 12924 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 12925 SourceLocation KindLoc, SourceLocation EndLoc) { 12926 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 12927 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 12928 std::string Value; 12929 SourceLocation Loc; 12930 Value += "'"; 12931 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 12932 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 12933 OMPC_DEFAULTMAP_MODIFIER_tofrom); 12934 Loc = MLoc; 12935 } else { 12936 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 12937 OMPC_DEFAULTMAP_scalar); 12938 Loc = KindLoc; 12939 } 12940 Value += "'"; 12941 Diag(Loc, diag::err_omp_unexpected_clause_value) 12942 << Value << getOpenMPClauseName(OMPC_defaultmap); 12943 return nullptr; 12944 } 12945 DSAStack->setDefaultDMAToFromScalar(StartLoc); 12946 12947 return new (Context) 12948 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 12949 } 12950 12951 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 12952 DeclContext *CurLexicalContext = getCurLexicalContext(); 12953 if (!CurLexicalContext->isFileContext() && 12954 !CurLexicalContext->isExternCContext() && 12955 !CurLexicalContext->isExternCXXContext() && 12956 !isa<CXXRecordDecl>(CurLexicalContext) && 12957 !isa<ClassTemplateDecl>(CurLexicalContext) && 12958 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 12959 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 12960 Diag(Loc, diag::err_omp_region_not_file_context); 12961 return false; 12962 } 12963 if (IsInOpenMPDeclareTargetContext) { 12964 Diag(Loc, diag::err_omp_enclosed_declare_target); 12965 return false; 12966 } 12967 12968 IsInOpenMPDeclareTargetContext = true; 12969 return true; 12970 } 12971 12972 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 12973 assert(IsInOpenMPDeclareTargetContext && 12974 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 12975 IsInOpenMPDeclareTargetContext = false; 12976 } 12977 12978 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 12979 CXXScopeSpec &ScopeSpec, 12980 const DeclarationNameInfo &Id, 12981 OMPDeclareTargetDeclAttr::MapTypeTy MT, 12982 NamedDeclSetType &SameDirectiveDecls) { 12983 LookupResult Lookup(*this, Id, LookupOrdinaryName); 12984 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 12985 12986 if (Lookup.isAmbiguous()) 12987 return; 12988 Lookup.suppressDiagnostics(); 12989 12990 if (!Lookup.isSingleResult()) { 12991 if (TypoCorrection Corrected = 12992 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 12993 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 12994 CTK_ErrorRecovery)) { 12995 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 12996 << Id.getName()); 12997 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 12998 return; 12999 } 13000 13001 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 13002 return; 13003 } 13004 13005 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 13006 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 13007 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 13008 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 13009 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { 13010 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 13011 ND->addAttr(A); 13012 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13013 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 13014 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 13015 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { 13016 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 13017 << Id.getName(); 13018 } 13019 } else { 13020 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 13021 } 13022 } 13023 13024 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 13025 Sema &SemaRef, Decl *D) { 13026 if (!D) 13027 return; 13028 const Decl *LD = nullptr; 13029 if (isa<TagDecl>(D)) { 13030 LD = cast<TagDecl>(D)->getDefinition(); 13031 } else if (isa<VarDecl>(D)) { 13032 LD = cast<VarDecl>(D)->getDefinition(); 13033 13034 // If this is an implicit variable that is legal and we do not need to do 13035 // anything. 13036 if (cast<VarDecl>(D)->isImplicit()) { 13037 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 13038 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 13039 D->addAttr(A); 13040 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 13041 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 13042 return; 13043 } 13044 } else if (const auto *F = dyn_cast<FunctionDecl>(D)) { 13045 const FunctionDecl *FD = nullptr; 13046 if (cast<FunctionDecl>(D)->hasBody(FD)) { 13047 LD = FD; 13048 // If the definition is associated with the current declaration in the 13049 // target region (it can be e.g. a lambda) that is legal and we do not 13050 // need to do anything else. 13051 if (LD == D) { 13052 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 13053 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 13054 D->addAttr(A); 13055 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 13056 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 13057 return; 13058 } 13059 } else if (F->isFunctionTemplateSpecialization() && 13060 F->getTemplateSpecializationKind() == 13061 TSK_ImplicitInstantiation) { 13062 // Check if the function is implicitly instantiated from the template 13063 // defined in the declare target region. 13064 const FunctionTemplateDecl *FTD = F->getPrimaryTemplate(); 13065 if (FTD && FTD->hasAttr<OMPDeclareTargetDeclAttr>()) 13066 return; 13067 } 13068 } 13069 if (!LD) 13070 LD = D; 13071 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 13072 ((isa<VarDecl>(LD) && !isa<ParmVarDecl>(LD)) || isa<FunctionDecl>(LD))) { 13073 // Outlined declaration is not declared target. 13074 if (!isa<FunctionDecl>(LD)) { 13075 if (LD->isOutOfLine()) { 13076 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 13077 SemaRef.Diag(SL, diag::note_used_here) << SR; 13078 } else { 13079 const DeclContext *DC = LD->getDeclContext(); 13080 while (DC && 13081 (!isa<FunctionDecl>(DC) || 13082 !cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())) 13083 DC = DC->getParent(); 13084 if (DC) 13085 return; 13086 13087 // Is not declared in target context. 13088 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 13089 SemaRef.Diag(SL, diag::note_used_here) << SR; 13090 } 13091 } 13092 // Mark decl as declared target to prevent further diagnostic. 13093 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 13094 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 13095 D->addAttr(A); 13096 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 13097 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 13098 } 13099 } 13100 13101 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 13102 Sema &SemaRef, DSAStackTy *Stack, 13103 ValueDecl *VD) { 13104 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 13105 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 13106 /*FullCheck=*/false); 13107 } 13108 13109 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 13110 SourceLocation IdLoc) { 13111 if (!D || D->isInvalidDecl()) 13112 return; 13113 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 13114 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 13115 if (auto *VD = dyn_cast<VarDecl>(D)) { 13116 // Only global variables can be marked as declare target. 13117 if (VD->isLocalVarDeclOrParm()) 13118 return; 13119 // 2.10.6: threadprivate variable cannot appear in a declare target 13120 // directive. 13121 if (DSAStack->isThreadPrivate(VD)) { 13122 Diag(SL, diag::err_omp_threadprivate_in_target); 13123 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 13124 return; 13125 } 13126 } 13127 if (auto *VD = dyn_cast<ValueDecl>(D)) { 13128 // Problem if any with var declared with incomplete type will be reported 13129 // as normal, so no need to check it here. 13130 if ((E || !VD->getType()->isIncompleteType()) && 13131 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 13132 // Mark decl as declared target to prevent further diagnostic. 13133 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD) || 13134 isa<FunctionTemplateDecl>(VD)) { 13135 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 13136 Context, OMPDeclareTargetDeclAttr::MT_To); 13137 VD->addAttr(A); 13138 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13139 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); 13140 } 13141 return; 13142 } 13143 } 13144 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 13145 D = FTD->getTemplatedDecl(); 13146 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 13147 if (FD->hasAttr<OMPDeclareTargetDeclAttr>() && 13148 (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() == 13149 OMPDeclareTargetDeclAttr::MT_Link)) { 13150 assert(IdLoc.isValid() && "Source location is expected"); 13151 Diag(IdLoc, diag::err_omp_function_in_link_clause); 13152 Diag(FD->getLocation(), diag::note_defined_here) << FD; 13153 return; 13154 } 13155 } 13156 if (!E) { 13157 // Checking declaration inside declare target region. 13158 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 13159 (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 13160 isa<FunctionTemplateDecl>(D))) { 13161 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 13162 Context, OMPDeclareTargetDeclAttr::MT_To); 13163 D->addAttr(A); 13164 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13165 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 13166 } 13167 return; 13168 } 13169 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 13170 } 13171 13172 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 13173 SourceLocation StartLoc, 13174 SourceLocation LParenLoc, 13175 SourceLocation EndLoc) { 13176 MappableVarListInfo MVLI(VarList); 13177 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 13178 if (MVLI.ProcessedVarList.empty()) 13179 return nullptr; 13180 13181 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13182 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13183 MVLI.VarComponents); 13184 } 13185 13186 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 13187 SourceLocation StartLoc, 13188 SourceLocation LParenLoc, 13189 SourceLocation EndLoc) { 13190 MappableVarListInfo MVLI(VarList); 13191 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 13192 if (MVLI.ProcessedVarList.empty()) 13193 return nullptr; 13194 13195 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13196 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13197 MVLI.VarComponents); 13198 } 13199 13200 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 13201 SourceLocation StartLoc, 13202 SourceLocation LParenLoc, 13203 SourceLocation EndLoc) { 13204 MappableVarListInfo MVLI(VarList); 13205 SmallVector<Expr *, 8> PrivateCopies; 13206 SmallVector<Expr *, 8> Inits; 13207 13208 for (Expr *RefExpr : VarList) { 13209 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 13210 SourceLocation ELoc; 13211 SourceRange ERange; 13212 Expr *SimpleRefExpr = RefExpr; 13213 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13214 if (Res.second) { 13215 // It will be analyzed later. 13216 MVLI.ProcessedVarList.push_back(RefExpr); 13217 PrivateCopies.push_back(nullptr); 13218 Inits.push_back(nullptr); 13219 } 13220 ValueDecl *D = Res.first; 13221 if (!D) 13222 continue; 13223 13224 QualType Type = D->getType(); 13225 Type = Type.getNonReferenceType().getUnqualifiedType(); 13226 13227 auto *VD = dyn_cast<VarDecl>(D); 13228 13229 // Item should be a pointer or reference to pointer. 13230 if (!Type->isPointerType()) { 13231 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 13232 << 0 << RefExpr->getSourceRange(); 13233 continue; 13234 } 13235 13236 // Build the private variable and the expression that refers to it. 13237 auto VDPrivate = 13238 buildVarDecl(*this, ELoc, Type, D->getName(), 13239 D->hasAttrs() ? &D->getAttrs() : nullptr, 13240 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13241 if (VDPrivate->isInvalidDecl()) 13242 continue; 13243 13244 CurContext->addDecl(VDPrivate); 13245 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13246 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13247 13248 // Add temporary variable to initialize the private copy of the pointer. 13249 VarDecl *VDInit = 13250 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 13251 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 13252 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 13253 AddInitializerToDecl(VDPrivate, 13254 DefaultLvalueConversion(VDInitRefExpr).get(), 13255 /*DirectInit=*/false); 13256 13257 // If required, build a capture to implement the privatization initialized 13258 // with the current list item value. 13259 DeclRefExpr *Ref = nullptr; 13260 if (!VD) 13261 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13262 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 13263 PrivateCopies.push_back(VDPrivateRefExpr); 13264 Inits.push_back(VDInitRefExpr); 13265 13266 // We need to add a data sharing attribute for this variable to make sure it 13267 // is correctly captured. A variable that shows up in a use_device_ptr has 13268 // similar properties of a first private variable. 13269 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13270 13271 // Create a mappable component for the list item. List items in this clause 13272 // only need a component. 13273 MVLI.VarBaseDeclarations.push_back(D); 13274 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13275 MVLI.VarComponents.back().push_back( 13276 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 13277 } 13278 13279 if (MVLI.ProcessedVarList.empty()) 13280 return nullptr; 13281 13282 return OMPUseDevicePtrClause::Create( 13283 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 13284 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 13285 } 13286 13287 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 13288 SourceLocation StartLoc, 13289 SourceLocation LParenLoc, 13290 SourceLocation EndLoc) { 13291 MappableVarListInfo MVLI(VarList); 13292 for (Expr *RefExpr : VarList) { 13293 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 13294 SourceLocation ELoc; 13295 SourceRange ERange; 13296 Expr *SimpleRefExpr = RefExpr; 13297 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13298 if (Res.second) { 13299 // It will be analyzed later. 13300 MVLI.ProcessedVarList.push_back(RefExpr); 13301 } 13302 ValueDecl *D = Res.first; 13303 if (!D) 13304 continue; 13305 13306 QualType Type = D->getType(); 13307 // item should be a pointer or array or reference to pointer or array 13308 if (!Type.getNonReferenceType()->isPointerType() && 13309 !Type.getNonReferenceType()->isArrayType()) { 13310 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 13311 << 0 << RefExpr->getSourceRange(); 13312 continue; 13313 } 13314 13315 // Check if the declaration in the clause does not show up in any data 13316 // sharing attribute. 13317 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13318 if (isOpenMPPrivate(DVar.CKind)) { 13319 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13320 << getOpenMPClauseName(DVar.CKind) 13321 << getOpenMPClauseName(OMPC_is_device_ptr) 13322 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13323 reportOriginalDsa(*this, DSAStack, D, DVar); 13324 continue; 13325 } 13326 13327 const Expr *ConflictExpr; 13328 if (DSAStack->checkMappableExprComponentListsForDecl( 13329 D, /*CurrentRegionOnly=*/true, 13330 [&ConflictExpr]( 13331 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 13332 OpenMPClauseKind) -> bool { 13333 ConflictExpr = R.front().getAssociatedExpression(); 13334 return true; 13335 })) { 13336 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 13337 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 13338 << ConflictExpr->getSourceRange(); 13339 continue; 13340 } 13341 13342 // Store the components in the stack so that they can be used to check 13343 // against other clauses later on. 13344 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 13345 DSAStack->addMappableExpressionComponents( 13346 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 13347 13348 // Record the expression we've just processed. 13349 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 13350 13351 // Create a mappable component for the list item. List items in this clause 13352 // only need a component. We use a null declaration to signal fields in 13353 // 'this'. 13354 assert((isa<DeclRefExpr>(SimpleRefExpr) || 13355 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 13356 "Unexpected device pointer expression!"); 13357 MVLI.VarBaseDeclarations.push_back( 13358 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 13359 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13360 MVLI.VarComponents.back().push_back(MC); 13361 } 13362 13363 if (MVLI.ProcessedVarList.empty()) 13364 return nullptr; 13365 13366 return OMPIsDevicePtrClause::Create( 13367 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 13368 MVLI.VarBaseDeclarations, MVLI.VarComponents); 13369 } 13370