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 NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 10072 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 10073 10074 for (auto RD : D->redecls()) { 10075 // Don't bother with extra checks if we already know this one isn't visible. 10076 if (RD == D) 10077 continue; 10078 10079 auto ND = cast<NamedDecl>(RD); 10080 if (LookupResult::isVisible(SemaRef, ND)) 10081 return ND; 10082 } 10083 10084 return nullptr; 10085 } 10086 10087 static void 10088 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId, 10089 SourceLocation Loc, QualType Ty, 10090 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 10091 // Find all of the associated namespaces and classes based on the 10092 // arguments we have. 10093 Sema::AssociatedNamespaceSet AssociatedNamespaces; 10094 Sema::AssociatedClassSet AssociatedClasses; 10095 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 10096 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 10097 AssociatedClasses); 10098 10099 // C++ [basic.lookup.argdep]p3: 10100 // Let X be the lookup set produced by unqualified lookup (3.4.1) 10101 // and let Y be the lookup set produced by argument dependent 10102 // lookup (defined as follows). If X contains [...] then Y is 10103 // empty. Otherwise Y is the set of declarations found in the 10104 // namespaces associated with the argument types as described 10105 // below. The set of declarations found by the lookup of the name 10106 // is the union of X and Y. 10107 // 10108 // Here, we compute Y and add its members to the overloaded 10109 // candidate set. 10110 for (auto *NS : AssociatedNamespaces) { 10111 // When considering an associated namespace, the lookup is the 10112 // same as the lookup performed when the associated namespace is 10113 // used as a qualifier (3.4.3.2) except that: 10114 // 10115 // -- Any using-directives in the associated namespace are 10116 // ignored. 10117 // 10118 // -- Any namespace-scope friend functions declared in 10119 // associated classes are visible within their respective 10120 // namespaces even if they are not visible during an ordinary 10121 // lookup (11.4). 10122 DeclContext::lookup_result R = NS->lookup(ReductionId.getName()); 10123 for (auto *D : R) { 10124 auto *Underlying = D; 10125 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10126 Underlying = USD->getTargetDecl(); 10127 10128 if (!isa<OMPDeclareReductionDecl>(Underlying)) 10129 continue; 10130 10131 if (!SemaRef.isVisible(D)) { 10132 D = findAcceptableDecl(SemaRef, D); 10133 if (!D) 10134 continue; 10135 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10136 Underlying = USD->getTargetDecl(); 10137 } 10138 Lookups.emplace_back(); 10139 Lookups.back().addDecl(Underlying); 10140 } 10141 } 10142 } 10143 10144 static ExprResult 10145 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 10146 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 10147 const DeclarationNameInfo &ReductionId, QualType Ty, 10148 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 10149 if (ReductionIdScopeSpec.isInvalid()) 10150 return ExprError(); 10151 SmallVector<UnresolvedSet<8>, 4> Lookups; 10152 if (S) { 10153 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10154 Lookup.suppressDiagnostics(); 10155 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 10156 NamedDecl *D = Lookup.getRepresentativeDecl(); 10157 do { 10158 S = S->getParent(); 10159 } while (S && !S->isDeclScope(D)); 10160 if (S) 10161 S = S->getParent(); 10162 Lookups.emplace_back(); 10163 Lookups.back().append(Lookup.begin(), Lookup.end()); 10164 Lookup.clear(); 10165 } 10166 } else if (auto *ULE = 10167 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 10168 Lookups.push_back(UnresolvedSet<8>()); 10169 Decl *PrevD = nullptr; 10170 for (NamedDecl *D : ULE->decls()) { 10171 if (D == PrevD) 10172 Lookups.push_back(UnresolvedSet<8>()); 10173 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 10174 Lookups.back().addDecl(DRD); 10175 PrevD = D; 10176 } 10177 } 10178 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 10179 Ty->isInstantiationDependentType() || 10180 Ty->containsUnexpandedParameterPack() || 10181 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) { 10182 return !D->isInvalidDecl() && 10183 (D->getType()->isDependentType() || 10184 D->getType()->isInstantiationDependentType() || 10185 D->getType()->containsUnexpandedParameterPack()); 10186 })) { 10187 UnresolvedSet<8> ResSet; 10188 for (const UnresolvedSet<8> &Set : Lookups) { 10189 if (Set.empty()) 10190 continue; 10191 ResSet.append(Set.begin(), Set.end()); 10192 // The last item marks the end of all declarations at the specified scope. 10193 ResSet.addDecl(Set[Set.size() - 1]); 10194 } 10195 return UnresolvedLookupExpr::Create( 10196 SemaRef.Context, /*NamingClass=*/nullptr, 10197 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 10198 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 10199 } 10200 // Lookup inside the classes. 10201 // C++ [over.match.oper]p3: 10202 // For a unary operator @ with an operand of a type whose 10203 // cv-unqualified version is T1, and for a binary operator @ with 10204 // a left operand of a type whose cv-unqualified version is T1 and 10205 // a right operand of a type whose cv-unqualified version is T2, 10206 // three sets of candidate functions, designated member 10207 // candidates, non-member candidates and built-in candidates, are 10208 // constructed as follows: 10209 // -- If T1 is a complete class type or a class currently being 10210 // defined, the set of member candidates is the result of the 10211 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 10212 // the set of member candidates is empty. 10213 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10214 Lookup.suppressDiagnostics(); 10215 if (const auto *TyRec = Ty->getAs<RecordType>()) { 10216 // Complete the type if it can be completed. 10217 // If the type is neither complete nor being defined, bail out now. 10218 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 10219 TyRec->getDecl()->getDefinition()) { 10220 Lookup.clear(); 10221 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 10222 if (Lookup.empty()) { 10223 Lookups.emplace_back(); 10224 Lookups.back().append(Lookup.begin(), Lookup.end()); 10225 } 10226 } 10227 } 10228 // Perform ADL. 10229 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 10230 if (auto *VD = filterLookupForUDR<ValueDecl *>( 10231 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 10232 if (!D->isInvalidDecl() && 10233 SemaRef.Context.hasSameType(D->getType(), Ty)) 10234 return D; 10235 return nullptr; 10236 })) 10237 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 10238 if (auto *VD = filterLookupForUDR<ValueDecl *>( 10239 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 10240 if (!D->isInvalidDecl() && 10241 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 10242 !Ty.isMoreQualifiedThan(D->getType())) 10243 return D; 10244 return nullptr; 10245 })) { 10246 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 10247 /*DetectVirtual=*/false); 10248 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 10249 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 10250 VD->getType().getUnqualifiedType()))) { 10251 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 10252 /*DiagID=*/0) != 10253 Sema::AR_inaccessible) { 10254 SemaRef.BuildBasePathArray(Paths, BasePath); 10255 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 10256 } 10257 } 10258 } 10259 } 10260 if (ReductionIdScopeSpec.isSet()) { 10261 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 10262 return ExprError(); 10263 } 10264 return ExprEmpty(); 10265 } 10266 10267 namespace { 10268 /// Data for the reduction-based clauses. 10269 struct ReductionData { 10270 /// List of original reduction items. 10271 SmallVector<Expr *, 8> Vars; 10272 /// List of private copies of the reduction items. 10273 SmallVector<Expr *, 8> Privates; 10274 /// LHS expressions for the reduction_op expressions. 10275 SmallVector<Expr *, 8> LHSs; 10276 /// RHS expressions for the reduction_op expressions. 10277 SmallVector<Expr *, 8> RHSs; 10278 /// Reduction operation expression. 10279 SmallVector<Expr *, 8> ReductionOps; 10280 /// Taskgroup descriptors for the corresponding reduction items in 10281 /// in_reduction clauses. 10282 SmallVector<Expr *, 8> TaskgroupDescriptors; 10283 /// List of captures for clause. 10284 SmallVector<Decl *, 4> ExprCaptures; 10285 /// List of postupdate expressions. 10286 SmallVector<Expr *, 4> ExprPostUpdates; 10287 ReductionData() = delete; 10288 /// Reserves required memory for the reduction data. 10289 ReductionData(unsigned Size) { 10290 Vars.reserve(Size); 10291 Privates.reserve(Size); 10292 LHSs.reserve(Size); 10293 RHSs.reserve(Size); 10294 ReductionOps.reserve(Size); 10295 TaskgroupDescriptors.reserve(Size); 10296 ExprCaptures.reserve(Size); 10297 ExprPostUpdates.reserve(Size); 10298 } 10299 /// Stores reduction item and reduction operation only (required for dependent 10300 /// reduction item). 10301 void push(Expr *Item, Expr *ReductionOp) { 10302 Vars.emplace_back(Item); 10303 Privates.emplace_back(nullptr); 10304 LHSs.emplace_back(nullptr); 10305 RHSs.emplace_back(nullptr); 10306 ReductionOps.emplace_back(ReductionOp); 10307 TaskgroupDescriptors.emplace_back(nullptr); 10308 } 10309 /// Stores reduction data. 10310 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 10311 Expr *TaskgroupDescriptor) { 10312 Vars.emplace_back(Item); 10313 Privates.emplace_back(Private); 10314 LHSs.emplace_back(LHS); 10315 RHSs.emplace_back(RHS); 10316 ReductionOps.emplace_back(ReductionOp); 10317 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 10318 } 10319 }; 10320 } // namespace 10321 10322 static bool checkOMPArraySectionConstantForReduction( 10323 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 10324 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 10325 const Expr *Length = OASE->getLength(); 10326 if (Length == nullptr) { 10327 // For array sections of the form [1:] or [:], we would need to analyze 10328 // the lower bound... 10329 if (OASE->getColonLoc().isValid()) 10330 return false; 10331 10332 // This is an array subscript which has implicit length 1! 10333 SingleElement = true; 10334 ArraySizes.push_back(llvm::APSInt::get(1)); 10335 } else { 10336 llvm::APSInt ConstantLengthValue; 10337 if (!Length->EvaluateAsInt(ConstantLengthValue, Context)) 10338 return false; 10339 10340 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 10341 ArraySizes.push_back(ConstantLengthValue); 10342 } 10343 10344 // Get the base of this array section and walk up from there. 10345 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 10346 10347 // We require length = 1 for all array sections except the right-most to 10348 // guarantee that the memory region is contiguous and has no holes in it. 10349 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 10350 Length = TempOASE->getLength(); 10351 if (Length == nullptr) { 10352 // For array sections of the form [1:] or [:], we would need to analyze 10353 // the lower bound... 10354 if (OASE->getColonLoc().isValid()) 10355 return false; 10356 10357 // This is an array subscript which has implicit length 1! 10358 ArraySizes.push_back(llvm::APSInt::get(1)); 10359 } else { 10360 llvm::APSInt ConstantLengthValue; 10361 if (!Length->EvaluateAsInt(ConstantLengthValue, Context) || 10362 ConstantLengthValue.getSExtValue() != 1) 10363 return false; 10364 10365 ArraySizes.push_back(ConstantLengthValue); 10366 } 10367 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 10368 } 10369 10370 // If we have a single element, we don't need to add the implicit lengths. 10371 if (!SingleElement) { 10372 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 10373 // Has implicit length 1! 10374 ArraySizes.push_back(llvm::APSInt::get(1)); 10375 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10376 } 10377 } 10378 10379 // This array section can be privatized as a single value or as a constant 10380 // sized array. 10381 return true; 10382 } 10383 10384 static bool actOnOMPReductionKindClause( 10385 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 10386 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10387 SourceLocation ColonLoc, SourceLocation EndLoc, 10388 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10389 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 10390 DeclarationName DN = ReductionId.getName(); 10391 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 10392 BinaryOperatorKind BOK = BO_Comma; 10393 10394 ASTContext &Context = S.Context; 10395 // OpenMP [2.14.3.6, reduction clause] 10396 // C 10397 // reduction-identifier is either an identifier or one of the following 10398 // operators: +, -, *, &, |, ^, && and || 10399 // C++ 10400 // reduction-identifier is either an id-expression or one of the following 10401 // operators: +, -, *, &, |, ^, && and || 10402 switch (OOK) { 10403 case OO_Plus: 10404 case OO_Minus: 10405 BOK = BO_Add; 10406 break; 10407 case OO_Star: 10408 BOK = BO_Mul; 10409 break; 10410 case OO_Amp: 10411 BOK = BO_And; 10412 break; 10413 case OO_Pipe: 10414 BOK = BO_Or; 10415 break; 10416 case OO_Caret: 10417 BOK = BO_Xor; 10418 break; 10419 case OO_AmpAmp: 10420 BOK = BO_LAnd; 10421 break; 10422 case OO_PipePipe: 10423 BOK = BO_LOr; 10424 break; 10425 case OO_New: 10426 case OO_Delete: 10427 case OO_Array_New: 10428 case OO_Array_Delete: 10429 case OO_Slash: 10430 case OO_Percent: 10431 case OO_Tilde: 10432 case OO_Exclaim: 10433 case OO_Equal: 10434 case OO_Less: 10435 case OO_Greater: 10436 case OO_LessEqual: 10437 case OO_GreaterEqual: 10438 case OO_PlusEqual: 10439 case OO_MinusEqual: 10440 case OO_StarEqual: 10441 case OO_SlashEqual: 10442 case OO_PercentEqual: 10443 case OO_CaretEqual: 10444 case OO_AmpEqual: 10445 case OO_PipeEqual: 10446 case OO_LessLess: 10447 case OO_GreaterGreater: 10448 case OO_LessLessEqual: 10449 case OO_GreaterGreaterEqual: 10450 case OO_EqualEqual: 10451 case OO_ExclaimEqual: 10452 case OO_Spaceship: 10453 case OO_PlusPlus: 10454 case OO_MinusMinus: 10455 case OO_Comma: 10456 case OO_ArrowStar: 10457 case OO_Arrow: 10458 case OO_Call: 10459 case OO_Subscript: 10460 case OO_Conditional: 10461 case OO_Coawait: 10462 case NUM_OVERLOADED_OPERATORS: 10463 llvm_unreachable("Unexpected reduction identifier"); 10464 case OO_None: 10465 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 10466 if (II->isStr("max")) 10467 BOK = BO_GT; 10468 else if (II->isStr("min")) 10469 BOK = BO_LT; 10470 } 10471 break; 10472 } 10473 SourceRange ReductionIdRange; 10474 if (ReductionIdScopeSpec.isValid()) 10475 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 10476 else 10477 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 10478 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 10479 10480 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 10481 bool FirstIter = true; 10482 for (Expr *RefExpr : VarList) { 10483 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 10484 // OpenMP [2.1, C/C++] 10485 // A list item is a variable or array section, subject to the restrictions 10486 // specified in Section 2.4 on page 42 and in each of the sections 10487 // describing clauses and directives for which a list appears. 10488 // OpenMP [2.14.3.3, Restrictions, p.1] 10489 // A variable that is part of another variable (as an array or 10490 // structure element) cannot appear in a private clause. 10491 if (!FirstIter && IR != ER) 10492 ++IR; 10493 FirstIter = false; 10494 SourceLocation ELoc; 10495 SourceRange ERange; 10496 Expr *SimpleRefExpr = RefExpr; 10497 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 10498 /*AllowArraySection=*/true); 10499 if (Res.second) { 10500 // Try to find 'declare reduction' corresponding construct before using 10501 // builtin/overloaded operators. 10502 QualType Type = Context.DependentTy; 10503 CXXCastPath BasePath; 10504 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10505 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10506 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10507 Expr *ReductionOp = nullptr; 10508 if (S.CurContext->isDependentContext() && 10509 (DeclareReductionRef.isUnset() || 10510 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 10511 ReductionOp = DeclareReductionRef.get(); 10512 // It will be analyzed later. 10513 RD.push(RefExpr, ReductionOp); 10514 } 10515 ValueDecl *D = Res.first; 10516 if (!D) 10517 continue; 10518 10519 Expr *TaskgroupDescriptor = nullptr; 10520 QualType Type; 10521 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 10522 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 10523 if (ASE) { 10524 Type = ASE->getType().getNonReferenceType(); 10525 } else if (OASE) { 10526 QualType BaseType = 10527 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 10528 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 10529 Type = ATy->getElementType(); 10530 else 10531 Type = BaseType->getPointeeType(); 10532 Type = Type.getNonReferenceType(); 10533 } else { 10534 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 10535 } 10536 auto *VD = dyn_cast<VarDecl>(D); 10537 10538 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10539 // A variable that appears in a private clause must not have an incomplete 10540 // type or a reference type. 10541 if (S.RequireCompleteType(ELoc, D->getType(), 10542 diag::err_omp_reduction_incomplete_type)) 10543 continue; 10544 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10545 // A list item that appears in a reduction clause must not be 10546 // const-qualified. 10547 if (Type.getNonReferenceType().isConstant(Context)) { 10548 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange; 10549 if (!ASE && !OASE) { 10550 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10551 VarDecl::DeclarationOnly; 10552 S.Diag(D->getLocation(), 10553 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10554 << D; 10555 } 10556 continue; 10557 } 10558 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 10559 // If a list-item is a reference type then it must bind to the same object 10560 // for all threads of the team. 10561 if (!ASE && !OASE && VD) { 10562 VarDecl *VDDef = VD->getDefinition(); 10563 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 10564 DSARefChecker Check(Stack); 10565 if (Check.Visit(VDDef->getInit())) { 10566 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 10567 << getOpenMPClauseName(ClauseKind) << ERange; 10568 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 10569 continue; 10570 } 10571 } 10572 } 10573 10574 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10575 // in a Construct] 10576 // Variables with the predetermined data-sharing attributes may not be 10577 // listed in data-sharing attributes clauses, except for the cases 10578 // listed below. For these exceptions only, listing a predetermined 10579 // variable in a data-sharing attribute clause is allowed and overrides 10580 // the variable's predetermined data-sharing attributes. 10581 // OpenMP [2.14.3.6, Restrictions, p.3] 10582 // Any number of reduction clauses can be specified on the directive, 10583 // but a list item can appear only once in the reduction clauses for that 10584 // directive. 10585 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 10586 if (DVar.CKind == OMPC_reduction) { 10587 S.Diag(ELoc, diag::err_omp_once_referenced) 10588 << getOpenMPClauseName(ClauseKind); 10589 if (DVar.RefExpr) 10590 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 10591 continue; 10592 } 10593 if (DVar.CKind != OMPC_unknown) { 10594 S.Diag(ELoc, diag::err_omp_wrong_dsa) 10595 << getOpenMPClauseName(DVar.CKind) 10596 << getOpenMPClauseName(OMPC_reduction); 10597 reportOriginalDsa(S, Stack, D, DVar); 10598 continue; 10599 } 10600 10601 // OpenMP [2.14.3.6, Restrictions, p.1] 10602 // A list item that appears in a reduction clause of a worksharing 10603 // construct must be shared in the parallel regions to which any of the 10604 // worksharing regions arising from the worksharing construct bind. 10605 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 10606 if (isOpenMPWorksharingDirective(CurrDir) && 10607 !isOpenMPParallelDirective(CurrDir) && 10608 !isOpenMPTeamsDirective(CurrDir)) { 10609 DVar = Stack->getImplicitDSA(D, true); 10610 if (DVar.CKind != OMPC_shared) { 10611 S.Diag(ELoc, diag::err_omp_required_access) 10612 << getOpenMPClauseName(OMPC_reduction) 10613 << getOpenMPClauseName(OMPC_shared); 10614 reportOriginalDsa(S, Stack, D, DVar); 10615 continue; 10616 } 10617 } 10618 10619 // Try to find 'declare reduction' corresponding construct before using 10620 // builtin/overloaded operators. 10621 CXXCastPath BasePath; 10622 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10623 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10624 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10625 if (DeclareReductionRef.isInvalid()) 10626 continue; 10627 if (S.CurContext->isDependentContext() && 10628 (DeclareReductionRef.isUnset() || 10629 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 10630 RD.push(RefExpr, DeclareReductionRef.get()); 10631 continue; 10632 } 10633 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 10634 // Not allowed reduction identifier is found. 10635 S.Diag(ReductionId.getBeginLoc(), 10636 diag::err_omp_unknown_reduction_identifier) 10637 << Type << ReductionIdRange; 10638 continue; 10639 } 10640 10641 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10642 // The type of a list item that appears in a reduction clause must be valid 10643 // for the reduction-identifier. For a max or min reduction in C, the type 10644 // of the list item must be an allowed arithmetic data type: char, int, 10645 // float, double, or _Bool, possibly modified with long, short, signed, or 10646 // unsigned. For a max or min reduction in C++, the type of the list item 10647 // must be an allowed arithmetic data type: char, wchar_t, int, float, 10648 // double, or bool, possibly modified with long, short, signed, or unsigned. 10649 if (DeclareReductionRef.isUnset()) { 10650 if ((BOK == BO_GT || BOK == BO_LT) && 10651 !(Type->isScalarType() || 10652 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 10653 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 10654 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 10655 if (!ASE && !OASE) { 10656 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10657 VarDecl::DeclarationOnly; 10658 S.Diag(D->getLocation(), 10659 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10660 << D; 10661 } 10662 continue; 10663 } 10664 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 10665 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 10666 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 10667 << getOpenMPClauseName(ClauseKind); 10668 if (!ASE && !OASE) { 10669 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10670 VarDecl::DeclarationOnly; 10671 S.Diag(D->getLocation(), 10672 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10673 << D; 10674 } 10675 continue; 10676 } 10677 } 10678 10679 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 10680 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 10681 D->hasAttrs() ? &D->getAttrs() : nullptr); 10682 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 10683 D->hasAttrs() ? &D->getAttrs() : nullptr); 10684 QualType PrivateTy = Type; 10685 10686 // Try if we can determine constant lengths for all array sections and avoid 10687 // the VLA. 10688 bool ConstantLengthOASE = false; 10689 if (OASE) { 10690 bool SingleElement; 10691 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 10692 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 10693 Context, OASE, SingleElement, ArraySizes); 10694 10695 // If we don't have a single element, we must emit a constant array type. 10696 if (ConstantLengthOASE && !SingleElement) { 10697 for (llvm::APSInt &Size : ArraySizes) 10698 PrivateTy = Context.getConstantArrayType( 10699 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 10700 } 10701 } 10702 10703 if ((OASE && !ConstantLengthOASE) || 10704 (!OASE && !ASE && 10705 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 10706 if (!Context.getTargetInfo().isVLASupported() && 10707 S.shouldDiagnoseTargetSupportFromOpenMP()) { 10708 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 10709 S.Diag(ELoc, diag::note_vla_unsupported); 10710 continue; 10711 } 10712 // For arrays/array sections only: 10713 // Create pseudo array type for private copy. The size for this array will 10714 // be generated during codegen. 10715 // For array subscripts or single variables Private Ty is the same as Type 10716 // (type of the variable or single array element). 10717 PrivateTy = Context.getVariableArrayType( 10718 Type, 10719 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 10720 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 10721 } else if (!ASE && !OASE && 10722 Context.getAsArrayType(D->getType().getNonReferenceType())) { 10723 PrivateTy = D->getType().getNonReferenceType(); 10724 } 10725 // Private copy. 10726 VarDecl *PrivateVD = 10727 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 10728 D->hasAttrs() ? &D->getAttrs() : nullptr, 10729 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10730 // Add initializer for private variable. 10731 Expr *Init = nullptr; 10732 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 10733 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 10734 if (DeclareReductionRef.isUsable()) { 10735 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 10736 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 10737 if (DRD->getInitializer()) { 10738 Init = DRDRef; 10739 RHSVD->setInit(DRDRef); 10740 RHSVD->setInitStyle(VarDecl::CallInit); 10741 } 10742 } else { 10743 switch (BOK) { 10744 case BO_Add: 10745 case BO_Xor: 10746 case BO_Or: 10747 case BO_LOr: 10748 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 10749 if (Type->isScalarType() || Type->isAnyComplexType()) 10750 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 10751 break; 10752 case BO_Mul: 10753 case BO_LAnd: 10754 if (Type->isScalarType() || Type->isAnyComplexType()) { 10755 // '*' and '&&' reduction ops - initializer is '1'. 10756 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 10757 } 10758 break; 10759 case BO_And: { 10760 // '&' reduction op - initializer is '~0'. 10761 QualType OrigType = Type; 10762 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 10763 Type = ComplexTy->getElementType(); 10764 if (Type->isRealFloatingType()) { 10765 llvm::APFloat InitValue = 10766 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 10767 /*isIEEE=*/true); 10768 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 10769 Type, ELoc); 10770 } else if (Type->isScalarType()) { 10771 uint64_t Size = Context.getTypeSize(Type); 10772 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 10773 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 10774 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 10775 } 10776 if (Init && OrigType->isAnyComplexType()) { 10777 // Init = 0xFFFF + 0xFFFFi; 10778 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 10779 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 10780 } 10781 Type = OrigType; 10782 break; 10783 } 10784 case BO_LT: 10785 case BO_GT: { 10786 // 'min' reduction op - initializer is 'Largest representable number in 10787 // the reduction list item type'. 10788 // 'max' reduction op - initializer is 'Least representable number in 10789 // the reduction list item type'. 10790 if (Type->isIntegerType() || Type->isPointerType()) { 10791 bool IsSigned = Type->hasSignedIntegerRepresentation(); 10792 uint64_t Size = Context.getTypeSize(Type); 10793 QualType IntTy = 10794 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 10795 llvm::APInt InitValue = 10796 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 10797 : llvm::APInt::getMinValue(Size) 10798 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 10799 : llvm::APInt::getMaxValue(Size); 10800 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 10801 if (Type->isPointerType()) { 10802 // Cast to pointer type. 10803 ExprResult CastExpr = S.BuildCStyleCastExpr( 10804 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 10805 if (CastExpr.isInvalid()) 10806 continue; 10807 Init = CastExpr.get(); 10808 } 10809 } else if (Type->isRealFloatingType()) { 10810 llvm::APFloat InitValue = llvm::APFloat::getLargest( 10811 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 10812 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 10813 Type, ELoc); 10814 } 10815 break; 10816 } 10817 case BO_PtrMemD: 10818 case BO_PtrMemI: 10819 case BO_MulAssign: 10820 case BO_Div: 10821 case BO_Rem: 10822 case BO_Sub: 10823 case BO_Shl: 10824 case BO_Shr: 10825 case BO_LE: 10826 case BO_GE: 10827 case BO_EQ: 10828 case BO_NE: 10829 case BO_Cmp: 10830 case BO_AndAssign: 10831 case BO_XorAssign: 10832 case BO_OrAssign: 10833 case BO_Assign: 10834 case BO_AddAssign: 10835 case BO_SubAssign: 10836 case BO_DivAssign: 10837 case BO_RemAssign: 10838 case BO_ShlAssign: 10839 case BO_ShrAssign: 10840 case BO_Comma: 10841 llvm_unreachable("Unexpected reduction operation"); 10842 } 10843 } 10844 if (Init && DeclareReductionRef.isUnset()) 10845 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 10846 else if (!Init) 10847 S.ActOnUninitializedDecl(RHSVD); 10848 if (RHSVD->isInvalidDecl()) 10849 continue; 10850 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 10851 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 10852 << Type << ReductionIdRange; 10853 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10854 VarDecl::DeclarationOnly; 10855 S.Diag(D->getLocation(), 10856 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10857 << D; 10858 continue; 10859 } 10860 // Store initializer for single element in private copy. Will be used during 10861 // codegen. 10862 PrivateVD->setInit(RHSVD->getInit()); 10863 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 10864 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 10865 ExprResult ReductionOp; 10866 if (DeclareReductionRef.isUsable()) { 10867 QualType RedTy = DeclareReductionRef.get()->getType(); 10868 QualType PtrRedTy = Context.getPointerType(RedTy); 10869 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 10870 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 10871 if (!BasePath.empty()) { 10872 LHS = S.DefaultLvalueConversion(LHS.get()); 10873 RHS = S.DefaultLvalueConversion(RHS.get()); 10874 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 10875 CK_UncheckedDerivedToBase, LHS.get(), 10876 &BasePath, LHS.get()->getValueKind()); 10877 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 10878 CK_UncheckedDerivedToBase, RHS.get(), 10879 &BasePath, RHS.get()->getValueKind()); 10880 } 10881 FunctionProtoType::ExtProtoInfo EPI; 10882 QualType Params[] = {PtrRedTy, PtrRedTy}; 10883 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 10884 auto *OVE = new (Context) OpaqueValueExpr( 10885 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 10886 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 10887 Expr *Args[] = {LHS.get(), RHS.get()}; 10888 ReductionOp = new (Context) 10889 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 10890 } else { 10891 ReductionOp = S.BuildBinOp( 10892 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 10893 if (ReductionOp.isUsable()) { 10894 if (BOK != BO_LT && BOK != BO_GT) { 10895 ReductionOp = 10896 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 10897 BO_Assign, LHSDRE, ReductionOp.get()); 10898 } else { 10899 auto *ConditionalOp = new (Context) 10900 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 10901 Type, VK_LValue, OK_Ordinary); 10902 ReductionOp = 10903 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 10904 BO_Assign, LHSDRE, ConditionalOp); 10905 } 10906 if (ReductionOp.isUsable()) 10907 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); 10908 } 10909 if (!ReductionOp.isUsable()) 10910 continue; 10911 } 10912 10913 // OpenMP [2.15.4.6, Restrictions, p.2] 10914 // A list item that appears in an in_reduction clause of a task construct 10915 // must appear in a task_reduction clause of a construct associated with a 10916 // taskgroup region that includes the participating task in its taskgroup 10917 // set. The construct associated with the innermost region that meets this 10918 // condition must specify the same reduction-identifier as the in_reduction 10919 // clause. 10920 if (ClauseKind == OMPC_in_reduction) { 10921 SourceRange ParentSR; 10922 BinaryOperatorKind ParentBOK; 10923 const Expr *ParentReductionOp; 10924 Expr *ParentBOKTD, *ParentReductionOpTD; 10925 DSAStackTy::DSAVarData ParentBOKDSA = 10926 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 10927 ParentBOKTD); 10928 DSAStackTy::DSAVarData ParentReductionOpDSA = 10929 Stack->getTopMostTaskgroupReductionData( 10930 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 10931 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 10932 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 10933 if (!IsParentBOK && !IsParentReductionOp) { 10934 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 10935 continue; 10936 } 10937 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 10938 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 10939 IsParentReductionOp) { 10940 bool EmitError = true; 10941 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 10942 llvm::FoldingSetNodeID RedId, ParentRedId; 10943 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 10944 DeclareReductionRef.get()->Profile(RedId, Context, 10945 /*Canonical=*/true); 10946 EmitError = RedId != ParentRedId; 10947 } 10948 if (EmitError) { 10949 S.Diag(ReductionId.getBeginLoc(), 10950 diag::err_omp_reduction_identifier_mismatch) 10951 << ReductionIdRange << RefExpr->getSourceRange(); 10952 S.Diag(ParentSR.getBegin(), 10953 diag::note_omp_previous_reduction_identifier) 10954 << ParentSR 10955 << (IsParentBOK ? ParentBOKDSA.RefExpr 10956 : ParentReductionOpDSA.RefExpr) 10957 ->getSourceRange(); 10958 continue; 10959 } 10960 } 10961 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 10962 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 10963 } 10964 10965 DeclRefExpr *Ref = nullptr; 10966 Expr *VarsExpr = RefExpr->IgnoreParens(); 10967 if (!VD && !S.CurContext->isDependentContext()) { 10968 if (ASE || OASE) { 10969 TransformExprToCaptures RebuildToCapture(S, D); 10970 VarsExpr = 10971 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 10972 Ref = RebuildToCapture.getCapturedExpr(); 10973 } else { 10974 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 10975 } 10976 if (!S.isOpenMPCapturedDecl(D)) { 10977 RD.ExprCaptures.emplace_back(Ref->getDecl()); 10978 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 10979 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 10980 if (!RefRes.isUsable()) 10981 continue; 10982 ExprResult PostUpdateRes = 10983 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10984 RefRes.get()); 10985 if (!PostUpdateRes.isUsable()) 10986 continue; 10987 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 10988 Stack->getCurrentDirective() == OMPD_taskgroup) { 10989 S.Diag(RefExpr->getExprLoc(), 10990 diag::err_omp_reduction_non_addressable_expression) 10991 << RefExpr->getSourceRange(); 10992 continue; 10993 } 10994 RD.ExprPostUpdates.emplace_back( 10995 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 10996 } 10997 } 10998 } 10999 // All reduction items are still marked as reduction (to do not increase 11000 // code base size). 11001 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 11002 if (CurrDir == OMPD_taskgroup) { 11003 if (DeclareReductionRef.isUsable()) 11004 Stack->addTaskgroupReductionData(D, ReductionIdRange, 11005 DeclareReductionRef.get()); 11006 else 11007 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 11008 } 11009 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 11010 TaskgroupDescriptor); 11011 } 11012 return RD.Vars.empty(); 11013 } 11014 11015 OMPClause *Sema::ActOnOpenMPReductionClause( 11016 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11017 SourceLocation ColonLoc, SourceLocation EndLoc, 11018 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11019 ArrayRef<Expr *> UnresolvedReductions) { 11020 ReductionData RD(VarList.size()); 11021 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 11022 StartLoc, LParenLoc, ColonLoc, EndLoc, 11023 ReductionIdScopeSpec, ReductionId, 11024 UnresolvedReductions, RD)) 11025 return nullptr; 11026 11027 return OMPReductionClause::Create( 11028 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11029 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11030 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11031 buildPreInits(Context, RD.ExprCaptures), 11032 buildPostUpdate(*this, RD.ExprPostUpdates)); 11033 } 11034 11035 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 11036 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11037 SourceLocation ColonLoc, SourceLocation EndLoc, 11038 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11039 ArrayRef<Expr *> UnresolvedReductions) { 11040 ReductionData RD(VarList.size()); 11041 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 11042 StartLoc, LParenLoc, ColonLoc, EndLoc, 11043 ReductionIdScopeSpec, ReductionId, 11044 UnresolvedReductions, RD)) 11045 return nullptr; 11046 11047 return OMPTaskReductionClause::Create( 11048 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11049 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11050 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11051 buildPreInits(Context, RD.ExprCaptures), 11052 buildPostUpdate(*this, RD.ExprPostUpdates)); 11053 } 11054 11055 OMPClause *Sema::ActOnOpenMPInReductionClause( 11056 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11057 SourceLocation ColonLoc, SourceLocation EndLoc, 11058 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11059 ArrayRef<Expr *> UnresolvedReductions) { 11060 ReductionData RD(VarList.size()); 11061 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 11062 StartLoc, LParenLoc, ColonLoc, EndLoc, 11063 ReductionIdScopeSpec, ReductionId, 11064 UnresolvedReductions, RD)) 11065 return nullptr; 11066 11067 return OMPInReductionClause::Create( 11068 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11069 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11070 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 11071 buildPreInits(Context, RD.ExprCaptures), 11072 buildPostUpdate(*this, RD.ExprPostUpdates)); 11073 } 11074 11075 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 11076 SourceLocation LinLoc) { 11077 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 11078 LinKind == OMPC_LINEAR_unknown) { 11079 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 11080 return true; 11081 } 11082 return false; 11083 } 11084 11085 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 11086 OpenMPLinearClauseKind LinKind, 11087 QualType Type) { 11088 const auto *VD = dyn_cast_or_null<VarDecl>(D); 11089 // A variable must not have an incomplete type or a reference type. 11090 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 11091 return true; 11092 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 11093 !Type->isReferenceType()) { 11094 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 11095 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 11096 return true; 11097 } 11098 Type = Type.getNonReferenceType(); 11099 11100 // A list item must not be const-qualified. 11101 if (Type.isConstant(Context)) { 11102 Diag(ELoc, diag::err_omp_const_variable) 11103 << getOpenMPClauseName(OMPC_linear); 11104 if (D) { 11105 bool IsDecl = 11106 !VD || 11107 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11108 Diag(D->getLocation(), 11109 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11110 << D; 11111 } 11112 return true; 11113 } 11114 11115 // A list item must be of integral or pointer type. 11116 Type = Type.getUnqualifiedType().getCanonicalType(); 11117 const auto *Ty = Type.getTypePtrOrNull(); 11118 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 11119 !Ty->isPointerType())) { 11120 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 11121 if (D) { 11122 bool IsDecl = 11123 !VD || 11124 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11125 Diag(D->getLocation(), 11126 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11127 << D; 11128 } 11129 return true; 11130 } 11131 return false; 11132 } 11133 11134 OMPClause *Sema::ActOnOpenMPLinearClause( 11135 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 11136 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 11137 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11138 SmallVector<Expr *, 8> Vars; 11139 SmallVector<Expr *, 8> Privates; 11140 SmallVector<Expr *, 8> Inits; 11141 SmallVector<Decl *, 4> ExprCaptures; 11142 SmallVector<Expr *, 4> ExprPostUpdates; 11143 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 11144 LinKind = OMPC_LINEAR_val; 11145 for (Expr *RefExpr : VarList) { 11146 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11147 SourceLocation ELoc; 11148 SourceRange ERange; 11149 Expr *SimpleRefExpr = RefExpr; 11150 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 11151 /*AllowArraySection=*/false); 11152 if (Res.second) { 11153 // It will be analyzed later. 11154 Vars.push_back(RefExpr); 11155 Privates.push_back(nullptr); 11156 Inits.push_back(nullptr); 11157 } 11158 ValueDecl *D = Res.first; 11159 if (!D) 11160 continue; 11161 11162 QualType Type = D->getType(); 11163 auto *VD = dyn_cast<VarDecl>(D); 11164 11165 // OpenMP [2.14.3.7, linear clause] 11166 // A list-item cannot appear in more than one linear clause. 11167 // A list-item that appears in a linear clause cannot appear in any 11168 // other data-sharing attribute clause. 11169 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11170 if (DVar.RefExpr) { 11171 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11172 << getOpenMPClauseName(OMPC_linear); 11173 reportOriginalDsa(*this, DSAStack, D, DVar); 11174 continue; 11175 } 11176 11177 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 11178 continue; 11179 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11180 11181 // Build private copy of original var. 11182 VarDecl *Private = 11183 buildVarDecl(*this, ELoc, Type, D->getName(), 11184 D->hasAttrs() ? &D->getAttrs() : nullptr, 11185 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11186 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 11187 // Build var to save initial value. 11188 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 11189 Expr *InitExpr; 11190 DeclRefExpr *Ref = nullptr; 11191 if (!VD && !CurContext->isDependentContext()) { 11192 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11193 if (!isOpenMPCapturedDecl(D)) { 11194 ExprCaptures.push_back(Ref->getDecl()); 11195 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11196 ExprResult RefRes = DefaultLvalueConversion(Ref); 11197 if (!RefRes.isUsable()) 11198 continue; 11199 ExprResult PostUpdateRes = 11200 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 11201 SimpleRefExpr, RefRes.get()); 11202 if (!PostUpdateRes.isUsable()) 11203 continue; 11204 ExprPostUpdates.push_back( 11205 IgnoredValueConversions(PostUpdateRes.get()).get()); 11206 } 11207 } 11208 } 11209 if (LinKind == OMPC_LINEAR_uval) 11210 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 11211 else 11212 InitExpr = VD ? SimpleRefExpr : Ref; 11213 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 11214 /*DirectInit=*/false); 11215 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 11216 11217 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 11218 Vars.push_back((VD || CurContext->isDependentContext()) 11219 ? RefExpr->IgnoreParens() 11220 : Ref); 11221 Privates.push_back(PrivateRef); 11222 Inits.push_back(InitRef); 11223 } 11224 11225 if (Vars.empty()) 11226 return nullptr; 11227 11228 Expr *StepExpr = Step; 11229 Expr *CalcStepExpr = nullptr; 11230 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 11231 !Step->isInstantiationDependent() && 11232 !Step->containsUnexpandedParameterPack()) { 11233 SourceLocation StepLoc = Step->getBeginLoc(); 11234 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 11235 if (Val.isInvalid()) 11236 return nullptr; 11237 StepExpr = Val.get(); 11238 11239 // Build var to save the step value. 11240 VarDecl *SaveVar = 11241 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 11242 ExprResult SaveRef = 11243 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 11244 ExprResult CalcStep = 11245 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 11246 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 11247 11248 // Warn about zero linear step (it would be probably better specified as 11249 // making corresponding variables 'const'). 11250 llvm::APSInt Result; 11251 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 11252 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 11253 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 11254 << (Vars.size() > 1); 11255 if (!IsConstant && CalcStep.isUsable()) { 11256 // Calculate the step beforehand instead of doing this on each iteration. 11257 // (This is not used if the number of iterations may be kfold-ed). 11258 CalcStepExpr = CalcStep.get(); 11259 } 11260 } 11261 11262 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 11263 ColonLoc, EndLoc, Vars, Privates, Inits, 11264 StepExpr, CalcStepExpr, 11265 buildPreInits(Context, ExprCaptures), 11266 buildPostUpdate(*this, ExprPostUpdates)); 11267 } 11268 11269 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 11270 Expr *NumIterations, Sema &SemaRef, 11271 Scope *S, DSAStackTy *Stack) { 11272 // Walk the vars and build update/final expressions for the CodeGen. 11273 SmallVector<Expr *, 8> Updates; 11274 SmallVector<Expr *, 8> Finals; 11275 Expr *Step = Clause.getStep(); 11276 Expr *CalcStep = Clause.getCalcStep(); 11277 // OpenMP [2.14.3.7, linear clause] 11278 // If linear-step is not specified it is assumed to be 1. 11279 if (!Step) 11280 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 11281 else if (CalcStep) 11282 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 11283 bool HasErrors = false; 11284 auto CurInit = Clause.inits().begin(); 11285 auto CurPrivate = Clause.privates().begin(); 11286 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 11287 for (Expr *RefExpr : Clause.varlists()) { 11288 SourceLocation ELoc; 11289 SourceRange ERange; 11290 Expr *SimpleRefExpr = RefExpr; 11291 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 11292 /*AllowArraySection=*/false); 11293 ValueDecl *D = Res.first; 11294 if (Res.second || !D) { 11295 Updates.push_back(nullptr); 11296 Finals.push_back(nullptr); 11297 HasErrors = true; 11298 continue; 11299 } 11300 auto &&Info = Stack->isLoopControlVariable(D); 11301 // OpenMP [2.15.11, distribute simd Construct] 11302 // A list item may not appear in a linear clause, unless it is the loop 11303 // iteration variable. 11304 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 11305 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 11306 SemaRef.Diag(ELoc, 11307 diag::err_omp_linear_distribute_var_non_loop_iteration); 11308 Updates.push_back(nullptr); 11309 Finals.push_back(nullptr); 11310 HasErrors = true; 11311 continue; 11312 } 11313 Expr *InitExpr = *CurInit; 11314 11315 // Build privatized reference to the current linear var. 11316 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 11317 Expr *CapturedRef; 11318 if (LinKind == OMPC_LINEAR_uval) 11319 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 11320 else 11321 CapturedRef = 11322 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 11323 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 11324 /*RefersToCapture=*/true); 11325 11326 // Build update: Var = InitExpr + IV * Step 11327 ExprResult Update; 11328 if (!Info.first) 11329 Update = 11330 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 11331 InitExpr, IV, Step, /* Subtract */ false); 11332 else 11333 Update = *CurPrivate; 11334 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 11335 /*DiscardedValue=*/true); 11336 11337 // Build final: Var = InitExpr + NumIterations * Step 11338 ExprResult Final; 11339 if (!Info.first) 11340 Final = 11341 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 11342 InitExpr, NumIterations, Step, /*Subtract=*/false); 11343 else 11344 Final = *CurPrivate; 11345 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 11346 /*DiscardedValue=*/true); 11347 11348 if (!Update.isUsable() || !Final.isUsable()) { 11349 Updates.push_back(nullptr); 11350 Finals.push_back(nullptr); 11351 HasErrors = true; 11352 } else { 11353 Updates.push_back(Update.get()); 11354 Finals.push_back(Final.get()); 11355 } 11356 ++CurInit; 11357 ++CurPrivate; 11358 } 11359 Clause.setUpdates(Updates); 11360 Clause.setFinals(Finals); 11361 return HasErrors; 11362 } 11363 11364 OMPClause *Sema::ActOnOpenMPAlignedClause( 11365 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 11366 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11367 SmallVector<Expr *, 8> Vars; 11368 for (Expr *RefExpr : VarList) { 11369 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11370 SourceLocation ELoc; 11371 SourceRange ERange; 11372 Expr *SimpleRefExpr = RefExpr; 11373 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 11374 /*AllowArraySection=*/false); 11375 if (Res.second) { 11376 // It will be analyzed later. 11377 Vars.push_back(RefExpr); 11378 } 11379 ValueDecl *D = Res.first; 11380 if (!D) 11381 continue; 11382 11383 QualType QType = D->getType(); 11384 auto *VD = dyn_cast<VarDecl>(D); 11385 11386 // OpenMP [2.8.1, simd construct, Restrictions] 11387 // The type of list items appearing in the aligned clause must be 11388 // array, pointer, reference to array, or reference to pointer. 11389 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11390 const Type *Ty = QType.getTypePtrOrNull(); 11391 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 11392 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 11393 << QType << getLangOpts().CPlusPlus << ERange; 11394 bool IsDecl = 11395 !VD || 11396 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11397 Diag(D->getLocation(), 11398 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11399 << D; 11400 continue; 11401 } 11402 11403 // OpenMP [2.8.1, simd construct, Restrictions] 11404 // A list-item cannot appear in more than one aligned clause. 11405 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 11406 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 11407 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 11408 << getOpenMPClauseName(OMPC_aligned); 11409 continue; 11410 } 11411 11412 DeclRefExpr *Ref = nullptr; 11413 if (!VD && isOpenMPCapturedDecl(D)) 11414 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11415 Vars.push_back(DefaultFunctionArrayConversion( 11416 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 11417 .get()); 11418 } 11419 11420 // OpenMP [2.8.1, simd construct, Description] 11421 // The parameter of the aligned clause, alignment, must be a constant 11422 // positive integer expression. 11423 // If no optional parameter is specified, implementation-defined default 11424 // alignments for SIMD instructions on the target platforms are assumed. 11425 if (Alignment != nullptr) { 11426 ExprResult AlignResult = 11427 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 11428 if (AlignResult.isInvalid()) 11429 return nullptr; 11430 Alignment = AlignResult.get(); 11431 } 11432 if (Vars.empty()) 11433 return nullptr; 11434 11435 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 11436 EndLoc, Vars, Alignment); 11437 } 11438 11439 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 11440 SourceLocation StartLoc, 11441 SourceLocation LParenLoc, 11442 SourceLocation EndLoc) { 11443 SmallVector<Expr *, 8> Vars; 11444 SmallVector<Expr *, 8> SrcExprs; 11445 SmallVector<Expr *, 8> DstExprs; 11446 SmallVector<Expr *, 8> AssignmentOps; 11447 for (Expr *RefExpr : VarList) { 11448 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 11449 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 11450 // It will be analyzed later. 11451 Vars.push_back(RefExpr); 11452 SrcExprs.push_back(nullptr); 11453 DstExprs.push_back(nullptr); 11454 AssignmentOps.push_back(nullptr); 11455 continue; 11456 } 11457 11458 SourceLocation ELoc = RefExpr->getExprLoc(); 11459 // OpenMP [2.1, C/C++] 11460 // A list item is a variable name. 11461 // OpenMP [2.14.4.1, Restrictions, p.1] 11462 // A list item that appears in a copyin clause must be threadprivate. 11463 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 11464 if (!DE || !isa<VarDecl>(DE->getDecl())) { 11465 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 11466 << 0 << RefExpr->getSourceRange(); 11467 continue; 11468 } 11469 11470 Decl *D = DE->getDecl(); 11471 auto *VD = cast<VarDecl>(D); 11472 11473 QualType Type = VD->getType(); 11474 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 11475 // It will be analyzed later. 11476 Vars.push_back(DE); 11477 SrcExprs.push_back(nullptr); 11478 DstExprs.push_back(nullptr); 11479 AssignmentOps.push_back(nullptr); 11480 continue; 11481 } 11482 11483 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 11484 // A list item that appears in a copyin clause must be threadprivate. 11485 if (!DSAStack->isThreadPrivate(VD)) { 11486 Diag(ELoc, diag::err_omp_required_access) 11487 << getOpenMPClauseName(OMPC_copyin) 11488 << getOpenMPDirectiveName(OMPD_threadprivate); 11489 continue; 11490 } 11491 11492 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11493 // A variable of class type (or array thereof) that appears in a 11494 // copyin clause requires an accessible, unambiguous copy assignment 11495 // operator for the class type. 11496 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11497 VarDecl *SrcVD = 11498 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 11499 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11500 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 11501 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 11502 VarDecl *DstVD = 11503 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 11504 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11505 DeclRefExpr *PseudoDstExpr = 11506 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 11507 // For arrays generate assignment operation for single element and replace 11508 // it by the original array element in CodeGen. 11509 ExprResult AssignmentOp = 11510 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 11511 PseudoSrcExpr); 11512 if (AssignmentOp.isInvalid()) 11513 continue; 11514 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 11515 /*DiscardedValue=*/true); 11516 if (AssignmentOp.isInvalid()) 11517 continue; 11518 11519 DSAStack->addDSA(VD, DE, OMPC_copyin); 11520 Vars.push_back(DE); 11521 SrcExprs.push_back(PseudoSrcExpr); 11522 DstExprs.push_back(PseudoDstExpr); 11523 AssignmentOps.push_back(AssignmentOp.get()); 11524 } 11525 11526 if (Vars.empty()) 11527 return nullptr; 11528 11529 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11530 SrcExprs, DstExprs, AssignmentOps); 11531 } 11532 11533 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 11534 SourceLocation StartLoc, 11535 SourceLocation LParenLoc, 11536 SourceLocation EndLoc) { 11537 SmallVector<Expr *, 8> Vars; 11538 SmallVector<Expr *, 8> SrcExprs; 11539 SmallVector<Expr *, 8> DstExprs; 11540 SmallVector<Expr *, 8> AssignmentOps; 11541 for (Expr *RefExpr : VarList) { 11542 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11543 SourceLocation ELoc; 11544 SourceRange ERange; 11545 Expr *SimpleRefExpr = RefExpr; 11546 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 11547 /*AllowArraySection=*/false); 11548 if (Res.second) { 11549 // It will be analyzed later. 11550 Vars.push_back(RefExpr); 11551 SrcExprs.push_back(nullptr); 11552 DstExprs.push_back(nullptr); 11553 AssignmentOps.push_back(nullptr); 11554 } 11555 ValueDecl *D = Res.first; 11556 if (!D) 11557 continue; 11558 11559 QualType Type = D->getType(); 11560 auto *VD = dyn_cast<VarDecl>(D); 11561 11562 // OpenMP [2.14.4.2, Restrictions, p.2] 11563 // A list item that appears in a copyprivate clause may not appear in a 11564 // private or firstprivate clause on the single construct. 11565 if (!VD || !DSAStack->isThreadPrivate(VD)) { 11566 DSAStackTy::DSAVarData DVar = 11567 DSAStack->getTopDSA(D, /*FromParent=*/false); 11568 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 11569 DVar.RefExpr) { 11570 Diag(ELoc, diag::err_omp_wrong_dsa) 11571 << getOpenMPClauseName(DVar.CKind) 11572 << getOpenMPClauseName(OMPC_copyprivate); 11573 reportOriginalDsa(*this, DSAStack, D, DVar); 11574 continue; 11575 } 11576 11577 // OpenMP [2.11.4.2, Restrictions, p.1] 11578 // All list items that appear in a copyprivate clause must be either 11579 // threadprivate or private in the enclosing context. 11580 if (DVar.CKind == OMPC_unknown) { 11581 DVar = DSAStack->getImplicitDSA(D, false); 11582 if (DVar.CKind == OMPC_shared) { 11583 Diag(ELoc, diag::err_omp_required_access) 11584 << getOpenMPClauseName(OMPC_copyprivate) 11585 << "threadprivate or private in the enclosing context"; 11586 reportOriginalDsa(*this, DSAStack, D, DVar); 11587 continue; 11588 } 11589 } 11590 } 11591 11592 // Variably modified types are not supported. 11593 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 11594 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11595 << getOpenMPClauseName(OMPC_copyprivate) << Type 11596 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11597 bool IsDecl = 11598 !VD || 11599 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11600 Diag(D->getLocation(), 11601 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11602 << D; 11603 continue; 11604 } 11605 11606 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11607 // A variable of class type (or array thereof) that appears in a 11608 // copyin clause requires an accessible, unambiguous copy assignment 11609 // operator for the class type. 11610 Type = Context.getBaseElementType(Type.getNonReferenceType()) 11611 .getUnqualifiedType(); 11612 VarDecl *SrcVD = 11613 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 11614 D->hasAttrs() ? &D->getAttrs() : nullptr); 11615 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 11616 VarDecl *DstVD = 11617 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 11618 D->hasAttrs() ? &D->getAttrs() : nullptr); 11619 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11620 ExprResult AssignmentOp = BuildBinOp( 11621 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 11622 if (AssignmentOp.isInvalid()) 11623 continue; 11624 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 11625 /*DiscardedValue=*/true); 11626 if (AssignmentOp.isInvalid()) 11627 continue; 11628 11629 // No need to mark vars as copyprivate, they are already threadprivate or 11630 // implicitly private. 11631 assert(VD || isOpenMPCapturedDecl(D)); 11632 Vars.push_back( 11633 VD ? RefExpr->IgnoreParens() 11634 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 11635 SrcExprs.push_back(PseudoSrcExpr); 11636 DstExprs.push_back(PseudoDstExpr); 11637 AssignmentOps.push_back(AssignmentOp.get()); 11638 } 11639 11640 if (Vars.empty()) 11641 return nullptr; 11642 11643 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11644 Vars, SrcExprs, DstExprs, AssignmentOps); 11645 } 11646 11647 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 11648 SourceLocation StartLoc, 11649 SourceLocation LParenLoc, 11650 SourceLocation EndLoc) { 11651 if (VarList.empty()) 11652 return nullptr; 11653 11654 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 11655 } 11656 11657 OMPClause * 11658 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 11659 SourceLocation DepLoc, SourceLocation ColonLoc, 11660 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 11661 SourceLocation LParenLoc, SourceLocation EndLoc) { 11662 if (DSAStack->getCurrentDirective() == OMPD_ordered && 11663 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 11664 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 11665 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 11666 return nullptr; 11667 } 11668 if (DSAStack->getCurrentDirective() != OMPD_ordered && 11669 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 11670 DepKind == OMPC_DEPEND_sink)) { 11671 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 11672 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 11673 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 11674 /*Last=*/OMPC_DEPEND_unknown, Except) 11675 << getOpenMPClauseName(OMPC_depend); 11676 return nullptr; 11677 } 11678 SmallVector<Expr *, 8> Vars; 11679 DSAStackTy::OperatorOffsetTy OpsOffs; 11680 llvm::APSInt DepCounter(/*BitWidth=*/32); 11681 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 11682 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 11683 if (const Expr *OrderedCountExpr = 11684 DSAStack->getParentOrderedRegionParam().first) { 11685 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 11686 TotalDepCount.setIsUnsigned(/*Val=*/true); 11687 } 11688 } 11689 for (Expr *RefExpr : VarList) { 11690 assert(RefExpr && "NULL expr in OpenMP shared clause."); 11691 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 11692 // It will be analyzed later. 11693 Vars.push_back(RefExpr); 11694 continue; 11695 } 11696 11697 SourceLocation ELoc = RefExpr->getExprLoc(); 11698 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 11699 if (DepKind == OMPC_DEPEND_sink) { 11700 if (DSAStack->getParentOrderedRegionParam().first && 11701 DepCounter >= TotalDepCount) { 11702 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 11703 continue; 11704 } 11705 ++DepCounter; 11706 // OpenMP [2.13.9, Summary] 11707 // depend(dependence-type : vec), where dependence-type is: 11708 // 'sink' and where vec is the iteration vector, which has the form: 11709 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 11710 // where n is the value specified by the ordered clause in the loop 11711 // directive, xi denotes the loop iteration variable of the i-th nested 11712 // loop associated with the loop directive, and di is a constant 11713 // non-negative integer. 11714 if (CurContext->isDependentContext()) { 11715 // It will be analyzed later. 11716 Vars.push_back(RefExpr); 11717 continue; 11718 } 11719 SimpleExpr = SimpleExpr->IgnoreImplicit(); 11720 OverloadedOperatorKind OOK = OO_None; 11721 SourceLocation OOLoc; 11722 Expr *LHS = SimpleExpr; 11723 Expr *RHS = nullptr; 11724 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 11725 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 11726 OOLoc = BO->getOperatorLoc(); 11727 LHS = BO->getLHS()->IgnoreParenImpCasts(); 11728 RHS = BO->getRHS()->IgnoreParenImpCasts(); 11729 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 11730 OOK = OCE->getOperator(); 11731 OOLoc = OCE->getOperatorLoc(); 11732 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 11733 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 11734 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 11735 OOK = MCE->getMethodDecl() 11736 ->getNameInfo() 11737 .getName() 11738 .getCXXOverloadedOperator(); 11739 OOLoc = MCE->getCallee()->getExprLoc(); 11740 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 11741 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 11742 } 11743 SourceLocation ELoc; 11744 SourceRange ERange; 11745 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 11746 /*AllowArraySection=*/false); 11747 if (Res.second) { 11748 // It will be analyzed later. 11749 Vars.push_back(RefExpr); 11750 } 11751 ValueDecl *D = Res.first; 11752 if (!D) 11753 continue; 11754 11755 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 11756 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 11757 continue; 11758 } 11759 if (RHS) { 11760 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 11761 RHS, OMPC_depend, /*StrictlyPositive=*/false); 11762 if (RHSRes.isInvalid()) 11763 continue; 11764 } 11765 if (!CurContext->isDependentContext() && 11766 DSAStack->getParentOrderedRegionParam().first && 11767 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 11768 const ValueDecl *VD = 11769 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 11770 if (VD) 11771 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 11772 << 1 << VD; 11773 else 11774 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 11775 continue; 11776 } 11777 OpsOffs.emplace_back(RHS, OOK); 11778 } else { 11779 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 11780 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 11781 (ASE && 11782 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 11783 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 11784 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 11785 << RefExpr->getSourceRange(); 11786 continue; 11787 } 11788 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 11789 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 11790 ExprResult Res = 11791 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 11792 getDiagnostics().setSuppressAllDiagnostics(Suppress); 11793 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 11794 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 11795 << RefExpr->getSourceRange(); 11796 continue; 11797 } 11798 } 11799 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 11800 } 11801 11802 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 11803 TotalDepCount > VarList.size() && 11804 DSAStack->getParentOrderedRegionParam().first && 11805 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 11806 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 11807 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 11808 } 11809 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 11810 Vars.empty()) 11811 return nullptr; 11812 11813 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11814 DepKind, DepLoc, ColonLoc, Vars, 11815 TotalDepCount.getZExtValue()); 11816 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 11817 DSAStack->isParentOrderedRegion()) 11818 DSAStack->addDoacrossDependClause(C, OpsOffs); 11819 return C; 11820 } 11821 11822 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 11823 SourceLocation LParenLoc, 11824 SourceLocation EndLoc) { 11825 Expr *ValExpr = Device; 11826 Stmt *HelperValStmt = nullptr; 11827 11828 // OpenMP [2.9.1, Restrictions] 11829 // The device expression must evaluate to a non-negative integer value. 11830 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 11831 /*StrictlyPositive=*/false)) 11832 return nullptr; 11833 11834 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11835 OpenMPDirectiveKind CaptureRegion = 11836 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 11837 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11838 ValExpr = MakeFullExpr(ValExpr).get(); 11839 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11840 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11841 HelperValStmt = buildPreInits(Context, Captures); 11842 } 11843 11844 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 11845 StartLoc, LParenLoc, EndLoc); 11846 } 11847 11848 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 11849 DSAStackTy *Stack, QualType QTy, 11850 bool FullCheck = true) { 11851 NamedDecl *ND; 11852 if (QTy->isIncompleteType(&ND)) { 11853 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 11854 return false; 11855 } 11856 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 11857 !QTy.isTrivialType(SemaRef.Context)) 11858 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 11859 return true; 11860 } 11861 11862 /// Return true if it can be proven that the provided array expression 11863 /// (array section or array subscript) does NOT specify the whole size of the 11864 /// array whose base type is \a BaseQTy. 11865 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 11866 const Expr *E, 11867 QualType BaseQTy) { 11868 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 11869 11870 // If this is an array subscript, it refers to the whole size if the size of 11871 // the dimension is constant and equals 1. Also, an array section assumes the 11872 // format of an array subscript if no colon is used. 11873 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 11874 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 11875 return ATy->getSize().getSExtValue() != 1; 11876 // Size can't be evaluated statically. 11877 return false; 11878 } 11879 11880 assert(OASE && "Expecting array section if not an array subscript."); 11881 const Expr *LowerBound = OASE->getLowerBound(); 11882 const Expr *Length = OASE->getLength(); 11883 11884 // If there is a lower bound that does not evaluates to zero, we are not 11885 // covering the whole dimension. 11886 if (LowerBound) { 11887 llvm::APSInt ConstLowerBound; 11888 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 11889 return false; // Can't get the integer value as a constant. 11890 if (ConstLowerBound.getSExtValue()) 11891 return true; 11892 } 11893 11894 // If we don't have a length we covering the whole dimension. 11895 if (!Length) 11896 return false; 11897 11898 // If the base is a pointer, we don't have a way to get the size of the 11899 // pointee. 11900 if (BaseQTy->isPointerType()) 11901 return false; 11902 11903 // We can only check if the length is the same as the size of the dimension 11904 // if we have a constant array. 11905 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 11906 if (!CATy) 11907 return false; 11908 11909 llvm::APSInt ConstLength; 11910 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 11911 return false; // Can't get the integer value as a constant. 11912 11913 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 11914 } 11915 11916 // Return true if it can be proven that the provided array expression (array 11917 // section or array subscript) does NOT specify a single element of the array 11918 // whose base type is \a BaseQTy. 11919 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 11920 const Expr *E, 11921 QualType BaseQTy) { 11922 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 11923 11924 // An array subscript always refer to a single element. Also, an array section 11925 // assumes the format of an array subscript if no colon is used. 11926 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 11927 return false; 11928 11929 assert(OASE && "Expecting array section if not an array subscript."); 11930 const Expr *Length = OASE->getLength(); 11931 11932 // If we don't have a length we have to check if the array has unitary size 11933 // for this dimension. Also, we should always expect a length if the base type 11934 // is pointer. 11935 if (!Length) { 11936 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 11937 return ATy->getSize().getSExtValue() != 1; 11938 // We cannot assume anything. 11939 return false; 11940 } 11941 11942 // Check if the length evaluates to 1. 11943 llvm::APSInt ConstLength; 11944 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 11945 return false; // Can't get the integer value as a constant. 11946 11947 return ConstLength.getSExtValue() != 1; 11948 } 11949 11950 // Return the expression of the base of the mappable expression or null if it 11951 // cannot be determined and do all the necessary checks to see if the expression 11952 // is valid as a standalone mappable expression. In the process, record all the 11953 // components of the expression. 11954 static const Expr *checkMapClauseExpressionBase( 11955 Sema &SemaRef, Expr *E, 11956 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 11957 OpenMPClauseKind CKind, bool NoDiagnose) { 11958 SourceLocation ELoc = E->getExprLoc(); 11959 SourceRange ERange = E->getSourceRange(); 11960 11961 // The base of elements of list in a map clause have to be either: 11962 // - a reference to variable or field. 11963 // - a member expression. 11964 // - an array expression. 11965 // 11966 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 11967 // reference to 'r'. 11968 // 11969 // If we have: 11970 // 11971 // struct SS { 11972 // Bla S; 11973 // foo() { 11974 // #pragma omp target map (S.Arr[:12]); 11975 // } 11976 // } 11977 // 11978 // We want to retrieve the member expression 'this->S'; 11979 11980 const Expr *RelevantExpr = nullptr; 11981 11982 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 11983 // If a list item is an array section, it must specify contiguous storage. 11984 // 11985 // For this restriction it is sufficient that we make sure only references 11986 // to variables or fields and array expressions, and that no array sections 11987 // exist except in the rightmost expression (unless they cover the whole 11988 // dimension of the array). E.g. these would be invalid: 11989 // 11990 // r.ArrS[3:5].Arr[6:7] 11991 // 11992 // r.ArrS[3:5].x 11993 // 11994 // but these would be valid: 11995 // r.ArrS[3].Arr[6:7] 11996 // 11997 // r.ArrS[3].x 11998 11999 bool AllowUnitySizeArraySection = true; 12000 bool AllowWholeSizeArraySection = true; 12001 12002 while (!RelevantExpr) { 12003 E = E->IgnoreParenImpCasts(); 12004 12005 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 12006 if (!isa<VarDecl>(CurE->getDecl())) 12007 return nullptr; 12008 12009 RelevantExpr = CurE; 12010 12011 // If we got a reference to a declaration, we should not expect any array 12012 // section before that. 12013 AllowUnitySizeArraySection = false; 12014 AllowWholeSizeArraySection = false; 12015 12016 // Record the component. 12017 CurComponents.emplace_back(CurE, CurE->getDecl()); 12018 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 12019 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 12020 12021 if (isa<CXXThisExpr>(BaseE)) 12022 // We found a base expression: this->Val. 12023 RelevantExpr = CurE; 12024 else 12025 E = BaseE; 12026 12027 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 12028 if (!NoDiagnose) { 12029 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 12030 << CurE->getSourceRange(); 12031 return nullptr; 12032 } 12033 if (RelevantExpr) 12034 return nullptr; 12035 continue; 12036 } 12037 12038 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 12039 12040 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 12041 // A bit-field cannot appear in a map clause. 12042 // 12043 if (FD->isBitField()) { 12044 if (!NoDiagnose) { 12045 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 12046 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 12047 return nullptr; 12048 } 12049 if (RelevantExpr) 12050 return nullptr; 12051 continue; 12052 } 12053 12054 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12055 // If the type of a list item is a reference to a type T then the type 12056 // will be considered to be T for all purposes of this clause. 12057 QualType CurType = BaseE->getType().getNonReferenceType(); 12058 12059 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 12060 // A list item cannot be a variable that is a member of a structure with 12061 // a union type. 12062 // 12063 if (CurType->isUnionType()) { 12064 if (!NoDiagnose) { 12065 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 12066 << CurE->getSourceRange(); 12067 return nullptr; 12068 } 12069 continue; 12070 } 12071 12072 // If we got a member expression, we should not expect any array section 12073 // before that: 12074 // 12075 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 12076 // If a list item is an element of a structure, only the rightmost symbol 12077 // of the variable reference can be an array section. 12078 // 12079 AllowUnitySizeArraySection = false; 12080 AllowWholeSizeArraySection = false; 12081 12082 // Record the component. 12083 CurComponents.emplace_back(CurE, FD); 12084 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 12085 E = CurE->getBase()->IgnoreParenImpCasts(); 12086 12087 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 12088 if (!NoDiagnose) { 12089 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12090 << 0 << CurE->getSourceRange(); 12091 return nullptr; 12092 } 12093 continue; 12094 } 12095 12096 // If we got an array subscript that express the whole dimension we 12097 // can have any array expressions before. If it only expressing part of 12098 // the dimension, we can only have unitary-size array expressions. 12099 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 12100 E->getType())) 12101 AllowWholeSizeArraySection = false; 12102 12103 // Record the component - we don't have any declaration associated. 12104 CurComponents.emplace_back(CurE, nullptr); 12105 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 12106 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 12107 E = CurE->getBase()->IgnoreParenImpCasts(); 12108 12109 QualType CurType = 12110 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12111 12112 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12113 // If the type of a list item is a reference to a type T then the type 12114 // will be considered to be T for all purposes of this clause. 12115 if (CurType->isReferenceType()) 12116 CurType = CurType->getPointeeType(); 12117 12118 bool IsPointer = CurType->isAnyPointerType(); 12119 12120 if (!IsPointer && !CurType->isArrayType()) { 12121 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12122 << 0 << CurE->getSourceRange(); 12123 return nullptr; 12124 } 12125 12126 bool NotWhole = 12127 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 12128 bool NotUnity = 12129 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 12130 12131 if (AllowWholeSizeArraySection) { 12132 // Any array section is currently allowed. Allowing a whole size array 12133 // section implies allowing a unity array section as well. 12134 // 12135 // If this array section refers to the whole dimension we can still 12136 // accept other array sections before this one, except if the base is a 12137 // pointer. Otherwise, only unitary sections are accepted. 12138 if (NotWhole || IsPointer) 12139 AllowWholeSizeArraySection = false; 12140 } else if (AllowUnitySizeArraySection && NotUnity) { 12141 // A unity or whole array section is not allowed and that is not 12142 // compatible with the properties of the current array section. 12143 SemaRef.Diag( 12144 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 12145 << CurE->getSourceRange(); 12146 return nullptr; 12147 } 12148 12149 // Record the component - we don't have any declaration associated. 12150 CurComponents.emplace_back(CurE, nullptr); 12151 } else { 12152 if (!NoDiagnose) { 12153 // If nothing else worked, this is not a valid map clause expression. 12154 SemaRef.Diag( 12155 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 12156 << ERange; 12157 } 12158 return nullptr; 12159 } 12160 } 12161 12162 return RelevantExpr; 12163 } 12164 12165 // Return true if expression E associated with value VD has conflicts with other 12166 // map information. 12167 static bool checkMapConflicts( 12168 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 12169 bool CurrentRegionOnly, 12170 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 12171 OpenMPClauseKind CKind) { 12172 assert(VD && E); 12173 SourceLocation ELoc = E->getExprLoc(); 12174 SourceRange ERange = E->getSourceRange(); 12175 12176 // In order to easily check the conflicts we need to match each component of 12177 // the expression under test with the components of the expressions that are 12178 // already in the stack. 12179 12180 assert(!CurComponents.empty() && "Map clause expression with no components!"); 12181 assert(CurComponents.back().getAssociatedDeclaration() == VD && 12182 "Map clause expression with unexpected base!"); 12183 12184 // Variables to help detecting enclosing problems in data environment nests. 12185 bool IsEnclosedByDataEnvironmentExpr = false; 12186 const Expr *EnclosingExpr = nullptr; 12187 12188 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 12189 VD, CurrentRegionOnly, 12190 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 12191 ERange, CKind, &EnclosingExpr, 12192 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 12193 StackComponents, 12194 OpenMPClauseKind) { 12195 assert(!StackComponents.empty() && 12196 "Map clause expression with no components!"); 12197 assert(StackComponents.back().getAssociatedDeclaration() == VD && 12198 "Map clause expression with unexpected base!"); 12199 (void)VD; 12200 12201 // The whole expression in the stack. 12202 const Expr *RE = StackComponents.front().getAssociatedExpression(); 12203 12204 // Expressions must start from the same base. Here we detect at which 12205 // point both expressions diverge from each other and see if we can 12206 // detect if the memory referred to both expressions is contiguous and 12207 // do not overlap. 12208 auto CI = CurComponents.rbegin(); 12209 auto CE = CurComponents.rend(); 12210 auto SI = StackComponents.rbegin(); 12211 auto SE = StackComponents.rend(); 12212 for (; CI != CE && SI != SE; ++CI, ++SI) { 12213 12214 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 12215 // At most one list item can be an array item derived from a given 12216 // variable in map clauses of the same construct. 12217 if (CurrentRegionOnly && 12218 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 12219 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 12220 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 12221 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 12222 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 12223 diag::err_omp_multiple_array_items_in_map_clause) 12224 << CI->getAssociatedExpression()->getSourceRange(); 12225 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 12226 diag::note_used_here) 12227 << SI->getAssociatedExpression()->getSourceRange(); 12228 return true; 12229 } 12230 12231 // Do both expressions have the same kind? 12232 if (CI->getAssociatedExpression()->getStmtClass() != 12233 SI->getAssociatedExpression()->getStmtClass()) 12234 break; 12235 12236 // Are we dealing with different variables/fields? 12237 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 12238 break; 12239 } 12240 // Check if the extra components of the expressions in the enclosing 12241 // data environment are redundant for the current base declaration. 12242 // If they are, the maps completely overlap, which is legal. 12243 for (; SI != SE; ++SI) { 12244 QualType Type; 12245 if (const auto *ASE = 12246 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 12247 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 12248 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 12249 SI->getAssociatedExpression())) { 12250 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 12251 Type = 12252 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12253 } 12254 if (Type.isNull() || Type->isAnyPointerType() || 12255 checkArrayExpressionDoesNotReferToWholeSize( 12256 SemaRef, SI->getAssociatedExpression(), Type)) 12257 break; 12258 } 12259 12260 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 12261 // List items of map clauses in the same construct must not share 12262 // original storage. 12263 // 12264 // If the expressions are exactly the same or one is a subset of the 12265 // other, it means they are sharing storage. 12266 if (CI == CE && SI == SE) { 12267 if (CurrentRegionOnly) { 12268 if (CKind == OMPC_map) { 12269 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 12270 } else { 12271 assert(CKind == OMPC_to || CKind == OMPC_from); 12272 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 12273 << ERange; 12274 } 12275 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12276 << RE->getSourceRange(); 12277 return true; 12278 } 12279 // If we find the same expression in the enclosing data environment, 12280 // that is legal. 12281 IsEnclosedByDataEnvironmentExpr = true; 12282 return false; 12283 } 12284 12285 QualType DerivedType = 12286 std::prev(CI)->getAssociatedDeclaration()->getType(); 12287 SourceLocation DerivedLoc = 12288 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 12289 12290 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12291 // If the type of a list item is a reference to a type T then the type 12292 // will be considered to be T for all purposes of this clause. 12293 DerivedType = DerivedType.getNonReferenceType(); 12294 12295 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 12296 // A variable for which the type is pointer and an array section 12297 // derived from that variable must not appear as list items of map 12298 // clauses of the same construct. 12299 // 12300 // Also, cover one of the cases in: 12301 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 12302 // If any part of the original storage of a list item has corresponding 12303 // storage in the device data environment, all of the original storage 12304 // must have corresponding storage in the device data environment. 12305 // 12306 if (DerivedType->isAnyPointerType()) { 12307 if (CI == CE || SI == SE) { 12308 SemaRef.Diag( 12309 DerivedLoc, 12310 diag::err_omp_pointer_mapped_along_with_derived_section) 12311 << DerivedLoc; 12312 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12313 << RE->getSourceRange(); 12314 return true; 12315 } 12316 if (CI->getAssociatedExpression()->getStmtClass() != 12317 SI->getAssociatedExpression()->getStmtClass() || 12318 CI->getAssociatedDeclaration()->getCanonicalDecl() == 12319 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 12320 assert(CI != CE && SI != SE); 12321 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 12322 << DerivedLoc; 12323 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12324 << RE->getSourceRange(); 12325 return true; 12326 } 12327 } 12328 12329 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 12330 // List items of map clauses in the same construct must not share 12331 // original storage. 12332 // 12333 // An expression is a subset of the other. 12334 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 12335 if (CKind == OMPC_map) { 12336 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 12337 } else { 12338 assert(CKind == OMPC_to || CKind == OMPC_from); 12339 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 12340 << ERange; 12341 } 12342 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12343 << RE->getSourceRange(); 12344 return true; 12345 } 12346 12347 // The current expression uses the same base as other expression in the 12348 // data environment but does not contain it completely. 12349 if (!CurrentRegionOnly && SI != SE) 12350 EnclosingExpr = RE; 12351 12352 // The current expression is a subset of the expression in the data 12353 // environment. 12354 IsEnclosedByDataEnvironmentExpr |= 12355 (!CurrentRegionOnly && CI != CE && SI == SE); 12356 12357 return false; 12358 }); 12359 12360 if (CurrentRegionOnly) 12361 return FoundError; 12362 12363 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 12364 // If any part of the original storage of a list item has corresponding 12365 // storage in the device data environment, all of the original storage must 12366 // have corresponding storage in the device data environment. 12367 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 12368 // If a list item is an element of a structure, and a different element of 12369 // the structure has a corresponding list item in the device data environment 12370 // prior to a task encountering the construct associated with the map clause, 12371 // then the list item must also have a corresponding list item in the device 12372 // data environment prior to the task encountering the construct. 12373 // 12374 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 12375 SemaRef.Diag(ELoc, 12376 diag::err_omp_original_storage_is_shared_and_does_not_contain) 12377 << ERange; 12378 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 12379 << EnclosingExpr->getSourceRange(); 12380 return true; 12381 } 12382 12383 return FoundError; 12384 } 12385 12386 namespace { 12387 // Utility struct that gathers all the related lists associated with a mappable 12388 // expression. 12389 struct MappableVarListInfo { 12390 // The list of expressions. 12391 ArrayRef<Expr *> VarList; 12392 // The list of processed expressions. 12393 SmallVector<Expr *, 16> ProcessedVarList; 12394 // The mappble components for each expression. 12395 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 12396 // The base declaration of the variable. 12397 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 12398 12399 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 12400 // We have a list of components and base declarations for each entry in the 12401 // variable list. 12402 VarComponents.reserve(VarList.size()); 12403 VarBaseDeclarations.reserve(VarList.size()); 12404 } 12405 }; 12406 } 12407 12408 // Check the validity of the provided variable list for the provided clause kind 12409 // \a CKind. In the check process the valid expressions, and mappable expression 12410 // components and variables are extracted and used to fill \a Vars, 12411 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 12412 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 12413 static void 12414 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 12415 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 12416 SourceLocation StartLoc, 12417 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 12418 bool IsMapTypeImplicit = false) { 12419 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 12420 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 12421 "Unexpected clause kind with mappable expressions!"); 12422 12423 // Keep track of the mappable components and base declarations in this clause. 12424 // Each entry in the list is going to have a list of components associated. We 12425 // record each set of the components so that we can build the clause later on. 12426 // In the end we should have the same amount of declarations and component 12427 // lists. 12428 12429 for (Expr *RE : MVLI.VarList) { 12430 assert(RE && "Null expr in omp to/from/map clause"); 12431 SourceLocation ELoc = RE->getExprLoc(); 12432 12433 const Expr *VE = RE->IgnoreParenLValueCasts(); 12434 12435 if (VE->isValueDependent() || VE->isTypeDependent() || 12436 VE->isInstantiationDependent() || 12437 VE->containsUnexpandedParameterPack()) { 12438 // We can only analyze this information once the missing information is 12439 // resolved. 12440 MVLI.ProcessedVarList.push_back(RE); 12441 continue; 12442 } 12443 12444 Expr *SimpleExpr = RE->IgnoreParenCasts(); 12445 12446 if (!RE->IgnoreParenImpCasts()->isLValue()) { 12447 SemaRef.Diag(ELoc, 12448 diag::err_omp_expected_named_var_member_or_array_expression) 12449 << RE->getSourceRange(); 12450 continue; 12451 } 12452 12453 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 12454 ValueDecl *CurDeclaration = nullptr; 12455 12456 // Obtain the array or member expression bases if required. Also, fill the 12457 // components array with all the components identified in the process. 12458 const Expr *BE = checkMapClauseExpressionBase( 12459 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 12460 if (!BE) 12461 continue; 12462 12463 assert(!CurComponents.empty() && 12464 "Invalid mappable expression information."); 12465 12466 // For the following checks, we rely on the base declaration which is 12467 // expected to be associated with the last component. The declaration is 12468 // expected to be a variable or a field (if 'this' is being mapped). 12469 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 12470 assert(CurDeclaration && "Null decl on map clause."); 12471 assert( 12472 CurDeclaration->isCanonicalDecl() && 12473 "Expecting components to have associated only canonical declarations."); 12474 12475 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 12476 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 12477 12478 assert((VD || FD) && "Only variables or fields are expected here!"); 12479 (void)FD; 12480 12481 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 12482 // threadprivate variables cannot appear in a map clause. 12483 // OpenMP 4.5 [2.10.5, target update Construct] 12484 // threadprivate variables cannot appear in a from clause. 12485 if (VD && DSAS->isThreadPrivate(VD)) { 12486 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 12487 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 12488 << getOpenMPClauseName(CKind); 12489 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 12490 continue; 12491 } 12492 12493 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12494 // A list item cannot appear in both a map clause and a data-sharing 12495 // attribute clause on the same construct. 12496 12497 // Check conflicts with other map clause expressions. We check the conflicts 12498 // with the current construct separately from the enclosing data 12499 // environment, because the restrictions are different. We only have to 12500 // check conflicts across regions for the map clauses. 12501 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12502 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 12503 break; 12504 if (CKind == OMPC_map && 12505 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12506 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 12507 break; 12508 12509 // OpenMP 4.5 [2.10.5, target update Construct] 12510 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12511 // If the type of a list item is a reference to a type T then the type will 12512 // be considered to be T for all purposes of this clause. 12513 auto I = llvm::find_if( 12514 CurComponents, 12515 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 12516 return MC.getAssociatedDeclaration(); 12517 }); 12518 assert(I != CurComponents.end() && "Null decl on map clause."); 12519 QualType Type = 12520 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 12521 12522 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 12523 // A list item in a to or from clause must have a mappable type. 12524 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12525 // A list item must have a mappable type. 12526 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 12527 DSAS, Type)) 12528 continue; 12529 12530 if (CKind == OMPC_map) { 12531 // target enter data 12532 // OpenMP [2.10.2, Restrictions, p. 99] 12533 // A map-type must be specified in all map clauses and must be either 12534 // to or alloc. 12535 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 12536 if (DKind == OMPD_target_enter_data && 12537 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 12538 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 12539 << (IsMapTypeImplicit ? 1 : 0) 12540 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 12541 << getOpenMPDirectiveName(DKind); 12542 continue; 12543 } 12544 12545 // target exit_data 12546 // OpenMP [2.10.3, Restrictions, p. 102] 12547 // A map-type must be specified in all map clauses and must be either 12548 // from, release, or delete. 12549 if (DKind == OMPD_target_exit_data && 12550 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 12551 MapType == OMPC_MAP_delete)) { 12552 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 12553 << (IsMapTypeImplicit ? 1 : 0) 12554 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 12555 << getOpenMPDirectiveName(DKind); 12556 continue; 12557 } 12558 12559 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12560 // A list item cannot appear in both a map clause and a data-sharing 12561 // attribute clause on the same construct 12562 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 12563 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 12564 if (isOpenMPPrivate(DVar.CKind)) { 12565 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12566 << getOpenMPClauseName(DVar.CKind) 12567 << getOpenMPClauseName(OMPC_map) 12568 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 12569 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 12570 continue; 12571 } 12572 } 12573 } 12574 12575 // Save the current expression. 12576 MVLI.ProcessedVarList.push_back(RE); 12577 12578 // Store the components in the stack so that they can be used to check 12579 // against other clauses later on. 12580 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 12581 /*WhereFoundClauseKind=*/OMPC_map); 12582 12583 // Save the components and declaration to create the clause. For purposes of 12584 // the clause creation, any component list that has has base 'this' uses 12585 // null as base declaration. 12586 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12587 MVLI.VarComponents.back().append(CurComponents.begin(), 12588 CurComponents.end()); 12589 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 12590 : CurDeclaration); 12591 } 12592 } 12593 12594 OMPClause * 12595 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 12596 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 12597 SourceLocation MapLoc, SourceLocation ColonLoc, 12598 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12599 SourceLocation LParenLoc, SourceLocation EndLoc) { 12600 MappableVarListInfo MVLI(VarList); 12601 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 12602 MapType, IsMapTypeImplicit); 12603 12604 // We need to produce a map clause even if we don't have variables so that 12605 // other diagnostics related with non-existing map clauses are accurate. 12606 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12607 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12608 MVLI.VarComponents, MapTypeModifier, MapType, 12609 IsMapTypeImplicit, MapLoc); 12610 } 12611 12612 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 12613 TypeResult ParsedType) { 12614 assert(ParsedType.isUsable()); 12615 12616 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 12617 if (ReductionType.isNull()) 12618 return QualType(); 12619 12620 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 12621 // A type name in a declare reduction directive cannot be a function type, an 12622 // array type, a reference type, or a type qualified with const, volatile or 12623 // restrict. 12624 if (ReductionType.hasQualifiers()) { 12625 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 12626 return QualType(); 12627 } 12628 12629 if (ReductionType->isFunctionType()) { 12630 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 12631 return QualType(); 12632 } 12633 if (ReductionType->isReferenceType()) { 12634 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 12635 return QualType(); 12636 } 12637 if (ReductionType->isArrayType()) { 12638 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 12639 return QualType(); 12640 } 12641 return ReductionType; 12642 } 12643 12644 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 12645 Scope *S, DeclContext *DC, DeclarationName Name, 12646 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 12647 AccessSpecifier AS, Decl *PrevDeclInScope) { 12648 SmallVector<Decl *, 8> Decls; 12649 Decls.reserve(ReductionTypes.size()); 12650 12651 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 12652 forRedeclarationInCurContext()); 12653 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 12654 // A reduction-identifier may not be re-declared in the current scope for the 12655 // same type or for a type that is compatible according to the base language 12656 // rules. 12657 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 12658 OMPDeclareReductionDecl *PrevDRD = nullptr; 12659 bool InCompoundScope = true; 12660 if (S != nullptr) { 12661 // Find previous declaration with the same name not referenced in other 12662 // declarations. 12663 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 12664 InCompoundScope = 12665 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 12666 LookupName(Lookup, S); 12667 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 12668 /*AllowInlineNamespace=*/false); 12669 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 12670 LookupResult::Filter Filter = Lookup.makeFilter(); 12671 while (Filter.hasNext()) { 12672 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 12673 if (InCompoundScope) { 12674 auto I = UsedAsPrevious.find(PrevDecl); 12675 if (I == UsedAsPrevious.end()) 12676 UsedAsPrevious[PrevDecl] = false; 12677 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 12678 UsedAsPrevious[D] = true; 12679 } 12680 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 12681 PrevDecl->getLocation(); 12682 } 12683 Filter.done(); 12684 if (InCompoundScope) { 12685 for (const auto &PrevData : UsedAsPrevious) { 12686 if (!PrevData.second) { 12687 PrevDRD = PrevData.first; 12688 break; 12689 } 12690 } 12691 } 12692 } else if (PrevDeclInScope != nullptr) { 12693 auto *PrevDRDInScope = PrevDRD = 12694 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 12695 do { 12696 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 12697 PrevDRDInScope->getLocation(); 12698 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 12699 } while (PrevDRDInScope != nullptr); 12700 } 12701 for (const auto &TyData : ReductionTypes) { 12702 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 12703 bool Invalid = false; 12704 if (I != PreviousRedeclTypes.end()) { 12705 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 12706 << TyData.first; 12707 Diag(I->second, diag::note_previous_definition); 12708 Invalid = true; 12709 } 12710 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 12711 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 12712 Name, TyData.first, PrevDRD); 12713 DC->addDecl(DRD); 12714 DRD->setAccess(AS); 12715 Decls.push_back(DRD); 12716 if (Invalid) 12717 DRD->setInvalidDecl(); 12718 else 12719 PrevDRD = DRD; 12720 } 12721 12722 return DeclGroupPtrTy::make( 12723 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 12724 } 12725 12726 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 12727 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12728 12729 // Enter new function scope. 12730 PushFunctionScope(); 12731 setFunctionHasBranchProtectedScope(); 12732 getCurFunction()->setHasOMPDeclareReductionCombiner(); 12733 12734 if (S != nullptr) 12735 PushDeclContext(S, DRD); 12736 else 12737 CurContext = DRD; 12738 12739 PushExpressionEvaluationContext( 12740 ExpressionEvaluationContext::PotentiallyEvaluated); 12741 12742 QualType ReductionType = DRD->getType(); 12743 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 12744 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 12745 // uses semantics of argument handles by value, but it should be passed by 12746 // reference. C lang does not support references, so pass all parameters as 12747 // pointers. 12748 // Create 'T omp_in;' variable. 12749 VarDecl *OmpInParm = 12750 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 12751 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 12752 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 12753 // uses semantics of argument handles by value, but it should be passed by 12754 // reference. C lang does not support references, so pass all parameters as 12755 // pointers. 12756 // Create 'T omp_out;' variable. 12757 VarDecl *OmpOutParm = 12758 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 12759 if (S != nullptr) { 12760 PushOnScopeChains(OmpInParm, S); 12761 PushOnScopeChains(OmpOutParm, S); 12762 } else { 12763 DRD->addDecl(OmpInParm); 12764 DRD->addDecl(OmpOutParm); 12765 } 12766 Expr *InE = 12767 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 12768 Expr *OutE = 12769 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 12770 DRD->setCombinerData(InE, OutE); 12771 } 12772 12773 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 12774 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12775 DiscardCleanupsInEvaluationContext(); 12776 PopExpressionEvaluationContext(); 12777 12778 PopDeclContext(); 12779 PopFunctionScopeInfo(); 12780 12781 if (Combiner != nullptr) 12782 DRD->setCombiner(Combiner); 12783 else 12784 DRD->setInvalidDecl(); 12785 } 12786 12787 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 12788 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12789 12790 // Enter new function scope. 12791 PushFunctionScope(); 12792 setFunctionHasBranchProtectedScope(); 12793 12794 if (S != nullptr) 12795 PushDeclContext(S, DRD); 12796 else 12797 CurContext = DRD; 12798 12799 PushExpressionEvaluationContext( 12800 ExpressionEvaluationContext::PotentiallyEvaluated); 12801 12802 QualType ReductionType = DRD->getType(); 12803 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 12804 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 12805 // uses semantics of argument handles by value, but it should be passed by 12806 // reference. C lang does not support references, so pass all parameters as 12807 // pointers. 12808 // Create 'T omp_priv;' variable. 12809 VarDecl *OmpPrivParm = 12810 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 12811 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 12812 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 12813 // uses semantics of argument handles by value, but it should be passed by 12814 // reference. C lang does not support references, so pass all parameters as 12815 // pointers. 12816 // Create 'T omp_orig;' variable. 12817 VarDecl *OmpOrigParm = 12818 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 12819 if (S != nullptr) { 12820 PushOnScopeChains(OmpPrivParm, S); 12821 PushOnScopeChains(OmpOrigParm, S); 12822 } else { 12823 DRD->addDecl(OmpPrivParm); 12824 DRD->addDecl(OmpOrigParm); 12825 } 12826 Expr *OrigE = 12827 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 12828 Expr *PrivE = 12829 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 12830 DRD->setInitializerData(OrigE, PrivE); 12831 return OmpPrivParm; 12832 } 12833 12834 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 12835 VarDecl *OmpPrivParm) { 12836 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12837 DiscardCleanupsInEvaluationContext(); 12838 PopExpressionEvaluationContext(); 12839 12840 PopDeclContext(); 12841 PopFunctionScopeInfo(); 12842 12843 if (Initializer != nullptr) { 12844 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 12845 } else if (OmpPrivParm->hasInit()) { 12846 DRD->setInitializer(OmpPrivParm->getInit(), 12847 OmpPrivParm->isDirectInit() 12848 ? OMPDeclareReductionDecl::DirectInit 12849 : OMPDeclareReductionDecl::CopyInit); 12850 } else { 12851 DRD->setInvalidDecl(); 12852 } 12853 } 12854 12855 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 12856 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 12857 for (Decl *D : DeclReductions.get()) { 12858 if (IsValid) { 12859 if (S) 12860 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 12861 /*AddToContext=*/false); 12862 } else { 12863 D->setInvalidDecl(); 12864 } 12865 } 12866 return DeclReductions; 12867 } 12868 12869 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 12870 SourceLocation StartLoc, 12871 SourceLocation LParenLoc, 12872 SourceLocation EndLoc) { 12873 Expr *ValExpr = NumTeams; 12874 Stmt *HelperValStmt = nullptr; 12875 12876 // OpenMP [teams Constrcut, Restrictions] 12877 // The num_teams expression must evaluate to a positive integer value. 12878 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 12879 /*StrictlyPositive=*/true)) 12880 return nullptr; 12881 12882 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12883 OpenMPDirectiveKind CaptureRegion = 12884 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 12885 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12886 ValExpr = MakeFullExpr(ValExpr).get(); 12887 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12888 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12889 HelperValStmt = buildPreInits(Context, Captures); 12890 } 12891 12892 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 12893 StartLoc, LParenLoc, EndLoc); 12894 } 12895 12896 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 12897 SourceLocation StartLoc, 12898 SourceLocation LParenLoc, 12899 SourceLocation EndLoc) { 12900 Expr *ValExpr = ThreadLimit; 12901 Stmt *HelperValStmt = nullptr; 12902 12903 // OpenMP [teams Constrcut, Restrictions] 12904 // The thread_limit expression must evaluate to a positive integer value. 12905 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 12906 /*StrictlyPositive=*/true)) 12907 return nullptr; 12908 12909 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12910 OpenMPDirectiveKind CaptureRegion = 12911 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 12912 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12913 ValExpr = MakeFullExpr(ValExpr).get(); 12914 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12915 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12916 HelperValStmt = buildPreInits(Context, Captures); 12917 } 12918 12919 return new (Context) OMPThreadLimitClause( 12920 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12921 } 12922 12923 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 12924 SourceLocation StartLoc, 12925 SourceLocation LParenLoc, 12926 SourceLocation EndLoc) { 12927 Expr *ValExpr = Priority; 12928 12929 // OpenMP [2.9.1, task Constrcut] 12930 // The priority-value is a non-negative numerical scalar expression. 12931 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 12932 /*StrictlyPositive=*/false)) 12933 return nullptr; 12934 12935 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12936 } 12937 12938 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 12939 SourceLocation StartLoc, 12940 SourceLocation LParenLoc, 12941 SourceLocation EndLoc) { 12942 Expr *ValExpr = Grainsize; 12943 12944 // OpenMP [2.9.2, taskloop Constrcut] 12945 // The parameter of the grainsize clause must be a positive integer 12946 // expression. 12947 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 12948 /*StrictlyPositive=*/true)) 12949 return nullptr; 12950 12951 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12952 } 12953 12954 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 12955 SourceLocation StartLoc, 12956 SourceLocation LParenLoc, 12957 SourceLocation EndLoc) { 12958 Expr *ValExpr = NumTasks; 12959 12960 // OpenMP [2.9.2, taskloop Constrcut] 12961 // The parameter of the num_tasks clause must be a positive integer 12962 // expression. 12963 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 12964 /*StrictlyPositive=*/true)) 12965 return nullptr; 12966 12967 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12968 } 12969 12970 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 12971 SourceLocation LParenLoc, 12972 SourceLocation EndLoc) { 12973 // OpenMP [2.13.2, critical construct, Description] 12974 // ... where hint-expression is an integer constant expression that evaluates 12975 // to a valid lock hint. 12976 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 12977 if (HintExpr.isInvalid()) 12978 return nullptr; 12979 return new (Context) 12980 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 12981 } 12982 12983 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 12984 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12985 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 12986 SourceLocation EndLoc) { 12987 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 12988 std::string Values; 12989 Values += "'"; 12990 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 12991 Values += "'"; 12992 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12993 << Values << getOpenMPClauseName(OMPC_dist_schedule); 12994 return nullptr; 12995 } 12996 Expr *ValExpr = ChunkSize; 12997 Stmt *HelperValStmt = nullptr; 12998 if (ChunkSize) { 12999 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13000 !ChunkSize->isInstantiationDependent() && 13001 !ChunkSize->containsUnexpandedParameterPack()) { 13002 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13003 ExprResult Val = 13004 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13005 if (Val.isInvalid()) 13006 return nullptr; 13007 13008 ValExpr = Val.get(); 13009 13010 // OpenMP [2.7.1, Restrictions] 13011 // chunk_size must be a loop invariant integer expression with a positive 13012 // value. 13013 llvm::APSInt Result; 13014 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 13015 if (Result.isSigned() && !Result.isStrictlyPositive()) { 13016 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13017 << "dist_schedule" << ChunkSize->getSourceRange(); 13018 return nullptr; 13019 } 13020 } else if (getOpenMPCaptureRegionForClause( 13021 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 13022 OMPD_unknown && 13023 !CurContext->isDependentContext()) { 13024 ValExpr = MakeFullExpr(ValExpr).get(); 13025 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13026 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13027 HelperValStmt = buildPreInits(Context, Captures); 13028 } 13029 } 13030 } 13031 13032 return new (Context) 13033 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 13034 Kind, ValExpr, HelperValStmt); 13035 } 13036 13037 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 13038 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 13039 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 13040 SourceLocation KindLoc, SourceLocation EndLoc) { 13041 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 13042 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 13043 std::string Value; 13044 SourceLocation Loc; 13045 Value += "'"; 13046 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 13047 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 13048 OMPC_DEFAULTMAP_MODIFIER_tofrom); 13049 Loc = MLoc; 13050 } else { 13051 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 13052 OMPC_DEFAULTMAP_scalar); 13053 Loc = KindLoc; 13054 } 13055 Value += "'"; 13056 Diag(Loc, diag::err_omp_unexpected_clause_value) 13057 << Value << getOpenMPClauseName(OMPC_defaultmap); 13058 return nullptr; 13059 } 13060 DSAStack->setDefaultDMAToFromScalar(StartLoc); 13061 13062 return new (Context) 13063 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 13064 } 13065 13066 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 13067 DeclContext *CurLexicalContext = getCurLexicalContext(); 13068 if (!CurLexicalContext->isFileContext() && 13069 !CurLexicalContext->isExternCContext() && 13070 !CurLexicalContext->isExternCXXContext() && 13071 !isa<CXXRecordDecl>(CurLexicalContext) && 13072 !isa<ClassTemplateDecl>(CurLexicalContext) && 13073 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 13074 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 13075 Diag(Loc, diag::err_omp_region_not_file_context); 13076 return false; 13077 } 13078 ++DeclareTargetNestingLevel; 13079 return true; 13080 } 13081 13082 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 13083 assert(DeclareTargetNestingLevel > 0 && 13084 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 13085 --DeclareTargetNestingLevel; 13086 } 13087 13088 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 13089 CXXScopeSpec &ScopeSpec, 13090 const DeclarationNameInfo &Id, 13091 OMPDeclareTargetDeclAttr::MapTypeTy MT, 13092 NamedDeclSetType &SameDirectiveDecls) { 13093 LookupResult Lookup(*this, Id, LookupOrdinaryName); 13094 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 13095 13096 if (Lookup.isAmbiguous()) 13097 return; 13098 Lookup.suppressDiagnostics(); 13099 13100 if (!Lookup.isSingleResult()) { 13101 if (TypoCorrection Corrected = 13102 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 13103 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 13104 CTK_ErrorRecovery)) { 13105 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 13106 << Id.getName()); 13107 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 13108 return; 13109 } 13110 13111 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 13112 return; 13113 } 13114 13115 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 13116 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 13117 isa<FunctionTemplateDecl>(ND)) { 13118 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 13119 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 13120 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 13121 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 13122 cast<ValueDecl>(ND)); 13123 if (!Res) { 13124 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 13125 ND->addAttr(A); 13126 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13127 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 13128 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 13129 } else if (*Res != MT) { 13130 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 13131 << Id.getName(); 13132 } 13133 } else { 13134 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 13135 } 13136 } 13137 13138 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 13139 Sema &SemaRef, Decl *D) { 13140 if (!D || !isa<VarDecl>(D)) 13141 return; 13142 auto *VD = cast<VarDecl>(D); 13143 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 13144 return; 13145 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 13146 SemaRef.Diag(SL, diag::note_used_here) << SR; 13147 } 13148 13149 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 13150 Sema &SemaRef, DSAStackTy *Stack, 13151 ValueDecl *VD) { 13152 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 13153 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 13154 /*FullCheck=*/false); 13155 } 13156 13157 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 13158 SourceLocation IdLoc) { 13159 if (!D || D->isInvalidDecl()) 13160 return; 13161 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 13162 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 13163 if (auto *VD = dyn_cast<VarDecl>(D)) { 13164 // Only global variables can be marked as declare target. 13165 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 13166 !VD->isStaticDataMember()) 13167 return; 13168 // 2.10.6: threadprivate variable cannot appear in a declare target 13169 // directive. 13170 if (DSAStack->isThreadPrivate(VD)) { 13171 Diag(SL, diag::err_omp_threadprivate_in_target); 13172 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 13173 return; 13174 } 13175 } 13176 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 13177 D = FTD->getTemplatedDecl(); 13178 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 13179 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 13180 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 13181 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 13182 assert(IdLoc.isValid() && "Source location is expected"); 13183 Diag(IdLoc, diag::err_omp_function_in_link_clause); 13184 Diag(FD->getLocation(), diag::note_defined_here) << FD; 13185 return; 13186 } 13187 } 13188 if (auto *VD = dyn_cast<ValueDecl>(D)) { 13189 // Problem if any with var declared with incomplete type will be reported 13190 // as normal, so no need to check it here. 13191 if ((E || !VD->getType()->isIncompleteType()) && 13192 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 13193 return; 13194 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 13195 // Checking declaration inside declare target region. 13196 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 13197 isa<FunctionTemplateDecl>(D)) { 13198 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 13199 Context, OMPDeclareTargetDeclAttr::MT_To); 13200 D->addAttr(A); 13201 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13202 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 13203 } 13204 return; 13205 } 13206 } 13207 if (!E) 13208 return; 13209 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 13210 } 13211 13212 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 13213 SourceLocation StartLoc, 13214 SourceLocation LParenLoc, 13215 SourceLocation EndLoc) { 13216 MappableVarListInfo MVLI(VarList); 13217 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 13218 if (MVLI.ProcessedVarList.empty()) 13219 return nullptr; 13220 13221 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13222 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13223 MVLI.VarComponents); 13224 } 13225 13226 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 13227 SourceLocation StartLoc, 13228 SourceLocation LParenLoc, 13229 SourceLocation EndLoc) { 13230 MappableVarListInfo MVLI(VarList); 13231 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 13232 if (MVLI.ProcessedVarList.empty()) 13233 return nullptr; 13234 13235 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13236 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13237 MVLI.VarComponents); 13238 } 13239 13240 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 13241 SourceLocation StartLoc, 13242 SourceLocation LParenLoc, 13243 SourceLocation EndLoc) { 13244 MappableVarListInfo MVLI(VarList); 13245 SmallVector<Expr *, 8> PrivateCopies; 13246 SmallVector<Expr *, 8> Inits; 13247 13248 for (Expr *RefExpr : VarList) { 13249 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 13250 SourceLocation ELoc; 13251 SourceRange ERange; 13252 Expr *SimpleRefExpr = RefExpr; 13253 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13254 if (Res.second) { 13255 // It will be analyzed later. 13256 MVLI.ProcessedVarList.push_back(RefExpr); 13257 PrivateCopies.push_back(nullptr); 13258 Inits.push_back(nullptr); 13259 } 13260 ValueDecl *D = Res.first; 13261 if (!D) 13262 continue; 13263 13264 QualType Type = D->getType(); 13265 Type = Type.getNonReferenceType().getUnqualifiedType(); 13266 13267 auto *VD = dyn_cast<VarDecl>(D); 13268 13269 // Item should be a pointer or reference to pointer. 13270 if (!Type->isPointerType()) { 13271 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 13272 << 0 << RefExpr->getSourceRange(); 13273 continue; 13274 } 13275 13276 // Build the private variable and the expression that refers to it. 13277 auto VDPrivate = 13278 buildVarDecl(*this, ELoc, Type, D->getName(), 13279 D->hasAttrs() ? &D->getAttrs() : nullptr, 13280 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13281 if (VDPrivate->isInvalidDecl()) 13282 continue; 13283 13284 CurContext->addDecl(VDPrivate); 13285 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13286 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13287 13288 // Add temporary variable to initialize the private copy of the pointer. 13289 VarDecl *VDInit = 13290 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 13291 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 13292 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 13293 AddInitializerToDecl(VDPrivate, 13294 DefaultLvalueConversion(VDInitRefExpr).get(), 13295 /*DirectInit=*/false); 13296 13297 // If required, build a capture to implement the privatization initialized 13298 // with the current list item value. 13299 DeclRefExpr *Ref = nullptr; 13300 if (!VD) 13301 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13302 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 13303 PrivateCopies.push_back(VDPrivateRefExpr); 13304 Inits.push_back(VDInitRefExpr); 13305 13306 // We need to add a data sharing attribute for this variable to make sure it 13307 // is correctly captured. A variable that shows up in a use_device_ptr has 13308 // similar properties of a first private variable. 13309 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13310 13311 // Create a mappable component for the list item. List items in this clause 13312 // only need a component. 13313 MVLI.VarBaseDeclarations.push_back(D); 13314 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13315 MVLI.VarComponents.back().push_back( 13316 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 13317 } 13318 13319 if (MVLI.ProcessedVarList.empty()) 13320 return nullptr; 13321 13322 return OMPUseDevicePtrClause::Create( 13323 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 13324 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 13325 } 13326 13327 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 13328 SourceLocation StartLoc, 13329 SourceLocation LParenLoc, 13330 SourceLocation EndLoc) { 13331 MappableVarListInfo MVLI(VarList); 13332 for (Expr *RefExpr : VarList) { 13333 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 13334 SourceLocation ELoc; 13335 SourceRange ERange; 13336 Expr *SimpleRefExpr = RefExpr; 13337 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13338 if (Res.second) { 13339 // It will be analyzed later. 13340 MVLI.ProcessedVarList.push_back(RefExpr); 13341 } 13342 ValueDecl *D = Res.first; 13343 if (!D) 13344 continue; 13345 13346 QualType Type = D->getType(); 13347 // item should be a pointer or array or reference to pointer or array 13348 if (!Type.getNonReferenceType()->isPointerType() && 13349 !Type.getNonReferenceType()->isArrayType()) { 13350 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 13351 << 0 << RefExpr->getSourceRange(); 13352 continue; 13353 } 13354 13355 // Check if the declaration in the clause does not show up in any data 13356 // sharing attribute. 13357 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13358 if (isOpenMPPrivate(DVar.CKind)) { 13359 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13360 << getOpenMPClauseName(DVar.CKind) 13361 << getOpenMPClauseName(OMPC_is_device_ptr) 13362 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13363 reportOriginalDsa(*this, DSAStack, D, DVar); 13364 continue; 13365 } 13366 13367 const Expr *ConflictExpr; 13368 if (DSAStack->checkMappableExprComponentListsForDecl( 13369 D, /*CurrentRegionOnly=*/true, 13370 [&ConflictExpr]( 13371 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 13372 OpenMPClauseKind) -> bool { 13373 ConflictExpr = R.front().getAssociatedExpression(); 13374 return true; 13375 })) { 13376 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 13377 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 13378 << ConflictExpr->getSourceRange(); 13379 continue; 13380 } 13381 13382 // Store the components in the stack so that they can be used to check 13383 // against other clauses later on. 13384 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 13385 DSAStack->addMappableExpressionComponents( 13386 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 13387 13388 // Record the expression we've just processed. 13389 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 13390 13391 // Create a mappable component for the list item. List items in this clause 13392 // only need a component. We use a null declaration to signal fields in 13393 // 'this'. 13394 assert((isa<DeclRefExpr>(SimpleRefExpr) || 13395 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 13396 "Unexpected device pointer expression!"); 13397 MVLI.VarBaseDeclarations.push_back( 13398 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 13399 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13400 MVLI.VarComponents.back().push_back(MC); 13401 } 13402 13403 if (MVLI.ProcessedVarList.empty()) 13404 return nullptr; 13405 13406 return OMPIsDevicePtrClause::Create( 13407 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 13408 MVLI.VarBaseDeclarations, MVLI.VarComponents); 13409 } 13410