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 /// Vector of previously declared requires directives 181 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 182 183 public: 184 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 185 186 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 187 OpenMPClauseKind getClauseParsingMode() const { 188 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 189 return ClauseKindMode; 190 } 191 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 192 193 bool isForceVarCapturing() const { return ForceCapturing; } 194 void setForceVarCapturing(bool V) { ForceCapturing = V; } 195 196 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 197 Scope *CurScope, SourceLocation Loc) { 198 if (Stack.empty() || 199 Stack.back().second != CurrentNonCapturingFunctionScope) 200 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 201 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 202 Stack.back().first.back().DefaultAttrLoc = Loc; 203 } 204 205 void pop() { 206 assert(!Stack.back().first.empty() && 207 "Data-sharing attributes stack is empty!"); 208 Stack.back().first.pop_back(); 209 } 210 211 /// Start new OpenMP region stack in new non-capturing function. 212 void pushFunction() { 213 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 214 assert(!isa<CapturingScopeInfo>(CurFnScope)); 215 CurrentNonCapturingFunctionScope = CurFnScope; 216 } 217 /// Pop region stack for non-capturing function. 218 void popFunction(const FunctionScopeInfo *OldFSI) { 219 if (!Stack.empty() && Stack.back().second == OldFSI) { 220 assert(Stack.back().first.empty()); 221 Stack.pop_back(); 222 } 223 CurrentNonCapturingFunctionScope = nullptr; 224 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 225 if (!isa<CapturingScopeInfo>(FSI)) { 226 CurrentNonCapturingFunctionScope = FSI; 227 break; 228 } 229 } 230 } 231 232 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 233 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 234 } 235 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 236 getCriticalWithHint(const DeclarationNameInfo &Name) const { 237 auto I = Criticals.find(Name.getAsString()); 238 if (I != Criticals.end()) 239 return I->second; 240 return std::make_pair(nullptr, llvm::APSInt()); 241 } 242 /// If 'aligned' declaration for given variable \a D was not seen yet, 243 /// add it and return NULL; otherwise return previous occurrence's expression 244 /// for diagnostics. 245 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 246 247 /// Register specified variable as loop control variable. 248 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 249 /// Check if the specified variable is a loop control variable for 250 /// current region. 251 /// \return The index of the loop control variable in the list of associated 252 /// for-loops (from outer to inner). 253 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 254 /// Check if the specified variable is a loop control variable for 255 /// parent region. 256 /// \return The index of the loop control variable in the list of associated 257 /// for-loops (from outer to inner). 258 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 259 /// Get the loop control variable for the I-th loop (or nullptr) in 260 /// parent directive. 261 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 262 263 /// Adds explicit data sharing attribute to the specified declaration. 264 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 265 DeclRefExpr *PrivateCopy = nullptr); 266 267 /// Adds additional information for the reduction items with the reduction id 268 /// represented as an operator. 269 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 270 BinaryOperatorKind BOK); 271 /// Adds additional information for the reduction items with the reduction id 272 /// represented as reduction identifier. 273 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 274 const Expr *ReductionRef); 275 /// Returns the location and reduction operation from the innermost parent 276 /// region for the given \p D. 277 const DSAVarData 278 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 279 BinaryOperatorKind &BOK, 280 Expr *&TaskgroupDescriptor) const; 281 /// Returns the location and reduction operation from the innermost parent 282 /// region for the given \p D. 283 const DSAVarData 284 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 285 const Expr *&ReductionRef, 286 Expr *&TaskgroupDescriptor) const; 287 /// Return reduction reference expression for the current taskgroup. 288 Expr *getTaskgroupReductionRef() const { 289 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 290 "taskgroup reference expression requested for non taskgroup " 291 "directive."); 292 return Stack.back().first.back().TaskgroupReductionRef; 293 } 294 /// Checks if the given \p VD declaration is actually a taskgroup reduction 295 /// descriptor variable at the \p Level of OpenMP regions. 296 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 297 return Stack.back().first[Level].TaskgroupReductionRef && 298 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 299 ->getDecl() == VD; 300 } 301 302 /// Returns data sharing attributes from top of the stack for the 303 /// specified declaration. 304 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 305 /// Returns data-sharing attributes for the specified declaration. 306 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 307 /// Checks if the specified variables has data-sharing attributes which 308 /// match specified \a CPred predicate in any directive which matches \a DPred 309 /// predicate. 310 const DSAVarData 311 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 312 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 313 bool FromParent) const; 314 /// Checks if the specified variables has data-sharing attributes which 315 /// match specified \a CPred predicate in any innermost directive which 316 /// matches \a DPred predicate. 317 const DSAVarData 318 hasInnermostDSA(ValueDecl *D, 319 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 320 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 321 bool FromParent) const; 322 /// Checks if the specified variables has explicit data-sharing 323 /// attributes which match specified \a CPred predicate at the specified 324 /// OpenMP region. 325 bool hasExplicitDSA(const ValueDecl *D, 326 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 327 unsigned Level, bool NotLastprivate = false) const; 328 329 /// Returns true if the directive at level \Level matches in the 330 /// specified \a DPred predicate. 331 bool hasExplicitDirective( 332 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 333 unsigned Level) const; 334 335 /// Finds a directive which matches specified \a DPred predicate. 336 bool hasDirective( 337 const llvm::function_ref<bool( 338 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 339 DPred, 340 bool FromParent) const; 341 342 /// Returns currently analyzed directive. 343 OpenMPDirectiveKind getCurrentDirective() const { 344 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 345 } 346 /// Returns directive kind at specified level. 347 OpenMPDirectiveKind getDirective(unsigned Level) const { 348 assert(!isStackEmpty() && "No directive at specified level."); 349 return Stack.back().first[Level].Directive; 350 } 351 /// Returns parent directive. 352 OpenMPDirectiveKind getParentDirective() const { 353 if (isStackEmpty() || Stack.back().first.size() == 1) 354 return OMPD_unknown; 355 return std::next(Stack.back().first.rbegin())->Directive; 356 } 357 358 /// Add requires decl to internal vector 359 void addRequiresDecl(OMPRequiresDecl *RD) { 360 RequiresDecls.push_back(RD); 361 } 362 363 /// Checks for a duplicate clause amongst previously declared requires 364 /// directives 365 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 366 bool IsDuplicate = false; 367 for (OMPClause *CNew : ClauseList) { 368 for (const OMPRequiresDecl *D : RequiresDecls) { 369 for (const OMPClause *CPrev : D->clauselists()) { 370 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 371 SemaRef.Diag(CNew->getBeginLoc(), 372 diag::err_omp_requires_clause_redeclaration) 373 << getOpenMPClauseName(CNew->getClauseKind()); 374 SemaRef.Diag(CPrev->getBeginLoc(), 375 diag::note_omp_requires_previous_clause) 376 << getOpenMPClauseName(CPrev->getClauseKind()); 377 IsDuplicate = true; 378 } 379 } 380 } 381 } 382 return IsDuplicate; 383 } 384 385 /// Set default data sharing attribute to none. 386 void setDefaultDSANone(SourceLocation Loc) { 387 assert(!isStackEmpty()); 388 Stack.back().first.back().DefaultAttr = DSA_none; 389 Stack.back().first.back().DefaultAttrLoc = Loc; 390 } 391 /// Set default data sharing attribute to shared. 392 void setDefaultDSAShared(SourceLocation Loc) { 393 assert(!isStackEmpty()); 394 Stack.back().first.back().DefaultAttr = DSA_shared; 395 Stack.back().first.back().DefaultAttrLoc = Loc; 396 } 397 /// Set default data mapping attribute to 'tofrom:scalar'. 398 void setDefaultDMAToFromScalar(SourceLocation Loc) { 399 assert(!isStackEmpty()); 400 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 401 Stack.back().first.back().DefaultMapAttrLoc = Loc; 402 } 403 404 DefaultDataSharingAttributes getDefaultDSA() const { 405 return isStackEmpty() ? DSA_unspecified 406 : Stack.back().first.back().DefaultAttr; 407 } 408 SourceLocation getDefaultDSALocation() const { 409 return isStackEmpty() ? SourceLocation() 410 : Stack.back().first.back().DefaultAttrLoc; 411 } 412 DefaultMapAttributes getDefaultDMA() const { 413 return isStackEmpty() ? DMA_unspecified 414 : Stack.back().first.back().DefaultMapAttr; 415 } 416 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 417 return Stack.back().first[Level].DefaultMapAttr; 418 } 419 SourceLocation getDefaultDMALocation() const { 420 return isStackEmpty() ? SourceLocation() 421 : Stack.back().first.back().DefaultMapAttrLoc; 422 } 423 424 /// Checks if the specified variable is a threadprivate. 425 bool isThreadPrivate(VarDecl *D) { 426 const DSAVarData DVar = getTopDSA(D, false); 427 return isOpenMPThreadPrivate(DVar.CKind); 428 } 429 430 /// Marks current region as ordered (it has an 'ordered' clause). 431 void setOrderedRegion(bool IsOrdered, const Expr *Param, 432 OMPOrderedClause *Clause) { 433 assert(!isStackEmpty()); 434 if (IsOrdered) 435 Stack.back().first.back().OrderedRegion.emplace(Param, Clause); 436 else 437 Stack.back().first.back().OrderedRegion.reset(); 438 } 439 /// Returns true, if region is ordered (has associated 'ordered' clause), 440 /// false - otherwise. 441 bool isOrderedRegion() const { 442 if (isStackEmpty()) 443 return false; 444 return Stack.back().first.rbegin()->OrderedRegion.hasValue(); 445 } 446 /// Returns optional parameter for the ordered region. 447 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 448 if (isStackEmpty() || 449 !Stack.back().first.rbegin()->OrderedRegion.hasValue()) 450 return std::make_pair(nullptr, nullptr); 451 return Stack.back().first.rbegin()->OrderedRegion.getValue(); 452 } 453 /// Returns true, if parent region is ordered (has associated 454 /// 'ordered' clause), false - otherwise. 455 bool isParentOrderedRegion() const { 456 if (isStackEmpty() || Stack.back().first.size() == 1) 457 return false; 458 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); 459 } 460 /// Returns optional parameter for the ordered region. 461 std::pair<const Expr *, OMPOrderedClause *> 462 getParentOrderedRegionParam() const { 463 if (isStackEmpty() || Stack.back().first.size() == 1 || 464 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) 465 return std::make_pair(nullptr, nullptr); 466 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); 467 } 468 /// Marks current region as nowait (it has a 'nowait' clause). 469 void setNowaitRegion(bool IsNowait = true) { 470 assert(!isStackEmpty()); 471 Stack.back().first.back().NowaitRegion = IsNowait; 472 } 473 /// Returns true, if parent region is nowait (has associated 474 /// 'nowait' clause), false - otherwise. 475 bool isParentNowaitRegion() const { 476 if (isStackEmpty() || Stack.back().first.size() == 1) 477 return false; 478 return std::next(Stack.back().first.rbegin())->NowaitRegion; 479 } 480 /// Marks parent region as cancel region. 481 void setParentCancelRegion(bool Cancel = true) { 482 if (!isStackEmpty() && Stack.back().first.size() > 1) { 483 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 484 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 485 } 486 } 487 /// Return true if current region has inner cancel construct. 488 bool isCancelRegion() const { 489 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 490 } 491 492 /// Set collapse value for the region. 493 void setAssociatedLoops(unsigned Val) { 494 assert(!isStackEmpty()); 495 Stack.back().first.back().AssociatedLoops = Val; 496 } 497 /// Return collapse value for region. 498 unsigned getAssociatedLoops() const { 499 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 500 } 501 502 /// Marks current target region as one with closely nested teams 503 /// region. 504 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 505 if (!isStackEmpty() && Stack.back().first.size() > 1) { 506 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 507 TeamsRegionLoc; 508 } 509 } 510 /// Returns true, if current region has closely nested teams region. 511 bool hasInnerTeamsRegion() const { 512 return getInnerTeamsRegionLoc().isValid(); 513 } 514 /// Returns location of the nested teams region (if any). 515 SourceLocation getInnerTeamsRegionLoc() const { 516 return isStackEmpty() ? SourceLocation() 517 : Stack.back().first.back().InnerTeamsRegionLoc; 518 } 519 520 Scope *getCurScope() const { 521 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 522 } 523 SourceLocation getConstructLoc() const { 524 return isStackEmpty() ? SourceLocation() 525 : Stack.back().first.back().ConstructLoc; 526 } 527 528 /// Do the check specified in \a Check to all component lists and return true 529 /// if any issue is found. 530 bool checkMappableExprComponentListsForDecl( 531 const ValueDecl *VD, bool CurrentRegionOnly, 532 const llvm::function_ref< 533 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 534 OpenMPClauseKind)> 535 Check) const { 536 if (isStackEmpty()) 537 return false; 538 auto SI = Stack.back().first.rbegin(); 539 auto SE = Stack.back().first.rend(); 540 541 if (SI == SE) 542 return false; 543 544 if (CurrentRegionOnly) 545 SE = std::next(SI); 546 else 547 std::advance(SI, 1); 548 549 for (; SI != SE; ++SI) { 550 auto MI = SI->MappedExprComponents.find(VD); 551 if (MI != SI->MappedExprComponents.end()) 552 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 553 MI->second.Components) 554 if (Check(L, MI->second.Kind)) 555 return true; 556 } 557 return false; 558 } 559 560 /// Do the check specified in \a Check to all component lists at a given level 561 /// and return true if any issue is found. 562 bool checkMappableExprComponentListsForDeclAtLevel( 563 const ValueDecl *VD, unsigned Level, 564 const llvm::function_ref< 565 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 566 OpenMPClauseKind)> 567 Check) const { 568 if (isStackEmpty()) 569 return false; 570 571 auto StartI = Stack.back().first.begin(); 572 auto EndI = Stack.back().first.end(); 573 if (std::distance(StartI, EndI) <= (int)Level) 574 return false; 575 std::advance(StartI, Level); 576 577 auto MI = StartI->MappedExprComponents.find(VD); 578 if (MI != StartI->MappedExprComponents.end()) 579 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 580 MI->second.Components) 581 if (Check(L, MI->second.Kind)) 582 return true; 583 return false; 584 } 585 586 /// Create a new mappable expression component list associated with a given 587 /// declaration and initialize it with the provided list of components. 588 void addMappableExpressionComponents( 589 const ValueDecl *VD, 590 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 591 OpenMPClauseKind WhereFoundClauseKind) { 592 assert(!isStackEmpty() && 593 "Not expecting to retrieve components from a empty stack!"); 594 MappedExprComponentTy &MEC = 595 Stack.back().first.back().MappedExprComponents[VD]; 596 // Create new entry and append the new components there. 597 MEC.Components.resize(MEC.Components.size() + 1); 598 MEC.Components.back().append(Components.begin(), Components.end()); 599 MEC.Kind = WhereFoundClauseKind; 600 } 601 602 unsigned getNestingLevel() const { 603 assert(!isStackEmpty()); 604 return Stack.back().first.size() - 1; 605 } 606 void addDoacrossDependClause(OMPDependClause *C, 607 const OperatorOffsetTy &OpsOffs) { 608 assert(!isStackEmpty() && Stack.back().first.size() > 1); 609 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 610 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 611 StackElem.DoacrossDepends.try_emplace(C, OpsOffs); 612 } 613 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 614 getDoacrossDependClauses() const { 615 assert(!isStackEmpty()); 616 const SharingMapTy &StackElem = Stack.back().first.back(); 617 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 618 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 619 return llvm::make_range(Ref.begin(), Ref.end()); 620 } 621 return llvm::make_range(StackElem.DoacrossDepends.end(), 622 StackElem.DoacrossDepends.end()); 623 } 624 }; 625 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 626 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 627 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 628 } 629 630 } // namespace 631 632 static const Expr *getExprAsWritten(const Expr *E) { 633 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 634 E = ExprTemp->getSubExpr(); 635 636 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 637 E = MTE->GetTemporaryExpr(); 638 639 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 640 E = Binder->getSubExpr(); 641 642 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 643 E = ICE->getSubExprAsWritten(); 644 return E->IgnoreParens(); 645 } 646 647 static Expr *getExprAsWritten(Expr *E) { 648 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 649 } 650 651 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 652 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 653 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 654 D = ME->getMemberDecl(); 655 const auto *VD = dyn_cast<VarDecl>(D); 656 const auto *FD = dyn_cast<FieldDecl>(D); 657 if (VD != nullptr) { 658 VD = VD->getCanonicalDecl(); 659 D = VD; 660 } else { 661 assert(FD); 662 FD = FD->getCanonicalDecl(); 663 D = FD; 664 } 665 return D; 666 } 667 668 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 669 return const_cast<ValueDecl *>( 670 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 671 } 672 673 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 674 ValueDecl *D) const { 675 D = getCanonicalDecl(D); 676 auto *VD = dyn_cast<VarDecl>(D); 677 const auto *FD = dyn_cast<FieldDecl>(D); 678 DSAVarData DVar; 679 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 680 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 681 // in a region but not in construct] 682 // File-scope or namespace-scope variables referenced in called routines 683 // in the region are shared unless they appear in a threadprivate 684 // directive. 685 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 686 DVar.CKind = OMPC_shared; 687 688 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 689 // in a region but not in construct] 690 // Variables with static storage duration that are declared in called 691 // routines in the region are shared. 692 if (VD && VD->hasGlobalStorage()) 693 DVar.CKind = OMPC_shared; 694 695 // Non-static data members are shared by default. 696 if (FD) 697 DVar.CKind = OMPC_shared; 698 699 return DVar; 700 } 701 702 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 703 // in a Construct, C/C++, predetermined, p.1] 704 // Variables with automatic storage duration that are declared in a scope 705 // inside the construct are private. 706 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 707 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 708 DVar.CKind = OMPC_private; 709 return DVar; 710 } 711 712 DVar.DKind = Iter->Directive; 713 // Explicitly specified attributes and local variables with predetermined 714 // attributes. 715 if (Iter->SharingMap.count(D)) { 716 const DSAInfo &Data = Iter->SharingMap.lookup(D); 717 DVar.RefExpr = Data.RefExpr.getPointer(); 718 DVar.PrivateCopy = Data.PrivateCopy; 719 DVar.CKind = Data.Attributes; 720 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 721 return DVar; 722 } 723 724 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 725 // in a Construct, C/C++, implicitly determined, p.1] 726 // In a parallel or task construct, the data-sharing attributes of these 727 // variables are determined by the default clause, if present. 728 switch (Iter->DefaultAttr) { 729 case DSA_shared: 730 DVar.CKind = OMPC_shared; 731 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 732 return DVar; 733 case DSA_none: 734 return DVar; 735 case DSA_unspecified: 736 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 737 // in a Construct, implicitly determined, p.2] 738 // In a parallel construct, if no default clause is present, these 739 // variables are shared. 740 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 741 if (isOpenMPParallelDirective(DVar.DKind) || 742 isOpenMPTeamsDirective(DVar.DKind)) { 743 DVar.CKind = OMPC_shared; 744 return DVar; 745 } 746 747 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 748 // in a Construct, implicitly determined, p.4] 749 // In a task construct, if no default clause is present, a variable that in 750 // the enclosing context is determined to be shared by all implicit tasks 751 // bound to the current team is shared. 752 if (isOpenMPTaskingDirective(DVar.DKind)) { 753 DSAVarData DVarTemp; 754 iterator I = Iter, E = Stack.back().first.rend(); 755 do { 756 ++I; 757 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 758 // Referenced in a Construct, implicitly determined, p.6] 759 // In a task construct, if no default clause is present, a variable 760 // whose data-sharing attribute is not determined by the rules above is 761 // firstprivate. 762 DVarTemp = getDSA(I, D); 763 if (DVarTemp.CKind != OMPC_shared) { 764 DVar.RefExpr = nullptr; 765 DVar.CKind = OMPC_firstprivate; 766 return DVar; 767 } 768 } while (I != E && !isParallelOrTaskRegion(I->Directive)); 769 DVar.CKind = 770 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 771 return DVar; 772 } 773 } 774 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 775 // in a Construct, implicitly determined, p.3] 776 // For constructs other than task, if no default clause is present, these 777 // variables inherit their data-sharing attributes from the enclosing 778 // context. 779 return getDSA(++Iter, D); 780 } 781 782 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 783 const Expr *NewDE) { 784 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 785 D = getCanonicalDecl(D); 786 SharingMapTy &StackElem = Stack.back().first.back(); 787 auto It = StackElem.AlignedMap.find(D); 788 if (It == StackElem.AlignedMap.end()) { 789 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 790 StackElem.AlignedMap[D] = NewDE; 791 return nullptr; 792 } 793 assert(It->second && "Unexpected nullptr expr in the aligned map"); 794 return It->second; 795 } 796 797 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 798 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 799 D = getCanonicalDecl(D); 800 SharingMapTy &StackElem = Stack.back().first.back(); 801 StackElem.LCVMap.try_emplace( 802 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 803 } 804 805 const DSAStackTy::LCDeclInfo 806 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 807 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 808 D = getCanonicalDecl(D); 809 const SharingMapTy &StackElem = Stack.back().first.back(); 810 auto It = StackElem.LCVMap.find(D); 811 if (It != StackElem.LCVMap.end()) 812 return It->second; 813 return {0, nullptr}; 814 } 815 816 const DSAStackTy::LCDeclInfo 817 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 818 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 819 "Data-sharing attributes stack is empty"); 820 D = getCanonicalDecl(D); 821 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 822 auto It = StackElem.LCVMap.find(D); 823 if (It != StackElem.LCVMap.end()) 824 return It->second; 825 return {0, nullptr}; 826 } 827 828 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 829 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 830 "Data-sharing attributes stack is empty"); 831 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 832 if (StackElem.LCVMap.size() < I) 833 return nullptr; 834 for (const auto &Pair : StackElem.LCVMap) 835 if (Pair.second.first == I) 836 return Pair.first; 837 return nullptr; 838 } 839 840 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 841 DeclRefExpr *PrivateCopy) { 842 D = getCanonicalDecl(D); 843 if (A == OMPC_threadprivate) { 844 DSAInfo &Data = Threadprivates[D]; 845 Data.Attributes = A; 846 Data.RefExpr.setPointer(E); 847 Data.PrivateCopy = nullptr; 848 } else { 849 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 850 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 851 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 852 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 853 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 854 (isLoopControlVariable(D).first && A == OMPC_private)); 855 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 856 Data.RefExpr.setInt(/*IntVal=*/true); 857 return; 858 } 859 const bool IsLastprivate = 860 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 861 Data.Attributes = A; 862 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 863 Data.PrivateCopy = PrivateCopy; 864 if (PrivateCopy) { 865 DSAInfo &Data = 866 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 867 Data.Attributes = A; 868 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 869 Data.PrivateCopy = nullptr; 870 } 871 } 872 } 873 874 /// Build a variable declaration for OpenMP loop iteration variable. 875 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 876 StringRef Name, const AttrVec *Attrs = nullptr, 877 DeclRefExpr *OrigRef = nullptr) { 878 DeclContext *DC = SemaRef.CurContext; 879 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 880 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 881 auto *Decl = 882 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 883 if (Attrs) { 884 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 885 I != E; ++I) 886 Decl->addAttr(*I); 887 } 888 Decl->setImplicit(); 889 if (OrigRef) { 890 Decl->addAttr( 891 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 892 } 893 return Decl; 894 } 895 896 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 897 SourceLocation Loc, 898 bool RefersToCapture = false) { 899 D->setReferenced(); 900 D->markUsed(S.Context); 901 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 902 SourceLocation(), D, RefersToCapture, Loc, Ty, 903 VK_LValue); 904 } 905 906 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 907 BinaryOperatorKind BOK) { 908 D = getCanonicalDecl(D); 909 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 910 assert( 911 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 912 "Additional reduction info may be specified only for reduction items."); 913 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 914 assert(ReductionData.ReductionRange.isInvalid() && 915 Stack.back().first.back().Directive == OMPD_taskgroup && 916 "Additional reduction info may be specified only once for reduction " 917 "items."); 918 ReductionData.set(BOK, SR); 919 Expr *&TaskgroupReductionRef = 920 Stack.back().first.back().TaskgroupReductionRef; 921 if (!TaskgroupReductionRef) { 922 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 923 SemaRef.Context.VoidPtrTy, ".task_red."); 924 TaskgroupReductionRef = 925 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 926 } 927 } 928 929 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 930 const Expr *ReductionRef) { 931 D = getCanonicalDecl(D); 932 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 933 assert( 934 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 935 "Additional reduction info may be specified only for reduction items."); 936 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 937 assert(ReductionData.ReductionRange.isInvalid() && 938 Stack.back().first.back().Directive == OMPD_taskgroup && 939 "Additional reduction info may be specified only once for reduction " 940 "items."); 941 ReductionData.set(ReductionRef, SR); 942 Expr *&TaskgroupReductionRef = 943 Stack.back().first.back().TaskgroupReductionRef; 944 if (!TaskgroupReductionRef) { 945 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 946 SemaRef.Context.VoidPtrTy, ".task_red."); 947 TaskgroupReductionRef = 948 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 949 } 950 } 951 952 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 953 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 954 Expr *&TaskgroupDescriptor) const { 955 D = getCanonicalDecl(D); 956 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 957 if (Stack.back().first.empty()) 958 return DSAVarData(); 959 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 960 E = Stack.back().first.rend(); 961 I != E; std::advance(I, 1)) { 962 const DSAInfo &Data = I->SharingMap.lookup(D); 963 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 964 continue; 965 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 966 if (!ReductionData.ReductionOp || 967 ReductionData.ReductionOp.is<const Expr *>()) 968 return DSAVarData(); 969 SR = ReductionData.ReductionRange; 970 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 971 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 972 "expression for the descriptor is not " 973 "set."); 974 TaskgroupDescriptor = I->TaskgroupReductionRef; 975 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 976 Data.PrivateCopy, I->DefaultAttrLoc); 977 } 978 return DSAVarData(); 979 } 980 981 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 982 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 983 Expr *&TaskgroupDescriptor) const { 984 D = getCanonicalDecl(D); 985 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 986 if (Stack.back().first.empty()) 987 return DSAVarData(); 988 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 989 E = Stack.back().first.rend(); 990 I != E; std::advance(I, 1)) { 991 const DSAInfo &Data = I->SharingMap.lookup(D); 992 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 993 continue; 994 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 995 if (!ReductionData.ReductionOp || 996 !ReductionData.ReductionOp.is<const Expr *>()) 997 return DSAVarData(); 998 SR = ReductionData.ReductionRange; 999 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1000 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1001 "expression for the descriptor is not " 1002 "set."); 1003 TaskgroupDescriptor = I->TaskgroupReductionRef; 1004 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1005 Data.PrivateCopy, I->DefaultAttrLoc); 1006 } 1007 return DSAVarData(); 1008 } 1009 1010 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 1011 D = D->getCanonicalDecl(); 1012 if (!isStackEmpty()) { 1013 iterator I = Iter, E = Stack.back().first.rend(); 1014 Scope *TopScope = nullptr; 1015 while (I != E && !isParallelOrTaskRegion(I->Directive) && 1016 !isOpenMPTargetExecutionDirective(I->Directive)) 1017 ++I; 1018 if (I == E) 1019 return false; 1020 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1021 Scope *CurScope = getCurScope(); 1022 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 1023 CurScope = CurScope->getParent(); 1024 return CurScope != TopScope; 1025 } 1026 return false; 1027 } 1028 1029 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1030 bool FromParent) { 1031 D = getCanonicalDecl(D); 1032 DSAVarData DVar; 1033 1034 auto *VD = dyn_cast<VarDecl>(D); 1035 auto TI = Threadprivates.find(D); 1036 if (TI != Threadprivates.end()) { 1037 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1038 DVar.CKind = OMPC_threadprivate; 1039 return DVar; 1040 } 1041 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1042 DVar.RefExpr = buildDeclRefExpr( 1043 SemaRef, VD, D->getType().getNonReferenceType(), 1044 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1045 DVar.CKind = OMPC_threadprivate; 1046 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1047 return DVar; 1048 } 1049 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1050 // in a Construct, C/C++, predetermined, p.1] 1051 // Variables appearing in threadprivate directives are threadprivate. 1052 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1053 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1054 SemaRef.getLangOpts().OpenMPUseTLS && 1055 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1056 (VD && VD->getStorageClass() == SC_Register && 1057 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1058 DVar.RefExpr = buildDeclRefExpr( 1059 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1060 DVar.CKind = OMPC_threadprivate; 1061 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1062 return DVar; 1063 } 1064 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1065 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1066 !isLoopControlVariable(D).first) { 1067 iterator IterTarget = 1068 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1069 [](const SharingMapTy &Data) { 1070 return isOpenMPTargetExecutionDirective(Data.Directive); 1071 }); 1072 if (IterTarget != Stack.back().first.rend()) { 1073 iterator ParentIterTarget = std::next(IterTarget, 1); 1074 for (iterator Iter = Stack.back().first.rbegin(); 1075 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1076 if (isOpenMPLocal(VD, Iter)) { 1077 DVar.RefExpr = 1078 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1079 D->getLocation()); 1080 DVar.CKind = OMPC_threadprivate; 1081 return DVar; 1082 } 1083 } 1084 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1085 auto DSAIter = IterTarget->SharingMap.find(D); 1086 if (DSAIter != IterTarget->SharingMap.end() && 1087 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1088 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1089 DVar.CKind = OMPC_threadprivate; 1090 return DVar; 1091 } 1092 iterator End = Stack.back().first.rend(); 1093 if (!SemaRef.isOpenMPCapturedByRef( 1094 D, std::distance(ParentIterTarget, End))) { 1095 DVar.RefExpr = 1096 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1097 IterTarget->ConstructLoc); 1098 DVar.CKind = OMPC_threadprivate; 1099 return DVar; 1100 } 1101 } 1102 } 1103 } 1104 1105 if (isStackEmpty()) 1106 // Not in OpenMP execution region and top scope was already checked. 1107 return DVar; 1108 1109 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1110 // in a Construct, C/C++, predetermined, p.4] 1111 // Static data members are shared. 1112 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1113 // in a Construct, C/C++, predetermined, p.7] 1114 // Variables with static storage duration that are declared in a scope 1115 // inside the construct are shared. 1116 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1117 if (VD && VD->isStaticDataMember()) { 1118 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1119 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1120 return DVar; 1121 1122 DVar.CKind = OMPC_shared; 1123 return DVar; 1124 } 1125 1126 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 1127 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 1128 Type = SemaRef.getASTContext().getBaseElementType(Type); 1129 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1130 // in a Construct, C/C++, predetermined, p.6] 1131 // Variables with const qualified type having no mutable member are 1132 // shared. 1133 const CXXRecordDecl *RD = 1134 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 1135 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1136 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1137 RD = CTD->getTemplatedDecl(); 1138 if (IsConstant && 1139 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 1140 RD->hasMutableFields())) { 1141 // Variables with const-qualified type having no mutable member may be 1142 // listed in a firstprivate clause, even if they are static data members. 1143 DSAVarData DVarTemp = 1144 hasDSA(D, [](OpenMPClauseKind C) { return C == OMPC_firstprivate; }, 1145 MatchesAlways, FromParent); 1146 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 1147 return DVarTemp; 1148 1149 DVar.CKind = OMPC_shared; 1150 return DVar; 1151 } 1152 1153 // Explicitly specified attributes and local variables with predetermined 1154 // attributes. 1155 iterator I = Stack.back().first.rbegin(); 1156 iterator EndI = Stack.back().first.rend(); 1157 if (FromParent && I != EndI) 1158 std::advance(I, 1); 1159 auto It = I->SharingMap.find(D); 1160 if (It != I->SharingMap.end()) { 1161 const DSAInfo &Data = It->getSecond(); 1162 DVar.RefExpr = Data.RefExpr.getPointer(); 1163 DVar.PrivateCopy = Data.PrivateCopy; 1164 DVar.CKind = Data.Attributes; 1165 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1166 DVar.DKind = I->Directive; 1167 } 1168 1169 return DVar; 1170 } 1171 1172 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1173 bool FromParent) const { 1174 if (isStackEmpty()) { 1175 iterator I; 1176 return getDSA(I, D); 1177 } 1178 D = getCanonicalDecl(D); 1179 iterator StartI = Stack.back().first.rbegin(); 1180 iterator EndI = Stack.back().first.rend(); 1181 if (FromParent && StartI != EndI) 1182 std::advance(StartI, 1); 1183 return getDSA(StartI, D); 1184 } 1185 1186 const DSAStackTy::DSAVarData 1187 DSAStackTy::hasDSA(ValueDecl *D, 1188 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1189 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1190 bool FromParent) const { 1191 if (isStackEmpty()) 1192 return {}; 1193 D = getCanonicalDecl(D); 1194 iterator I = Stack.back().first.rbegin(); 1195 iterator EndI = Stack.back().first.rend(); 1196 if (FromParent && I != EndI) 1197 std::advance(I, 1); 1198 for (; I != EndI; std::advance(I, 1)) { 1199 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 1200 continue; 1201 iterator NewI = I; 1202 DSAVarData DVar = getDSA(NewI, D); 1203 if (I == NewI && CPred(DVar.CKind)) 1204 return DVar; 1205 } 1206 return {}; 1207 } 1208 1209 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1210 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1211 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1212 bool FromParent) const { 1213 if (isStackEmpty()) 1214 return {}; 1215 D = getCanonicalDecl(D); 1216 iterator StartI = Stack.back().first.rbegin(); 1217 iterator EndI = Stack.back().first.rend(); 1218 if (FromParent && StartI != EndI) 1219 std::advance(StartI, 1); 1220 if (StartI == EndI || !DPred(StartI->Directive)) 1221 return {}; 1222 iterator NewI = StartI; 1223 DSAVarData DVar = getDSA(NewI, D); 1224 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1225 } 1226 1227 bool DSAStackTy::hasExplicitDSA( 1228 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1229 unsigned Level, bool NotLastprivate) const { 1230 if (isStackEmpty()) 1231 return false; 1232 D = getCanonicalDecl(D); 1233 auto StartI = Stack.back().first.begin(); 1234 auto EndI = Stack.back().first.end(); 1235 if (std::distance(StartI, EndI) <= (int)Level) 1236 return false; 1237 std::advance(StartI, Level); 1238 auto I = StartI->SharingMap.find(D); 1239 return (I != StartI->SharingMap.end()) && 1240 I->getSecond().RefExpr.getPointer() && 1241 CPred(I->getSecond().Attributes) && 1242 (!NotLastprivate || !I->getSecond().RefExpr.getInt()); 1243 } 1244 1245 bool DSAStackTy::hasExplicitDirective( 1246 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1247 unsigned Level) const { 1248 if (isStackEmpty()) 1249 return false; 1250 auto StartI = Stack.back().first.begin(); 1251 auto EndI = Stack.back().first.end(); 1252 if (std::distance(StartI, EndI) <= (int)Level) 1253 return false; 1254 std::advance(StartI, Level); 1255 return DPred(StartI->Directive); 1256 } 1257 1258 bool DSAStackTy::hasDirective( 1259 const llvm::function_ref<bool(OpenMPDirectiveKind, 1260 const DeclarationNameInfo &, SourceLocation)> 1261 DPred, 1262 bool FromParent) const { 1263 // We look only in the enclosing region. 1264 if (isStackEmpty()) 1265 return false; 1266 auto StartI = std::next(Stack.back().first.rbegin()); 1267 auto EndI = Stack.back().first.rend(); 1268 if (FromParent && StartI != EndI) 1269 StartI = std::next(StartI); 1270 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1271 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1272 return true; 1273 } 1274 return false; 1275 } 1276 1277 void Sema::InitDataSharingAttributesStack() { 1278 VarDataSharingAttributesStack = new DSAStackTy(*this); 1279 } 1280 1281 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1282 1283 void Sema::pushOpenMPFunctionRegion() { 1284 DSAStack->pushFunction(); 1285 } 1286 1287 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1288 DSAStack->popFunction(OldFSI); 1289 } 1290 1291 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1292 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1293 1294 ASTContext &Ctx = getASTContext(); 1295 bool IsByRef = true; 1296 1297 // Find the directive that is associated with the provided scope. 1298 D = cast<ValueDecl>(D->getCanonicalDecl()); 1299 QualType Ty = D->getType(); 1300 1301 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1302 // This table summarizes how a given variable should be passed to the device 1303 // given its type and the clauses where it appears. This table is based on 1304 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1305 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1306 // 1307 // ========================================================================= 1308 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1309 // | |(tofrom:scalar)| | pvt | | | | 1310 // ========================================================================= 1311 // | scl | | | | - | | bycopy| 1312 // | scl | | - | x | - | - | bycopy| 1313 // | scl | | x | - | - | - | null | 1314 // | scl | x | | | - | | byref | 1315 // | scl | x | - | x | - | - | bycopy| 1316 // | scl | x | x | - | - | - | null | 1317 // | scl | | - | - | - | x | byref | 1318 // | scl | x | - | - | - | x | byref | 1319 // 1320 // | agg | n.a. | | | - | | byref | 1321 // | agg | n.a. | - | x | - | - | byref | 1322 // | agg | n.a. | x | - | - | - | null | 1323 // | agg | n.a. | - | - | - | x | byref | 1324 // | agg | n.a. | - | - | - | x[] | byref | 1325 // 1326 // | ptr | n.a. | | | - | | bycopy| 1327 // | ptr | n.a. | - | x | - | - | bycopy| 1328 // | ptr | n.a. | x | - | - | - | null | 1329 // | ptr | n.a. | - | - | - | x | byref | 1330 // | ptr | n.a. | - | - | - | x[] | bycopy| 1331 // | ptr | n.a. | - | - | x | | bycopy| 1332 // | ptr | n.a. | - | - | x | x | bycopy| 1333 // | ptr | n.a. | - | - | x | x[] | bycopy| 1334 // ========================================================================= 1335 // Legend: 1336 // scl - scalar 1337 // ptr - pointer 1338 // agg - aggregate 1339 // x - applies 1340 // - - invalid in this combination 1341 // [] - mapped with an array section 1342 // byref - should be mapped by reference 1343 // byval - should be mapped by value 1344 // null - initialize a local variable to null on the device 1345 // 1346 // Observations: 1347 // - All scalar declarations that show up in a map clause have to be passed 1348 // by reference, because they may have been mapped in the enclosing data 1349 // environment. 1350 // - If the scalar value does not fit the size of uintptr, it has to be 1351 // passed by reference, regardless the result in the table above. 1352 // - For pointers mapped by value that have either an implicit map or an 1353 // array section, the runtime library may pass the NULL value to the 1354 // device instead of the value passed to it by the compiler. 1355 1356 if (Ty->isReferenceType()) 1357 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1358 1359 // Locate map clauses and see if the variable being captured is referred to 1360 // in any of those clauses. Here we only care about variables, not fields, 1361 // because fields are part of aggregates. 1362 bool IsVariableUsedInMapClause = false; 1363 bool IsVariableAssociatedWithSection = false; 1364 1365 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1366 D, Level, 1367 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1368 OMPClauseMappableExprCommon::MappableExprComponentListRef 1369 MapExprComponents, 1370 OpenMPClauseKind WhereFoundClauseKind) { 1371 // Only the map clause information influences how a variable is 1372 // captured. E.g. is_device_ptr does not require changing the default 1373 // behavior. 1374 if (WhereFoundClauseKind != OMPC_map) 1375 return false; 1376 1377 auto EI = MapExprComponents.rbegin(); 1378 auto EE = MapExprComponents.rend(); 1379 1380 assert(EI != EE && "Invalid map expression!"); 1381 1382 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1383 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1384 1385 ++EI; 1386 if (EI == EE) 1387 return false; 1388 1389 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1390 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1391 isa<MemberExpr>(EI->getAssociatedExpression())) { 1392 IsVariableAssociatedWithSection = true; 1393 // There is nothing more we need to know about this variable. 1394 return true; 1395 } 1396 1397 // Keep looking for more map info. 1398 return false; 1399 }); 1400 1401 if (IsVariableUsedInMapClause) { 1402 // If variable is identified in a map clause it is always captured by 1403 // reference except if it is a pointer that is dereferenced somehow. 1404 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1405 } else { 1406 // By default, all the data that has a scalar type is mapped by copy 1407 // (except for reduction variables). 1408 IsByRef = 1409 !Ty->isScalarType() || 1410 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1411 DSAStack->hasExplicitDSA( 1412 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1413 } 1414 } 1415 1416 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1417 IsByRef = 1418 !DSAStack->hasExplicitDSA( 1419 D, 1420 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1421 Level, /*NotLastprivate=*/true) && 1422 // If the variable is artificial and must be captured by value - try to 1423 // capture by value. 1424 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1425 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1426 } 1427 1428 // When passing data by copy, we need to make sure it fits the uintptr size 1429 // and alignment, because the runtime library only deals with uintptr types. 1430 // If it does not fit the uintptr size, we need to pass the data by reference 1431 // instead. 1432 if (!IsByRef && 1433 (Ctx.getTypeSizeInChars(Ty) > 1434 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1435 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1436 IsByRef = true; 1437 } 1438 1439 return IsByRef; 1440 } 1441 1442 unsigned Sema::getOpenMPNestingLevel() const { 1443 assert(getLangOpts().OpenMP); 1444 return DSAStack->getNestingLevel(); 1445 } 1446 1447 bool Sema::isInOpenMPTargetExecutionDirective() const { 1448 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1449 !DSAStack->isClauseParsingMode()) || 1450 DSAStack->hasDirective( 1451 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1452 SourceLocation) -> bool { 1453 return isOpenMPTargetExecutionDirective(K); 1454 }, 1455 false); 1456 } 1457 1458 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { 1459 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1460 D = getCanonicalDecl(D); 1461 1462 // If we are attempting to capture a global variable in a directive with 1463 // 'target' we return true so that this global is also mapped to the device. 1464 // 1465 auto *VD = dyn_cast<VarDecl>(D); 1466 if (VD && !VD->hasLocalStorage()) { 1467 if (isInOpenMPDeclareTargetContext() && 1468 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1469 // Try to mark variable as declare target if it is used in capturing 1470 // regions. 1471 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1472 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1473 return nullptr; 1474 } else if (isInOpenMPTargetExecutionDirective()) { 1475 // If the declaration is enclosed in a 'declare target' directive, 1476 // then it should not be captured. 1477 // 1478 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1479 return nullptr; 1480 return VD; 1481 } 1482 } 1483 1484 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1485 (!DSAStack->isClauseParsingMode() || 1486 DSAStack->getParentDirective() != OMPD_unknown)) { 1487 auto &&Info = DSAStack->isLoopControlVariable(D); 1488 if (Info.first || 1489 (VD && VD->hasLocalStorage() && 1490 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1491 (VD && DSAStack->isForceVarCapturing())) 1492 return VD ? VD : Info.second; 1493 DSAStackTy::DSAVarData DVarPrivate = 1494 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1495 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1496 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1497 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1498 [](OpenMPDirectiveKind) { return true; }, 1499 DSAStack->isClauseParsingMode()); 1500 if (DVarPrivate.CKind != OMPC_unknown) 1501 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1502 } 1503 return nullptr; 1504 } 1505 1506 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1507 unsigned Level) const { 1508 SmallVector<OpenMPDirectiveKind, 4> Regions; 1509 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1510 FunctionScopesIndex -= Regions.size(); 1511 } 1512 1513 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1514 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1515 return DSAStack->hasExplicitDSA( 1516 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1517 (DSAStack->isClauseParsingMode() && 1518 DSAStack->getClauseParsingMode() == OMPC_private) || 1519 // Consider taskgroup reduction descriptor variable a private to avoid 1520 // possible capture in the region. 1521 (DSAStack->hasExplicitDirective( 1522 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1523 Level) && 1524 DSAStack->isTaskgroupReductionRef(D, Level)); 1525 } 1526 1527 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1528 unsigned Level) { 1529 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1530 D = getCanonicalDecl(D); 1531 OpenMPClauseKind OMPC = OMPC_unknown; 1532 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1533 const unsigned NewLevel = I - 1; 1534 if (DSAStack->hasExplicitDSA(D, 1535 [&OMPC](const OpenMPClauseKind K) { 1536 if (isOpenMPPrivate(K)) { 1537 OMPC = K; 1538 return true; 1539 } 1540 return false; 1541 }, 1542 NewLevel)) 1543 break; 1544 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1545 D, NewLevel, 1546 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1547 OpenMPClauseKind) { return true; })) { 1548 OMPC = OMPC_map; 1549 break; 1550 } 1551 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1552 NewLevel)) { 1553 OMPC = OMPC_map; 1554 if (D->getType()->isScalarType() && 1555 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1556 DefaultMapAttributes::DMA_tofrom_scalar) 1557 OMPC = OMPC_firstprivate; 1558 break; 1559 } 1560 } 1561 if (OMPC != OMPC_unknown) 1562 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1563 } 1564 1565 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1566 unsigned Level) const { 1567 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1568 // Return true if the current level is no longer enclosed in a target region. 1569 1570 const auto *VD = dyn_cast<VarDecl>(D); 1571 return VD && !VD->hasLocalStorage() && 1572 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1573 Level); 1574 } 1575 1576 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1577 1578 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1579 const DeclarationNameInfo &DirName, 1580 Scope *CurScope, SourceLocation Loc) { 1581 DSAStack->push(DKind, DirName, CurScope, Loc); 1582 PushExpressionEvaluationContext( 1583 ExpressionEvaluationContext::PotentiallyEvaluated); 1584 } 1585 1586 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1587 DSAStack->setClauseParsingMode(K); 1588 } 1589 1590 void Sema::EndOpenMPClause() { 1591 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1592 } 1593 1594 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1595 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1596 // A variable of class type (or array thereof) that appears in a lastprivate 1597 // clause requires an accessible, unambiguous default constructor for the 1598 // class type, unless the list item is also specified in a firstprivate 1599 // clause. 1600 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1601 for (OMPClause *C : D->clauses()) { 1602 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1603 SmallVector<Expr *, 8> PrivateCopies; 1604 for (Expr *DE : Clause->varlists()) { 1605 if (DE->isValueDependent() || DE->isTypeDependent()) { 1606 PrivateCopies.push_back(nullptr); 1607 continue; 1608 } 1609 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1610 auto *VD = cast<VarDecl>(DRE->getDecl()); 1611 QualType Type = VD->getType().getNonReferenceType(); 1612 const DSAStackTy::DSAVarData DVar = 1613 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1614 if (DVar.CKind == OMPC_lastprivate) { 1615 // Generate helper private variable and initialize it with the 1616 // default value. The address of the original variable is replaced 1617 // by the address of the new private variable in CodeGen. This new 1618 // variable is not added to IdResolver, so the code in the OpenMP 1619 // region uses original variable for proper diagnostics. 1620 VarDecl *VDPrivate = buildVarDecl( 1621 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1622 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1623 ActOnUninitializedDecl(VDPrivate); 1624 if (VDPrivate->isInvalidDecl()) 1625 continue; 1626 PrivateCopies.push_back(buildDeclRefExpr( 1627 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1628 } else { 1629 // The variable is also a firstprivate, so initialization sequence 1630 // for private copy is generated already. 1631 PrivateCopies.push_back(nullptr); 1632 } 1633 } 1634 // Set initializers to private copies if no errors were found. 1635 if (PrivateCopies.size() == Clause->varlist_size()) 1636 Clause->setPrivateCopies(PrivateCopies); 1637 } 1638 } 1639 } 1640 1641 DSAStack->pop(); 1642 DiscardCleanupsInEvaluationContext(); 1643 PopExpressionEvaluationContext(); 1644 } 1645 1646 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1647 Expr *NumIterations, Sema &SemaRef, 1648 Scope *S, DSAStackTy *Stack); 1649 1650 namespace { 1651 1652 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1653 private: 1654 Sema &SemaRef; 1655 1656 public: 1657 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1658 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1659 NamedDecl *ND = Candidate.getCorrectionDecl(); 1660 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1661 return VD->hasGlobalStorage() && 1662 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1663 SemaRef.getCurScope()); 1664 } 1665 return false; 1666 } 1667 }; 1668 1669 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 1670 private: 1671 Sema &SemaRef; 1672 1673 public: 1674 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1675 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1676 NamedDecl *ND = Candidate.getCorrectionDecl(); 1677 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) { 1678 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1679 SemaRef.getCurScope()); 1680 } 1681 return false; 1682 } 1683 }; 1684 1685 } // namespace 1686 1687 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1688 CXXScopeSpec &ScopeSpec, 1689 const DeclarationNameInfo &Id) { 1690 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1691 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1692 1693 if (Lookup.isAmbiguous()) 1694 return ExprError(); 1695 1696 VarDecl *VD; 1697 if (!Lookup.isSingleResult()) { 1698 if (TypoCorrection Corrected = CorrectTypo( 1699 Id, LookupOrdinaryName, CurScope, nullptr, 1700 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1701 diagnoseTypo(Corrected, 1702 PDiag(Lookup.empty() 1703 ? diag::err_undeclared_var_use_suggest 1704 : diag::err_omp_expected_var_arg_suggest) 1705 << Id.getName()); 1706 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1707 } else { 1708 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1709 : diag::err_omp_expected_var_arg) 1710 << Id.getName(); 1711 return ExprError(); 1712 } 1713 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1714 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1715 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1716 return ExprError(); 1717 } 1718 Lookup.suppressDiagnostics(); 1719 1720 // OpenMP [2.9.2, Syntax, C/C++] 1721 // Variables must be file-scope, namespace-scope, or static block-scope. 1722 if (!VD->hasGlobalStorage()) { 1723 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1724 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1725 bool IsDecl = 1726 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1727 Diag(VD->getLocation(), 1728 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1729 << VD; 1730 return ExprError(); 1731 } 1732 1733 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1734 NamedDecl *ND = CanonicalVD; 1735 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1736 // A threadprivate directive for file-scope variables must appear outside 1737 // any definition or declaration. 1738 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1739 !getCurLexicalContext()->isTranslationUnit()) { 1740 Diag(Id.getLoc(), diag::err_omp_var_scope) 1741 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1742 bool IsDecl = 1743 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1744 Diag(VD->getLocation(), 1745 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1746 << VD; 1747 return ExprError(); 1748 } 1749 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1750 // A threadprivate directive for static class member variables must appear 1751 // in the class definition, in the same scope in which the member 1752 // variables are declared. 1753 if (CanonicalVD->isStaticDataMember() && 1754 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 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 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1765 // A threadprivate directive for namespace-scope variables must appear 1766 // outside any definition or declaration other than the namespace 1767 // definition itself. 1768 if (CanonicalVD->getDeclContext()->isNamespace() && 1769 (!getCurLexicalContext()->isFileContext() || 1770 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1771 Diag(Id.getLoc(), diag::err_omp_var_scope) 1772 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1773 bool IsDecl = 1774 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1775 Diag(VD->getLocation(), 1776 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1777 << VD; 1778 return ExprError(); 1779 } 1780 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1781 // A threadprivate directive for static block-scope variables must appear 1782 // in the scope of the variable and not in a nested scope. 1783 if (CanonicalVD->isStaticLocal() && CurScope && 1784 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1785 Diag(Id.getLoc(), diag::err_omp_var_scope) 1786 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1787 bool IsDecl = 1788 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1789 Diag(VD->getLocation(), 1790 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1791 << VD; 1792 return ExprError(); 1793 } 1794 1795 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1796 // A threadprivate directive must lexically precede all references to any 1797 // of the variables in its list. 1798 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1799 Diag(Id.getLoc(), diag::err_omp_var_used) 1800 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1801 return ExprError(); 1802 } 1803 1804 QualType ExprType = VD->getType().getNonReferenceType(); 1805 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1806 SourceLocation(), VD, 1807 /*RefersToEnclosingVariableOrCapture=*/false, 1808 Id.getLoc(), ExprType, VK_LValue); 1809 } 1810 1811 Sema::DeclGroupPtrTy 1812 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1813 ArrayRef<Expr *> VarList) { 1814 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1815 CurContext->addDecl(D); 1816 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1817 } 1818 return nullptr; 1819 } 1820 1821 namespace { 1822 class LocalVarRefChecker final 1823 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1824 Sema &SemaRef; 1825 1826 public: 1827 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1828 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1829 if (VD->hasLocalStorage()) { 1830 SemaRef.Diag(E->getBeginLoc(), 1831 diag::err_omp_local_var_in_threadprivate_init) 1832 << E->getSourceRange(); 1833 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1834 << VD << VD->getSourceRange(); 1835 return true; 1836 } 1837 } 1838 return false; 1839 } 1840 bool VisitStmt(const Stmt *S) { 1841 for (const Stmt *Child : S->children()) { 1842 if (Child && Visit(Child)) 1843 return true; 1844 } 1845 return false; 1846 } 1847 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1848 }; 1849 } // namespace 1850 1851 OMPThreadPrivateDecl * 1852 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1853 SmallVector<Expr *, 8> Vars; 1854 for (Expr *RefExpr : VarList) { 1855 auto *DE = cast<DeclRefExpr>(RefExpr); 1856 auto *VD = cast<VarDecl>(DE->getDecl()); 1857 SourceLocation ILoc = DE->getExprLoc(); 1858 1859 // Mark variable as used. 1860 VD->setReferenced(); 1861 VD->markUsed(Context); 1862 1863 QualType QType = VD->getType(); 1864 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1865 // It will be analyzed later. 1866 Vars.push_back(DE); 1867 continue; 1868 } 1869 1870 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1871 // A threadprivate variable must not have an incomplete type. 1872 if (RequireCompleteType(ILoc, VD->getType(), 1873 diag::err_omp_threadprivate_incomplete_type)) { 1874 continue; 1875 } 1876 1877 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1878 // A threadprivate variable must not have a reference type. 1879 if (VD->getType()->isReferenceType()) { 1880 Diag(ILoc, diag::err_omp_ref_type_arg) 1881 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1882 bool IsDecl = 1883 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1884 Diag(VD->getLocation(), 1885 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1886 << VD; 1887 continue; 1888 } 1889 1890 // Check if this is a TLS variable. If TLS is not being supported, produce 1891 // the corresponding diagnostic. 1892 if ((VD->getTLSKind() != VarDecl::TLS_None && 1893 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1894 getLangOpts().OpenMPUseTLS && 1895 getASTContext().getTargetInfo().isTLSSupported())) || 1896 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1897 !VD->isLocalVarDecl())) { 1898 Diag(ILoc, diag::err_omp_var_thread_local) 1899 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1900 bool IsDecl = 1901 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1902 Diag(VD->getLocation(), 1903 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1904 << VD; 1905 continue; 1906 } 1907 1908 // Check if initial value of threadprivate variable reference variable with 1909 // local storage (it is not supported by runtime). 1910 if (const Expr *Init = VD->getAnyInitializer()) { 1911 LocalVarRefChecker Checker(*this); 1912 if (Checker.Visit(Init)) 1913 continue; 1914 } 1915 1916 Vars.push_back(RefExpr); 1917 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1918 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1919 Context, SourceRange(Loc, Loc))); 1920 if (ASTMutationListener *ML = Context.getASTMutationListener()) 1921 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1922 } 1923 OMPThreadPrivateDecl *D = nullptr; 1924 if (!Vars.empty()) { 1925 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1926 Vars); 1927 D->setAccess(AS_public); 1928 } 1929 return D; 1930 } 1931 1932 Sema::DeclGroupPtrTy 1933 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 1934 ArrayRef<OMPClause *> ClauseList) { 1935 OMPRequiresDecl *D = nullptr; 1936 if (!CurContext->isFileContext()) { 1937 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 1938 } else { 1939 D = CheckOMPRequiresDecl(Loc, ClauseList); 1940 if (D) { 1941 CurContext->addDecl(D); 1942 DSAStack->addRequiresDecl(D); 1943 } 1944 } 1945 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1946 } 1947 1948 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 1949 ArrayRef<OMPClause *> ClauseList) { 1950 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 1951 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 1952 ClauseList); 1953 return nullptr; 1954 } 1955 1956 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 1957 const ValueDecl *D, 1958 const DSAStackTy::DSAVarData &DVar, 1959 bool IsLoopIterVar = false) { 1960 if (DVar.RefExpr) { 1961 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1962 << getOpenMPClauseName(DVar.CKind); 1963 return; 1964 } 1965 enum { 1966 PDSA_StaticMemberShared, 1967 PDSA_StaticLocalVarShared, 1968 PDSA_LoopIterVarPrivate, 1969 PDSA_LoopIterVarLinear, 1970 PDSA_LoopIterVarLastprivate, 1971 PDSA_ConstVarShared, 1972 PDSA_GlobalVarShared, 1973 PDSA_TaskVarFirstprivate, 1974 PDSA_LocalVarPrivate, 1975 PDSA_Implicit 1976 } Reason = PDSA_Implicit; 1977 bool ReportHint = false; 1978 auto ReportLoc = D->getLocation(); 1979 auto *VD = dyn_cast<VarDecl>(D); 1980 if (IsLoopIterVar) { 1981 if (DVar.CKind == OMPC_private) 1982 Reason = PDSA_LoopIterVarPrivate; 1983 else if (DVar.CKind == OMPC_lastprivate) 1984 Reason = PDSA_LoopIterVarLastprivate; 1985 else 1986 Reason = PDSA_LoopIterVarLinear; 1987 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1988 DVar.CKind == OMPC_firstprivate) { 1989 Reason = PDSA_TaskVarFirstprivate; 1990 ReportLoc = DVar.ImplicitDSALoc; 1991 } else if (VD && VD->isStaticLocal()) 1992 Reason = PDSA_StaticLocalVarShared; 1993 else if (VD && VD->isStaticDataMember()) 1994 Reason = PDSA_StaticMemberShared; 1995 else if (VD && VD->isFileVarDecl()) 1996 Reason = PDSA_GlobalVarShared; 1997 else if (D->getType().isConstant(SemaRef.getASTContext())) 1998 Reason = PDSA_ConstVarShared; 1999 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2000 ReportHint = true; 2001 Reason = PDSA_LocalVarPrivate; 2002 } 2003 if (Reason != PDSA_Implicit) { 2004 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2005 << Reason << ReportHint 2006 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2007 } else if (DVar.ImplicitDSALoc.isValid()) { 2008 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2009 << getOpenMPClauseName(DVar.CKind); 2010 } 2011 } 2012 2013 namespace { 2014 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2015 DSAStackTy *Stack; 2016 Sema &SemaRef; 2017 bool ErrorFound = false; 2018 CapturedStmt *CS = nullptr; 2019 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2020 llvm::SmallVector<Expr *, 4> ImplicitMap; 2021 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2022 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2023 2024 public: 2025 void VisitDeclRefExpr(DeclRefExpr *E) { 2026 if (E->isTypeDependent() || E->isValueDependent() || 2027 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2028 return; 2029 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2030 VD = VD->getCanonicalDecl(); 2031 // Skip internally declared variables. 2032 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 2033 return; 2034 2035 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2036 // Check if the variable has explicit DSA set and stop analysis if it so. 2037 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2038 return; 2039 2040 // Skip internally declared static variables. 2041 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2042 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2043 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && 2044 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2045 return; 2046 2047 SourceLocation ELoc = E->getExprLoc(); 2048 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2049 // The default(none) clause requires that each variable that is referenced 2050 // in the construct, and does not have a predetermined data-sharing 2051 // attribute, must have its data-sharing attribute explicitly determined 2052 // by being listed in a data-sharing attribute clause. 2053 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2054 isParallelOrTaskRegion(DKind) && 2055 VarsWithInheritedDSA.count(VD) == 0) { 2056 VarsWithInheritedDSA[VD] = E; 2057 return; 2058 } 2059 2060 if (isOpenMPTargetExecutionDirective(DKind) && 2061 !Stack->isLoopControlVariable(VD).first) { 2062 if (!Stack->checkMappableExprComponentListsForDecl( 2063 VD, /*CurrentRegionOnly=*/true, 2064 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2065 StackComponents, 2066 OpenMPClauseKind) { 2067 // Variable is used if it has been marked as an array, array 2068 // section or the variable iself. 2069 return StackComponents.size() == 1 || 2070 std::all_of( 2071 std::next(StackComponents.rbegin()), 2072 StackComponents.rend(), 2073 [](const OMPClauseMappableExprCommon:: 2074 MappableComponent &MC) { 2075 return MC.getAssociatedDeclaration() == 2076 nullptr && 2077 (isa<OMPArraySectionExpr>( 2078 MC.getAssociatedExpression()) || 2079 isa<ArraySubscriptExpr>( 2080 MC.getAssociatedExpression())); 2081 }); 2082 })) { 2083 bool IsFirstprivate = false; 2084 // By default lambdas are captured as firstprivates. 2085 if (const auto *RD = 2086 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2087 IsFirstprivate = RD->isLambda(); 2088 IsFirstprivate = 2089 IsFirstprivate || 2090 (VD->getType().getNonReferenceType()->isScalarType() && 2091 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2092 if (IsFirstprivate) 2093 ImplicitFirstprivate.emplace_back(E); 2094 else 2095 ImplicitMap.emplace_back(E); 2096 return; 2097 } 2098 } 2099 2100 // OpenMP [2.9.3.6, Restrictions, p.2] 2101 // A list item that appears in a reduction clause of the innermost 2102 // enclosing worksharing or parallel construct may not be accessed in an 2103 // explicit task. 2104 DVar = Stack->hasInnermostDSA( 2105 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2106 [](OpenMPDirectiveKind K) { 2107 return isOpenMPParallelDirective(K) || 2108 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2109 }, 2110 /*FromParent=*/true); 2111 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2112 ErrorFound = true; 2113 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2114 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2115 return; 2116 } 2117 2118 // Define implicit data-sharing attributes for task. 2119 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2120 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2121 !Stack->isLoopControlVariable(VD).first) 2122 ImplicitFirstprivate.push_back(E); 2123 } 2124 } 2125 void VisitMemberExpr(MemberExpr *E) { 2126 if (E->isTypeDependent() || E->isValueDependent() || 2127 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2128 return; 2129 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2130 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2131 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2132 if (!FD) 2133 return; 2134 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2135 // Check if the variable has explicit DSA set and stop analysis if it 2136 // so. 2137 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2138 return; 2139 2140 if (isOpenMPTargetExecutionDirective(DKind) && 2141 !Stack->isLoopControlVariable(FD).first && 2142 !Stack->checkMappableExprComponentListsForDecl( 2143 FD, /*CurrentRegionOnly=*/true, 2144 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2145 StackComponents, 2146 OpenMPClauseKind) { 2147 return isa<CXXThisExpr>( 2148 cast<MemberExpr>( 2149 StackComponents.back().getAssociatedExpression()) 2150 ->getBase() 2151 ->IgnoreParens()); 2152 })) { 2153 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2154 // A bit-field cannot appear in a map clause. 2155 // 2156 if (FD->isBitField()) 2157 return; 2158 ImplicitMap.emplace_back(E); 2159 return; 2160 } 2161 2162 SourceLocation ELoc = E->getExprLoc(); 2163 // OpenMP [2.9.3.6, Restrictions, p.2] 2164 // A list item that appears in a reduction clause of the innermost 2165 // enclosing worksharing or parallel construct may not be accessed in 2166 // an explicit task. 2167 DVar = Stack->hasInnermostDSA( 2168 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2169 [](OpenMPDirectiveKind K) { 2170 return isOpenMPParallelDirective(K) || 2171 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2172 }, 2173 /*FromParent=*/true); 2174 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2175 ErrorFound = true; 2176 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2177 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2178 return; 2179 } 2180 2181 // Define implicit data-sharing attributes for task. 2182 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2183 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2184 !Stack->isLoopControlVariable(FD).first) { 2185 // Check if there is a captured expression for the current field in the 2186 // region. Do not mark it as firstprivate unless there is no captured 2187 // expression. 2188 // TODO: try to make it firstprivate. 2189 if (DVar.CKind != OMPC_unknown) 2190 ImplicitFirstprivate.push_back(E); 2191 } 2192 return; 2193 } 2194 if (isOpenMPTargetExecutionDirective(DKind)) { 2195 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2196 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2197 /*NoDiagnose=*/true)) 2198 return; 2199 const auto *VD = cast<ValueDecl>( 2200 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2201 if (!Stack->checkMappableExprComponentListsForDecl( 2202 VD, /*CurrentRegionOnly=*/true, 2203 [&CurComponents]( 2204 OMPClauseMappableExprCommon::MappableExprComponentListRef 2205 StackComponents, 2206 OpenMPClauseKind) { 2207 auto CCI = CurComponents.rbegin(); 2208 auto CCE = CurComponents.rend(); 2209 for (const auto &SC : llvm::reverse(StackComponents)) { 2210 // Do both expressions have the same kind? 2211 if (CCI->getAssociatedExpression()->getStmtClass() != 2212 SC.getAssociatedExpression()->getStmtClass()) 2213 if (!(isa<OMPArraySectionExpr>( 2214 SC.getAssociatedExpression()) && 2215 isa<ArraySubscriptExpr>( 2216 CCI->getAssociatedExpression()))) 2217 return false; 2218 2219 const Decl *CCD = CCI->getAssociatedDeclaration(); 2220 const Decl *SCD = SC.getAssociatedDeclaration(); 2221 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2222 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2223 if (SCD != CCD) 2224 return false; 2225 std::advance(CCI, 1); 2226 if (CCI == CCE) 2227 break; 2228 } 2229 return true; 2230 })) { 2231 Visit(E->getBase()); 2232 } 2233 } else { 2234 Visit(E->getBase()); 2235 } 2236 } 2237 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2238 for (OMPClause *C : S->clauses()) { 2239 // Skip analysis of arguments of implicitly defined firstprivate clause 2240 // for task|target directives. 2241 // Skip analysis of arguments of implicitly defined map clause for target 2242 // directives. 2243 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2244 C->isImplicit())) { 2245 for (Stmt *CC : C->children()) { 2246 if (CC) 2247 Visit(CC); 2248 } 2249 } 2250 } 2251 } 2252 void VisitStmt(Stmt *S) { 2253 for (Stmt *C : S->children()) { 2254 if (C) { 2255 if (auto *OED = dyn_cast<OMPExecutableDirective>(C)) { 2256 // Check implicitly captured vriables in the task-based directives to 2257 // check if they must be firstprivatized. 2258 if (!OED->hasAssociatedStmt()) 2259 continue; 2260 const Stmt *AS = OED->getAssociatedStmt(); 2261 if (!AS) 2262 continue; 2263 for (const CapturedStmt::Capture &Cap : 2264 cast<CapturedStmt>(AS)->captures()) { 2265 if (Cap.capturesVariable()) { 2266 DeclRefExpr *DRE = buildDeclRefExpr( 2267 SemaRef, Cap.getCapturedVar(), 2268 Cap.getCapturedVar()->getType().getNonLValueExprType( 2269 SemaRef.Context), 2270 Cap.getLocation(), 2271 /*RefersToCapture=*/true); 2272 Visit(DRE); 2273 } 2274 } 2275 } else { 2276 Visit(C); 2277 } 2278 } 2279 } 2280 } 2281 2282 bool isErrorFound() const { return ErrorFound; } 2283 ArrayRef<Expr *> getImplicitFirstprivate() const { 2284 return ImplicitFirstprivate; 2285 } 2286 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2287 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2288 return VarsWithInheritedDSA; 2289 } 2290 2291 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2292 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 2293 }; 2294 } // namespace 2295 2296 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2297 switch (DKind) { 2298 case OMPD_parallel: 2299 case OMPD_parallel_for: 2300 case OMPD_parallel_for_simd: 2301 case OMPD_parallel_sections: 2302 case OMPD_teams: 2303 case OMPD_teams_distribute: 2304 case OMPD_teams_distribute_simd: { 2305 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2306 QualType KmpInt32PtrTy = 2307 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2308 Sema::CapturedParamNameType Params[] = { 2309 std::make_pair(".global_tid.", KmpInt32PtrTy), 2310 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2311 std::make_pair(StringRef(), QualType()) // __context with shared vars 2312 }; 2313 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2314 Params); 2315 break; 2316 } 2317 case OMPD_target_teams: 2318 case OMPD_target_parallel: 2319 case OMPD_target_parallel_for: 2320 case OMPD_target_parallel_for_simd: 2321 case OMPD_target_teams_distribute: 2322 case OMPD_target_teams_distribute_simd: { 2323 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2324 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2325 QualType KmpInt32PtrTy = 2326 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2327 QualType Args[] = {VoidPtrTy}; 2328 FunctionProtoType::ExtProtoInfo EPI; 2329 EPI.Variadic = true; 2330 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2331 Sema::CapturedParamNameType Params[] = { 2332 std::make_pair(".global_tid.", KmpInt32Ty), 2333 std::make_pair(".part_id.", KmpInt32PtrTy), 2334 std::make_pair(".privates.", VoidPtrTy), 2335 std::make_pair( 2336 ".copy_fn.", 2337 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2338 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2339 std::make_pair(StringRef(), QualType()) // __context with shared vars 2340 }; 2341 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2342 Params); 2343 // Mark this captured region as inlined, because we don't use outlined 2344 // function directly. 2345 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2346 AlwaysInlineAttr::CreateImplicit( 2347 Context, AlwaysInlineAttr::Keyword_forceinline)); 2348 Sema::CapturedParamNameType ParamsTarget[] = { 2349 std::make_pair(StringRef(), QualType()) // __context with shared vars 2350 }; 2351 // Start a captured region for 'target' with no implicit parameters. 2352 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2353 ParamsTarget); 2354 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2355 std::make_pair(".global_tid.", KmpInt32PtrTy), 2356 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2357 std::make_pair(StringRef(), QualType()) // __context with shared vars 2358 }; 2359 // Start a captured region for 'teams' or 'parallel'. Both regions have 2360 // the same implicit parameters. 2361 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2362 ParamsTeamsOrParallel); 2363 break; 2364 } 2365 case OMPD_target: 2366 case OMPD_target_simd: { 2367 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2368 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2369 QualType KmpInt32PtrTy = 2370 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2371 QualType Args[] = {VoidPtrTy}; 2372 FunctionProtoType::ExtProtoInfo EPI; 2373 EPI.Variadic = true; 2374 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2375 Sema::CapturedParamNameType Params[] = { 2376 std::make_pair(".global_tid.", KmpInt32Ty), 2377 std::make_pair(".part_id.", KmpInt32PtrTy), 2378 std::make_pair(".privates.", VoidPtrTy), 2379 std::make_pair( 2380 ".copy_fn.", 2381 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2382 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2383 std::make_pair(StringRef(), QualType()) // __context with shared vars 2384 }; 2385 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2386 Params); 2387 // Mark this captured region as inlined, because we don't use outlined 2388 // function directly. 2389 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2390 AlwaysInlineAttr::CreateImplicit( 2391 Context, AlwaysInlineAttr::Keyword_forceinline)); 2392 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2393 std::make_pair(StringRef(), QualType())); 2394 break; 2395 } 2396 case OMPD_simd: 2397 case OMPD_for: 2398 case OMPD_for_simd: 2399 case OMPD_sections: 2400 case OMPD_section: 2401 case OMPD_single: 2402 case OMPD_master: 2403 case OMPD_critical: 2404 case OMPD_taskgroup: 2405 case OMPD_distribute: 2406 case OMPD_distribute_simd: 2407 case OMPD_ordered: 2408 case OMPD_atomic: 2409 case OMPD_target_data: { 2410 Sema::CapturedParamNameType Params[] = { 2411 std::make_pair(StringRef(), QualType()) // __context with shared vars 2412 }; 2413 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2414 Params); 2415 break; 2416 } 2417 case OMPD_task: { 2418 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2419 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2420 QualType KmpInt32PtrTy = 2421 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2422 QualType Args[] = {VoidPtrTy}; 2423 FunctionProtoType::ExtProtoInfo EPI; 2424 EPI.Variadic = true; 2425 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2426 Sema::CapturedParamNameType Params[] = { 2427 std::make_pair(".global_tid.", KmpInt32Ty), 2428 std::make_pair(".part_id.", KmpInt32PtrTy), 2429 std::make_pair(".privates.", VoidPtrTy), 2430 std::make_pair( 2431 ".copy_fn.", 2432 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2433 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2434 std::make_pair(StringRef(), QualType()) // __context with shared vars 2435 }; 2436 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2437 Params); 2438 // Mark this captured region as inlined, because we don't use outlined 2439 // function directly. 2440 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2441 AlwaysInlineAttr::CreateImplicit( 2442 Context, AlwaysInlineAttr::Keyword_forceinline)); 2443 break; 2444 } 2445 case OMPD_taskloop: 2446 case OMPD_taskloop_simd: { 2447 QualType KmpInt32Ty = 2448 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 2449 .withConst(); 2450 QualType KmpUInt64Ty = 2451 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 2452 .withConst(); 2453 QualType KmpInt64Ty = 2454 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 2455 .withConst(); 2456 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2457 QualType KmpInt32PtrTy = 2458 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2459 QualType Args[] = {VoidPtrTy}; 2460 FunctionProtoType::ExtProtoInfo EPI; 2461 EPI.Variadic = true; 2462 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2463 Sema::CapturedParamNameType Params[] = { 2464 std::make_pair(".global_tid.", KmpInt32Ty), 2465 std::make_pair(".part_id.", KmpInt32PtrTy), 2466 std::make_pair(".privates.", VoidPtrTy), 2467 std::make_pair( 2468 ".copy_fn.", 2469 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2470 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2471 std::make_pair(".lb.", KmpUInt64Ty), 2472 std::make_pair(".ub.", KmpUInt64Ty), 2473 std::make_pair(".st.", KmpInt64Ty), 2474 std::make_pair(".liter.", KmpInt32Ty), 2475 std::make_pair(".reductions.", VoidPtrTy), 2476 std::make_pair(StringRef(), QualType()) // __context with shared vars 2477 }; 2478 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2479 Params); 2480 // Mark this captured region as inlined, because we don't use outlined 2481 // function directly. 2482 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2483 AlwaysInlineAttr::CreateImplicit( 2484 Context, AlwaysInlineAttr::Keyword_forceinline)); 2485 break; 2486 } 2487 case OMPD_distribute_parallel_for_simd: 2488 case OMPD_distribute_parallel_for: { 2489 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2490 QualType KmpInt32PtrTy = 2491 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2492 Sema::CapturedParamNameType Params[] = { 2493 std::make_pair(".global_tid.", KmpInt32PtrTy), 2494 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2495 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2496 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2497 std::make_pair(StringRef(), QualType()) // __context with shared vars 2498 }; 2499 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2500 Params); 2501 break; 2502 } 2503 case OMPD_target_teams_distribute_parallel_for: 2504 case OMPD_target_teams_distribute_parallel_for_simd: { 2505 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2506 QualType KmpInt32PtrTy = 2507 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2508 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2509 2510 QualType Args[] = {VoidPtrTy}; 2511 FunctionProtoType::ExtProtoInfo EPI; 2512 EPI.Variadic = true; 2513 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2514 Sema::CapturedParamNameType Params[] = { 2515 std::make_pair(".global_tid.", KmpInt32Ty), 2516 std::make_pair(".part_id.", KmpInt32PtrTy), 2517 std::make_pair(".privates.", VoidPtrTy), 2518 std::make_pair( 2519 ".copy_fn.", 2520 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2521 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2522 std::make_pair(StringRef(), QualType()) // __context with shared vars 2523 }; 2524 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2525 Params); 2526 // Mark this captured region as inlined, because we don't use outlined 2527 // function directly. 2528 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2529 AlwaysInlineAttr::CreateImplicit( 2530 Context, AlwaysInlineAttr::Keyword_forceinline)); 2531 Sema::CapturedParamNameType ParamsTarget[] = { 2532 std::make_pair(StringRef(), QualType()) // __context with shared vars 2533 }; 2534 // Start a captured region for 'target' with no implicit parameters. 2535 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2536 ParamsTarget); 2537 2538 Sema::CapturedParamNameType ParamsTeams[] = { 2539 std::make_pair(".global_tid.", KmpInt32PtrTy), 2540 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2541 std::make_pair(StringRef(), QualType()) // __context with shared vars 2542 }; 2543 // Start a captured region for 'target' with no implicit parameters. 2544 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2545 ParamsTeams); 2546 2547 Sema::CapturedParamNameType ParamsParallel[] = { 2548 std::make_pair(".global_tid.", KmpInt32PtrTy), 2549 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2550 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2551 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2552 std::make_pair(StringRef(), QualType()) // __context with shared vars 2553 }; 2554 // Start a captured region for 'teams' or 'parallel'. Both regions have 2555 // the same implicit parameters. 2556 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2557 ParamsParallel); 2558 break; 2559 } 2560 2561 case OMPD_teams_distribute_parallel_for: 2562 case OMPD_teams_distribute_parallel_for_simd: { 2563 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2564 QualType KmpInt32PtrTy = 2565 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2566 2567 Sema::CapturedParamNameType ParamsTeams[] = { 2568 std::make_pair(".global_tid.", KmpInt32PtrTy), 2569 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2570 std::make_pair(StringRef(), QualType()) // __context with shared vars 2571 }; 2572 // Start a captured region for 'target' with no implicit parameters. 2573 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2574 ParamsTeams); 2575 2576 Sema::CapturedParamNameType ParamsParallel[] = { 2577 std::make_pair(".global_tid.", KmpInt32PtrTy), 2578 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2579 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2580 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2581 std::make_pair(StringRef(), QualType()) // __context with shared vars 2582 }; 2583 // Start a captured region for 'teams' or 'parallel'. Both regions have 2584 // the same implicit parameters. 2585 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2586 ParamsParallel); 2587 break; 2588 } 2589 case OMPD_target_update: 2590 case OMPD_target_enter_data: 2591 case OMPD_target_exit_data: { 2592 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2593 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2594 QualType KmpInt32PtrTy = 2595 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2596 QualType Args[] = {VoidPtrTy}; 2597 FunctionProtoType::ExtProtoInfo EPI; 2598 EPI.Variadic = true; 2599 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2600 Sema::CapturedParamNameType Params[] = { 2601 std::make_pair(".global_tid.", KmpInt32Ty), 2602 std::make_pair(".part_id.", KmpInt32PtrTy), 2603 std::make_pair(".privates.", VoidPtrTy), 2604 std::make_pair( 2605 ".copy_fn.", 2606 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2607 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2608 std::make_pair(StringRef(), QualType()) // __context with shared vars 2609 }; 2610 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2611 Params); 2612 // Mark this captured region as inlined, because we don't use outlined 2613 // function directly. 2614 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2615 AlwaysInlineAttr::CreateImplicit( 2616 Context, AlwaysInlineAttr::Keyword_forceinline)); 2617 break; 2618 } 2619 case OMPD_threadprivate: 2620 case OMPD_taskyield: 2621 case OMPD_barrier: 2622 case OMPD_taskwait: 2623 case OMPD_cancellation_point: 2624 case OMPD_cancel: 2625 case OMPD_flush: 2626 case OMPD_declare_reduction: 2627 case OMPD_declare_simd: 2628 case OMPD_declare_target: 2629 case OMPD_end_declare_target: 2630 case OMPD_requires: 2631 llvm_unreachable("OpenMP Directive is not allowed"); 2632 case OMPD_unknown: 2633 llvm_unreachable("Unknown OpenMP directive"); 2634 } 2635 } 2636 2637 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 2638 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2639 getOpenMPCaptureRegions(CaptureRegions, DKind); 2640 return CaptureRegions.size(); 2641 } 2642 2643 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2644 Expr *CaptureExpr, bool WithInit, 2645 bool AsExpression) { 2646 assert(CaptureExpr); 2647 ASTContext &C = S.getASTContext(); 2648 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 2649 QualType Ty = Init->getType(); 2650 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 2651 if (S.getLangOpts().CPlusPlus) { 2652 Ty = C.getLValueReferenceType(Ty); 2653 } else { 2654 Ty = C.getPointerType(Ty); 2655 ExprResult Res = 2656 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 2657 if (!Res.isUsable()) 2658 return nullptr; 2659 Init = Res.get(); 2660 } 2661 WithInit = true; 2662 } 2663 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 2664 CaptureExpr->getBeginLoc()); 2665 if (!WithInit) 2666 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 2667 S.CurContext->addHiddenDecl(CED); 2668 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 2669 return CED; 2670 } 2671 2672 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2673 bool WithInit) { 2674 OMPCapturedExprDecl *CD; 2675 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 2676 CD = cast<OMPCapturedExprDecl>(VD); 2677 else 2678 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 2679 /*AsExpression=*/false); 2680 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2681 CaptureExpr->getExprLoc()); 2682 } 2683 2684 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 2685 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 2686 if (!Ref) { 2687 OMPCapturedExprDecl *CD = buildCaptureDecl( 2688 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 2689 /*WithInit=*/true, /*AsExpression=*/true); 2690 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2691 CaptureExpr->getExprLoc()); 2692 } 2693 ExprResult Res = Ref; 2694 if (!S.getLangOpts().CPlusPlus && 2695 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 2696 Ref->getType()->isPointerType()) { 2697 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 2698 if (!Res.isUsable()) 2699 return ExprError(); 2700 } 2701 return S.DefaultLvalueConversion(Res.get()); 2702 } 2703 2704 namespace { 2705 // OpenMP directives parsed in this section are represented as a 2706 // CapturedStatement with an associated statement. If a syntax error 2707 // is detected during the parsing of the associated statement, the 2708 // compiler must abort processing and close the CapturedStatement. 2709 // 2710 // Combined directives such as 'target parallel' have more than one 2711 // nested CapturedStatements. This RAII ensures that we unwind out 2712 // of all the nested CapturedStatements when an error is found. 2713 class CaptureRegionUnwinderRAII { 2714 private: 2715 Sema &S; 2716 bool &ErrorFound; 2717 OpenMPDirectiveKind DKind = OMPD_unknown; 2718 2719 public: 2720 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 2721 OpenMPDirectiveKind DKind) 2722 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 2723 ~CaptureRegionUnwinderRAII() { 2724 if (ErrorFound) { 2725 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 2726 while (--ThisCaptureLevel >= 0) 2727 S.ActOnCapturedRegionError(); 2728 } 2729 } 2730 }; 2731 } // namespace 2732 2733 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 2734 ArrayRef<OMPClause *> Clauses) { 2735 bool ErrorFound = false; 2736 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 2737 *this, ErrorFound, DSAStack->getCurrentDirective()); 2738 if (!S.isUsable()) { 2739 ErrorFound = true; 2740 return StmtError(); 2741 } 2742 2743 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2744 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 2745 OMPOrderedClause *OC = nullptr; 2746 OMPScheduleClause *SC = nullptr; 2747 SmallVector<const OMPLinearClause *, 4> LCs; 2748 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 2749 // This is required for proper codegen. 2750 for (OMPClause *Clause : Clauses) { 2751 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2752 Clause->getClauseKind() == OMPC_in_reduction) { 2753 // Capture taskgroup task_reduction descriptors inside the tasking regions 2754 // with the corresponding in_reduction items. 2755 auto *IRC = cast<OMPInReductionClause>(Clause); 2756 for (Expr *E : IRC->taskgroup_descriptors()) 2757 if (E) 2758 MarkDeclarationsReferencedInExpr(E); 2759 } 2760 if (isOpenMPPrivate(Clause->getClauseKind()) || 2761 Clause->getClauseKind() == OMPC_copyprivate || 2762 (getLangOpts().OpenMPUseTLS && 2763 getASTContext().getTargetInfo().isTLSSupported() && 2764 Clause->getClauseKind() == OMPC_copyin)) { 2765 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 2766 // Mark all variables in private list clauses as used in inner region. 2767 for (Stmt *VarRef : Clause->children()) { 2768 if (auto *E = cast_or_null<Expr>(VarRef)) { 2769 MarkDeclarationsReferencedInExpr(E); 2770 } 2771 } 2772 DSAStack->setForceVarCapturing(/*V=*/false); 2773 } else if (CaptureRegions.size() > 1 || 2774 CaptureRegions.back() != OMPD_unknown) { 2775 if (auto *C = OMPClauseWithPreInit::get(Clause)) 2776 PICs.push_back(C); 2777 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 2778 if (Expr *E = C->getPostUpdateExpr()) 2779 MarkDeclarationsReferencedInExpr(E); 2780 } 2781 } 2782 if (Clause->getClauseKind() == OMPC_schedule) 2783 SC = cast<OMPScheduleClause>(Clause); 2784 else if (Clause->getClauseKind() == OMPC_ordered) 2785 OC = cast<OMPOrderedClause>(Clause); 2786 else if (Clause->getClauseKind() == OMPC_linear) 2787 LCs.push_back(cast<OMPLinearClause>(Clause)); 2788 } 2789 // OpenMP, 2.7.1 Loop Construct, Restrictions 2790 // The nonmonotonic modifier cannot be specified if an ordered clause is 2791 // specified. 2792 if (SC && 2793 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 2794 SC->getSecondScheduleModifier() == 2795 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 2796 OC) { 2797 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 2798 ? SC->getFirstScheduleModifierLoc() 2799 : SC->getSecondScheduleModifierLoc(), 2800 diag::err_omp_schedule_nonmonotonic_ordered) 2801 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 2802 ErrorFound = true; 2803 } 2804 if (!LCs.empty() && OC && OC->getNumForLoops()) { 2805 for (const OMPLinearClause *C : LCs) { 2806 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 2807 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 2808 } 2809 ErrorFound = true; 2810 } 2811 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 2812 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 2813 OC->getNumForLoops()) { 2814 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 2815 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 2816 ErrorFound = true; 2817 } 2818 if (ErrorFound) { 2819 return StmtError(); 2820 } 2821 StmtResult SR = S; 2822 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 2823 // Mark all variables in private list clauses as used in inner region. 2824 // Required for proper codegen of combined directives. 2825 // TODO: add processing for other clauses. 2826 if (ThisCaptureRegion != OMPD_unknown) { 2827 for (const clang::OMPClauseWithPreInit *C : PICs) { 2828 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 2829 // Find the particular capture region for the clause if the 2830 // directive is a combined one with multiple capture regions. 2831 // If the directive is not a combined one, the capture region 2832 // associated with the clause is OMPD_unknown and is generated 2833 // only once. 2834 if (CaptureRegion == ThisCaptureRegion || 2835 CaptureRegion == OMPD_unknown) { 2836 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 2837 for (Decl *D : DS->decls()) 2838 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 2839 } 2840 } 2841 } 2842 } 2843 SR = ActOnCapturedRegionEnd(SR.get()); 2844 } 2845 return SR; 2846 } 2847 2848 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 2849 OpenMPDirectiveKind CancelRegion, 2850 SourceLocation StartLoc) { 2851 // CancelRegion is only needed for cancel and cancellation_point. 2852 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 2853 return false; 2854 2855 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 2856 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 2857 return false; 2858 2859 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 2860 << getOpenMPDirectiveName(CancelRegion); 2861 return true; 2862 } 2863 2864 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 2865 OpenMPDirectiveKind CurrentRegion, 2866 const DeclarationNameInfo &CurrentName, 2867 OpenMPDirectiveKind CancelRegion, 2868 SourceLocation StartLoc) { 2869 if (Stack->getCurScope()) { 2870 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 2871 OpenMPDirectiveKind OffendingRegion = ParentRegion; 2872 bool NestingProhibited = false; 2873 bool CloseNesting = true; 2874 bool OrphanSeen = false; 2875 enum { 2876 NoRecommend, 2877 ShouldBeInParallelRegion, 2878 ShouldBeInOrderedRegion, 2879 ShouldBeInTargetRegion, 2880 ShouldBeInTeamsRegion 2881 } Recommend = NoRecommend; 2882 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 2883 // OpenMP [2.16, Nesting of Regions] 2884 // OpenMP constructs may not be nested inside a simd region. 2885 // OpenMP [2.8.1,simd Construct, Restrictions] 2886 // An ordered construct with the simd clause is the only OpenMP 2887 // construct that can appear in the simd region. 2888 // Allowing a SIMD construct nested in another SIMD construct is an 2889 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 2890 // message. 2891 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 2892 ? diag::err_omp_prohibited_region_simd 2893 : diag::warn_omp_nesting_simd); 2894 return CurrentRegion != OMPD_simd; 2895 } 2896 if (ParentRegion == OMPD_atomic) { 2897 // OpenMP [2.16, Nesting of Regions] 2898 // OpenMP constructs may not be nested inside an atomic region. 2899 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2900 return true; 2901 } 2902 if (CurrentRegion == OMPD_section) { 2903 // OpenMP [2.7.2, sections Construct, Restrictions] 2904 // Orphaned section directives are prohibited. That is, the section 2905 // directives must appear within the sections construct and must not be 2906 // encountered elsewhere in the sections region. 2907 if (ParentRegion != OMPD_sections && 2908 ParentRegion != OMPD_parallel_sections) { 2909 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2910 << (ParentRegion != OMPD_unknown) 2911 << getOpenMPDirectiveName(ParentRegion); 2912 return true; 2913 } 2914 return false; 2915 } 2916 // Allow some constructs (except teams) to be orphaned (they could be 2917 // used in functions, called from OpenMP regions with the required 2918 // preconditions). 2919 if (ParentRegion == OMPD_unknown && 2920 !isOpenMPNestingTeamsDirective(CurrentRegion)) 2921 return false; 2922 if (CurrentRegion == OMPD_cancellation_point || 2923 CurrentRegion == OMPD_cancel) { 2924 // OpenMP [2.16, Nesting of Regions] 2925 // A cancellation point construct for which construct-type-clause is 2926 // taskgroup must be nested inside a task construct. A cancellation 2927 // point construct for which construct-type-clause is not taskgroup must 2928 // be closely nested inside an OpenMP construct that matches the type 2929 // specified in construct-type-clause. 2930 // A cancel construct for which construct-type-clause is taskgroup must be 2931 // nested inside a task construct. A cancel construct for which 2932 // construct-type-clause is not taskgroup must be closely nested inside an 2933 // OpenMP construct that matches the type specified in 2934 // construct-type-clause. 2935 NestingProhibited = 2936 !((CancelRegion == OMPD_parallel && 2937 (ParentRegion == OMPD_parallel || 2938 ParentRegion == OMPD_target_parallel)) || 2939 (CancelRegion == OMPD_for && 2940 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2941 ParentRegion == OMPD_target_parallel_for || 2942 ParentRegion == OMPD_distribute_parallel_for || 2943 ParentRegion == OMPD_teams_distribute_parallel_for || 2944 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 2945 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2946 (CancelRegion == OMPD_sections && 2947 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2948 ParentRegion == OMPD_parallel_sections))); 2949 } else if (CurrentRegion == OMPD_master) { 2950 // OpenMP [2.16, Nesting of Regions] 2951 // A master region may not be closely nested inside a worksharing, 2952 // atomic, or explicit task region. 2953 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2954 isOpenMPTaskingDirective(ParentRegion); 2955 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2956 // OpenMP [2.16, Nesting of Regions] 2957 // A critical region may not be nested (closely or otherwise) inside a 2958 // critical region with the same name. Note that this restriction is not 2959 // sufficient to prevent deadlock. 2960 SourceLocation PreviousCriticalLoc; 2961 bool DeadLock = Stack->hasDirective( 2962 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 2963 const DeclarationNameInfo &DNI, 2964 SourceLocation Loc) { 2965 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 2966 PreviousCriticalLoc = Loc; 2967 return true; 2968 } 2969 return false; 2970 }, 2971 false /* skip top directive */); 2972 if (DeadLock) { 2973 SemaRef.Diag(StartLoc, 2974 diag::err_omp_prohibited_region_critical_same_name) 2975 << CurrentName.getName(); 2976 if (PreviousCriticalLoc.isValid()) 2977 SemaRef.Diag(PreviousCriticalLoc, 2978 diag::note_omp_previous_critical_region); 2979 return true; 2980 } 2981 } else if (CurrentRegion == OMPD_barrier) { 2982 // OpenMP [2.16, Nesting of Regions] 2983 // A barrier region may not be closely nested inside a worksharing, 2984 // explicit task, critical, ordered, atomic, or master region. 2985 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2986 isOpenMPTaskingDirective(ParentRegion) || 2987 ParentRegion == OMPD_master || 2988 ParentRegion == OMPD_critical || 2989 ParentRegion == OMPD_ordered; 2990 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2991 !isOpenMPParallelDirective(CurrentRegion) && 2992 !isOpenMPTeamsDirective(CurrentRegion)) { 2993 // OpenMP [2.16, Nesting of Regions] 2994 // A worksharing region may not be closely nested inside a worksharing, 2995 // explicit task, critical, ordered, atomic, or master region. 2996 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2997 isOpenMPTaskingDirective(ParentRegion) || 2998 ParentRegion == OMPD_master || 2999 ParentRegion == OMPD_critical || 3000 ParentRegion == OMPD_ordered; 3001 Recommend = ShouldBeInParallelRegion; 3002 } else if (CurrentRegion == OMPD_ordered) { 3003 // OpenMP [2.16, Nesting of Regions] 3004 // An ordered region may not be closely nested inside a critical, 3005 // atomic, or explicit task region. 3006 // An ordered region must be closely nested inside a loop region (or 3007 // parallel loop region) with an ordered clause. 3008 // OpenMP [2.8.1,simd Construct, Restrictions] 3009 // An ordered construct with the simd clause is the only OpenMP construct 3010 // that can appear in the simd region. 3011 NestingProhibited = ParentRegion == OMPD_critical || 3012 isOpenMPTaskingDirective(ParentRegion) || 3013 !(isOpenMPSimdDirective(ParentRegion) || 3014 Stack->isParentOrderedRegion()); 3015 Recommend = ShouldBeInOrderedRegion; 3016 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3017 // OpenMP [2.16, Nesting of Regions] 3018 // If specified, a teams construct must be contained within a target 3019 // construct. 3020 NestingProhibited = ParentRegion != OMPD_target; 3021 OrphanSeen = ParentRegion == OMPD_unknown; 3022 Recommend = ShouldBeInTargetRegion; 3023 } 3024 if (!NestingProhibited && 3025 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3026 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3027 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3028 // OpenMP [2.16, Nesting of Regions] 3029 // distribute, parallel, parallel sections, parallel workshare, and the 3030 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3031 // constructs that can be closely nested in the teams region. 3032 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3033 !isOpenMPDistributeDirective(CurrentRegion); 3034 Recommend = ShouldBeInParallelRegion; 3035 } 3036 if (!NestingProhibited && 3037 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3038 // OpenMP 4.5 [2.17 Nesting of Regions] 3039 // The region associated with the distribute construct must be strictly 3040 // nested inside a teams region 3041 NestingProhibited = 3042 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3043 Recommend = ShouldBeInTeamsRegion; 3044 } 3045 if (!NestingProhibited && 3046 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3047 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3048 // OpenMP 4.5 [2.17 Nesting of Regions] 3049 // If a target, target update, target data, target enter data, or 3050 // target exit data construct is encountered during execution of a 3051 // target region, the behavior is unspecified. 3052 NestingProhibited = Stack->hasDirective( 3053 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3054 SourceLocation) { 3055 if (isOpenMPTargetExecutionDirective(K)) { 3056 OffendingRegion = K; 3057 return true; 3058 } 3059 return false; 3060 }, 3061 false /* don't skip top directive */); 3062 CloseNesting = false; 3063 } 3064 if (NestingProhibited) { 3065 if (OrphanSeen) { 3066 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3067 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3068 } else { 3069 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3070 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3071 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3072 } 3073 return true; 3074 } 3075 } 3076 return false; 3077 } 3078 3079 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3080 ArrayRef<OMPClause *> Clauses, 3081 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3082 bool ErrorFound = false; 3083 unsigned NamedModifiersNumber = 0; 3084 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3085 OMPD_unknown + 1); 3086 SmallVector<SourceLocation, 4> NameModifierLoc; 3087 for (const OMPClause *C : Clauses) { 3088 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3089 // At most one if clause without a directive-name-modifier can appear on 3090 // the directive. 3091 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3092 if (FoundNameModifiers[CurNM]) { 3093 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3094 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3095 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3096 ErrorFound = true; 3097 } else if (CurNM != OMPD_unknown) { 3098 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3099 ++NamedModifiersNumber; 3100 } 3101 FoundNameModifiers[CurNM] = IC; 3102 if (CurNM == OMPD_unknown) 3103 continue; 3104 // Check if the specified name modifier is allowed for the current 3105 // directive. 3106 // At most one if clause with the particular directive-name-modifier can 3107 // appear on the directive. 3108 bool MatchFound = false; 3109 for (auto NM : AllowedNameModifiers) { 3110 if (CurNM == NM) { 3111 MatchFound = true; 3112 break; 3113 } 3114 } 3115 if (!MatchFound) { 3116 S.Diag(IC->getNameModifierLoc(), 3117 diag::err_omp_wrong_if_directive_name_modifier) 3118 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3119 ErrorFound = true; 3120 } 3121 } 3122 } 3123 // If any if clause on the directive includes a directive-name-modifier then 3124 // all if clauses on the directive must include a directive-name-modifier. 3125 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3126 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3127 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3128 diag::err_omp_no_more_if_clause); 3129 } else { 3130 std::string Values; 3131 std::string Sep(", "); 3132 unsigned AllowedCnt = 0; 3133 unsigned TotalAllowedNum = 3134 AllowedNameModifiers.size() - NamedModifiersNumber; 3135 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3136 ++Cnt) { 3137 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3138 if (!FoundNameModifiers[NM]) { 3139 Values += "'"; 3140 Values += getOpenMPDirectiveName(NM); 3141 Values += "'"; 3142 if (AllowedCnt + 2 == TotalAllowedNum) 3143 Values += " or "; 3144 else if (AllowedCnt + 1 != TotalAllowedNum) 3145 Values += Sep; 3146 ++AllowedCnt; 3147 } 3148 } 3149 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3150 diag::err_omp_unnamed_if_clause) 3151 << (TotalAllowedNum > 1) << Values; 3152 } 3153 for (SourceLocation Loc : NameModifierLoc) { 3154 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3155 } 3156 ErrorFound = true; 3157 } 3158 return ErrorFound; 3159 } 3160 3161 StmtResult Sema::ActOnOpenMPExecutableDirective( 3162 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3163 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3164 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3165 StmtResult Res = StmtError(); 3166 // First check CancelRegion which is then used in checkNestingOfRegions. 3167 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3168 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3169 StartLoc)) 3170 return StmtError(); 3171 3172 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3173 VarsWithInheritedDSAType VarsWithInheritedDSA; 3174 bool ErrorFound = false; 3175 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3176 if (AStmt && !CurContext->isDependentContext()) { 3177 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3178 3179 // Check default data sharing attributes for referenced variables. 3180 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3181 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3182 Stmt *S = AStmt; 3183 while (--ThisCaptureLevel >= 0) 3184 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3185 DSAChecker.Visit(S); 3186 if (DSAChecker.isErrorFound()) 3187 return StmtError(); 3188 // Generate list of implicitly defined firstprivate variables. 3189 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3190 3191 SmallVector<Expr *, 4> ImplicitFirstprivates( 3192 DSAChecker.getImplicitFirstprivate().begin(), 3193 DSAChecker.getImplicitFirstprivate().end()); 3194 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3195 DSAChecker.getImplicitMap().end()); 3196 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3197 for (OMPClause *C : Clauses) { 3198 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3199 for (Expr *E : IRC->taskgroup_descriptors()) 3200 if (E) 3201 ImplicitFirstprivates.emplace_back(E); 3202 } 3203 } 3204 if (!ImplicitFirstprivates.empty()) { 3205 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3206 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3207 SourceLocation())) { 3208 ClausesWithImplicit.push_back(Implicit); 3209 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3210 ImplicitFirstprivates.size(); 3211 } else { 3212 ErrorFound = true; 3213 } 3214 } 3215 if (!ImplicitMaps.empty()) { 3216 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3217 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, 3218 SourceLocation(), SourceLocation(), ImplicitMaps, 3219 SourceLocation(), SourceLocation(), SourceLocation())) { 3220 ClausesWithImplicit.emplace_back(Implicit); 3221 ErrorFound |= 3222 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3223 } else { 3224 ErrorFound = true; 3225 } 3226 } 3227 } 3228 3229 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3230 switch (Kind) { 3231 case OMPD_parallel: 3232 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3233 EndLoc); 3234 AllowedNameModifiers.push_back(OMPD_parallel); 3235 break; 3236 case OMPD_simd: 3237 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3238 VarsWithInheritedDSA); 3239 break; 3240 case OMPD_for: 3241 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3242 VarsWithInheritedDSA); 3243 break; 3244 case OMPD_for_simd: 3245 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3246 EndLoc, VarsWithInheritedDSA); 3247 break; 3248 case OMPD_sections: 3249 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3250 EndLoc); 3251 break; 3252 case OMPD_section: 3253 assert(ClausesWithImplicit.empty() && 3254 "No clauses are allowed for 'omp section' directive"); 3255 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3256 break; 3257 case OMPD_single: 3258 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3259 EndLoc); 3260 break; 3261 case OMPD_master: 3262 assert(ClausesWithImplicit.empty() && 3263 "No clauses are allowed for 'omp master' directive"); 3264 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3265 break; 3266 case OMPD_critical: 3267 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3268 StartLoc, EndLoc); 3269 break; 3270 case OMPD_parallel_for: 3271 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3272 EndLoc, VarsWithInheritedDSA); 3273 AllowedNameModifiers.push_back(OMPD_parallel); 3274 break; 3275 case OMPD_parallel_for_simd: 3276 Res = ActOnOpenMPParallelForSimdDirective( 3277 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3278 AllowedNameModifiers.push_back(OMPD_parallel); 3279 break; 3280 case OMPD_parallel_sections: 3281 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3282 StartLoc, EndLoc); 3283 AllowedNameModifiers.push_back(OMPD_parallel); 3284 break; 3285 case OMPD_task: 3286 Res = 3287 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3288 AllowedNameModifiers.push_back(OMPD_task); 3289 break; 3290 case OMPD_taskyield: 3291 assert(ClausesWithImplicit.empty() && 3292 "No clauses are allowed for 'omp taskyield' directive"); 3293 assert(AStmt == nullptr && 3294 "No associated statement allowed for 'omp taskyield' directive"); 3295 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3296 break; 3297 case OMPD_barrier: 3298 assert(ClausesWithImplicit.empty() && 3299 "No clauses are allowed for 'omp barrier' directive"); 3300 assert(AStmt == nullptr && 3301 "No associated statement allowed for 'omp barrier' directive"); 3302 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3303 break; 3304 case OMPD_taskwait: 3305 assert(ClausesWithImplicit.empty() && 3306 "No clauses are allowed for 'omp taskwait' directive"); 3307 assert(AStmt == nullptr && 3308 "No associated statement allowed for 'omp taskwait' directive"); 3309 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3310 break; 3311 case OMPD_taskgroup: 3312 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 3313 EndLoc); 3314 break; 3315 case OMPD_flush: 3316 assert(AStmt == nullptr && 3317 "No associated statement allowed for 'omp flush' directive"); 3318 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3319 break; 3320 case OMPD_ordered: 3321 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3322 EndLoc); 3323 break; 3324 case OMPD_atomic: 3325 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3326 EndLoc); 3327 break; 3328 case OMPD_teams: 3329 Res = 3330 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3331 break; 3332 case OMPD_target: 3333 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3334 EndLoc); 3335 AllowedNameModifiers.push_back(OMPD_target); 3336 break; 3337 case OMPD_target_parallel: 3338 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3339 StartLoc, EndLoc); 3340 AllowedNameModifiers.push_back(OMPD_target); 3341 AllowedNameModifiers.push_back(OMPD_parallel); 3342 break; 3343 case OMPD_target_parallel_for: 3344 Res = ActOnOpenMPTargetParallelForDirective( 3345 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3346 AllowedNameModifiers.push_back(OMPD_target); 3347 AllowedNameModifiers.push_back(OMPD_parallel); 3348 break; 3349 case OMPD_cancellation_point: 3350 assert(ClausesWithImplicit.empty() && 3351 "No clauses are allowed for 'omp cancellation point' directive"); 3352 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3353 "cancellation point' directive"); 3354 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3355 break; 3356 case OMPD_cancel: 3357 assert(AStmt == nullptr && 3358 "No associated statement allowed for 'omp cancel' directive"); 3359 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3360 CancelRegion); 3361 AllowedNameModifiers.push_back(OMPD_cancel); 3362 break; 3363 case OMPD_target_data: 3364 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3365 EndLoc); 3366 AllowedNameModifiers.push_back(OMPD_target_data); 3367 break; 3368 case OMPD_target_enter_data: 3369 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3370 EndLoc, AStmt); 3371 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3372 break; 3373 case OMPD_target_exit_data: 3374 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3375 EndLoc, AStmt); 3376 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3377 break; 3378 case OMPD_taskloop: 3379 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3380 EndLoc, VarsWithInheritedDSA); 3381 AllowedNameModifiers.push_back(OMPD_taskloop); 3382 break; 3383 case OMPD_taskloop_simd: 3384 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3385 EndLoc, VarsWithInheritedDSA); 3386 AllowedNameModifiers.push_back(OMPD_taskloop); 3387 break; 3388 case OMPD_distribute: 3389 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3390 EndLoc, VarsWithInheritedDSA); 3391 break; 3392 case OMPD_target_update: 3393 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 3394 EndLoc, AStmt); 3395 AllowedNameModifiers.push_back(OMPD_target_update); 3396 break; 3397 case OMPD_distribute_parallel_for: 3398 Res = ActOnOpenMPDistributeParallelForDirective( 3399 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3400 AllowedNameModifiers.push_back(OMPD_parallel); 3401 break; 3402 case OMPD_distribute_parallel_for_simd: 3403 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3404 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3405 AllowedNameModifiers.push_back(OMPD_parallel); 3406 break; 3407 case OMPD_distribute_simd: 3408 Res = ActOnOpenMPDistributeSimdDirective( 3409 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3410 break; 3411 case OMPD_target_parallel_for_simd: 3412 Res = ActOnOpenMPTargetParallelForSimdDirective( 3413 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3414 AllowedNameModifiers.push_back(OMPD_target); 3415 AllowedNameModifiers.push_back(OMPD_parallel); 3416 break; 3417 case OMPD_target_simd: 3418 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3419 EndLoc, VarsWithInheritedDSA); 3420 AllowedNameModifiers.push_back(OMPD_target); 3421 break; 3422 case OMPD_teams_distribute: 3423 Res = ActOnOpenMPTeamsDistributeDirective( 3424 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3425 break; 3426 case OMPD_teams_distribute_simd: 3427 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3428 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3429 break; 3430 case OMPD_teams_distribute_parallel_for_simd: 3431 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3432 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3433 AllowedNameModifiers.push_back(OMPD_parallel); 3434 break; 3435 case OMPD_teams_distribute_parallel_for: 3436 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3437 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3438 AllowedNameModifiers.push_back(OMPD_parallel); 3439 break; 3440 case OMPD_target_teams: 3441 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3442 EndLoc); 3443 AllowedNameModifiers.push_back(OMPD_target); 3444 break; 3445 case OMPD_target_teams_distribute: 3446 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3447 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3448 AllowedNameModifiers.push_back(OMPD_target); 3449 break; 3450 case OMPD_target_teams_distribute_parallel_for: 3451 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3452 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3453 AllowedNameModifiers.push_back(OMPD_target); 3454 AllowedNameModifiers.push_back(OMPD_parallel); 3455 break; 3456 case OMPD_target_teams_distribute_parallel_for_simd: 3457 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3458 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3459 AllowedNameModifiers.push_back(OMPD_target); 3460 AllowedNameModifiers.push_back(OMPD_parallel); 3461 break; 3462 case OMPD_target_teams_distribute_simd: 3463 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3464 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3465 AllowedNameModifiers.push_back(OMPD_target); 3466 break; 3467 case OMPD_declare_target: 3468 case OMPD_end_declare_target: 3469 case OMPD_threadprivate: 3470 case OMPD_declare_reduction: 3471 case OMPD_declare_simd: 3472 case OMPD_requires: 3473 llvm_unreachable("OpenMP Directive is not allowed"); 3474 case OMPD_unknown: 3475 llvm_unreachable("Unknown OpenMP directive"); 3476 } 3477 3478 for (const auto &P : VarsWithInheritedDSA) { 3479 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3480 << P.first << P.second->getSourceRange(); 3481 } 3482 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3483 3484 if (!AllowedNameModifiers.empty()) 3485 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3486 ErrorFound; 3487 3488 if (ErrorFound) 3489 return StmtError(); 3490 return Res; 3491 } 3492 3493 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3494 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3495 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3496 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3497 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3498 assert(Aligneds.size() == Alignments.size()); 3499 assert(Linears.size() == LinModifiers.size()); 3500 assert(Linears.size() == Steps.size()); 3501 if (!DG || DG.get().isNull()) 3502 return DeclGroupPtrTy(); 3503 3504 if (!DG.get().isSingleDecl()) { 3505 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3506 return DG; 3507 } 3508 Decl *ADecl = DG.get().getSingleDecl(); 3509 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3510 ADecl = FTD->getTemplatedDecl(); 3511 3512 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3513 if (!FD) { 3514 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3515 return DeclGroupPtrTy(); 3516 } 3517 3518 // OpenMP [2.8.2, declare simd construct, Description] 3519 // The parameter of the simdlen clause must be a constant positive integer 3520 // expression. 3521 ExprResult SL; 3522 if (Simdlen) 3523 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3524 // OpenMP [2.8.2, declare simd construct, Description] 3525 // The special this pointer can be used as if was one of the arguments to the 3526 // function in any of the linear, aligned, or uniform clauses. 3527 // The uniform clause declares one or more arguments to have an invariant 3528 // value for all concurrent invocations of the function in the execution of a 3529 // single SIMD loop. 3530 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 3531 const Expr *UniformedLinearThis = nullptr; 3532 for (const Expr *E : Uniforms) { 3533 E = E->IgnoreParenImpCasts(); 3534 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3535 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3536 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3537 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3538 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3539 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 3540 continue; 3541 } 3542 if (isa<CXXThisExpr>(E)) { 3543 UniformedLinearThis = E; 3544 continue; 3545 } 3546 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3547 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3548 } 3549 // OpenMP [2.8.2, declare simd construct, Description] 3550 // The aligned clause declares that the object to which each list item points 3551 // is aligned to the number of bytes expressed in the optional parameter of 3552 // the aligned clause. 3553 // The special this pointer can be used as if was one of the arguments to the 3554 // function in any of the linear, aligned, or uniform clauses. 3555 // The type of list items appearing in the aligned clause must be array, 3556 // pointer, reference to array, or reference to pointer. 3557 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 3558 const Expr *AlignedThis = nullptr; 3559 for (const Expr *E : Aligneds) { 3560 E = E->IgnoreParenImpCasts(); 3561 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3562 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3563 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3564 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3565 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3566 ->getCanonicalDecl() == CanonPVD) { 3567 // OpenMP [2.8.1, simd construct, Restrictions] 3568 // A list-item cannot appear in more than one aligned clause. 3569 if (AlignedArgs.count(CanonPVD) > 0) { 3570 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3571 << 1 << E->getSourceRange(); 3572 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3573 diag::note_omp_explicit_dsa) 3574 << getOpenMPClauseName(OMPC_aligned); 3575 continue; 3576 } 3577 AlignedArgs[CanonPVD] = E; 3578 QualType QTy = PVD->getType() 3579 .getNonReferenceType() 3580 .getUnqualifiedType() 3581 .getCanonicalType(); 3582 const Type *Ty = QTy.getTypePtrOrNull(); 3583 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3584 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3585 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3586 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3587 } 3588 continue; 3589 } 3590 } 3591 if (isa<CXXThisExpr>(E)) { 3592 if (AlignedThis) { 3593 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3594 << 2 << E->getSourceRange(); 3595 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3596 << getOpenMPClauseName(OMPC_aligned); 3597 } 3598 AlignedThis = E; 3599 continue; 3600 } 3601 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3602 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3603 } 3604 // The optional parameter of the aligned clause, alignment, must be a constant 3605 // positive integer expression. If no optional parameter is specified, 3606 // implementation-defined default alignments for SIMD instructions on the 3607 // target platforms are assumed. 3608 SmallVector<const Expr *, 4> NewAligns; 3609 for (Expr *E : Alignments) { 3610 ExprResult Align; 3611 if (E) 3612 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3613 NewAligns.push_back(Align.get()); 3614 } 3615 // OpenMP [2.8.2, declare simd construct, Description] 3616 // The linear clause declares one or more list items to be private to a SIMD 3617 // lane and to have a linear relationship with respect to the iteration space 3618 // of a loop. 3619 // The special this pointer can be used as if was one of the arguments to the 3620 // function in any of the linear, aligned, or uniform clauses. 3621 // When a linear-step expression is specified in a linear clause it must be 3622 // either a constant integer expression or an integer-typed parameter that is 3623 // specified in a uniform clause on the directive. 3624 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 3625 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3626 auto MI = LinModifiers.begin(); 3627 for (const Expr *E : Linears) { 3628 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3629 ++MI; 3630 E = E->IgnoreParenImpCasts(); 3631 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3632 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3633 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3634 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3635 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3636 ->getCanonicalDecl() == CanonPVD) { 3637 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3638 // A list-item cannot appear in more than one linear clause. 3639 if (LinearArgs.count(CanonPVD) > 0) { 3640 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3641 << getOpenMPClauseName(OMPC_linear) 3642 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3643 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3644 diag::note_omp_explicit_dsa) 3645 << getOpenMPClauseName(OMPC_linear); 3646 continue; 3647 } 3648 // Each argument can appear in at most one uniform or linear clause. 3649 if (UniformedArgs.count(CanonPVD) > 0) { 3650 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3651 << getOpenMPClauseName(OMPC_linear) 3652 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3653 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3654 diag::note_omp_explicit_dsa) 3655 << getOpenMPClauseName(OMPC_uniform); 3656 continue; 3657 } 3658 LinearArgs[CanonPVD] = E; 3659 if (E->isValueDependent() || E->isTypeDependent() || 3660 E->isInstantiationDependent() || 3661 E->containsUnexpandedParameterPack()) 3662 continue; 3663 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 3664 PVD->getOriginalType()); 3665 continue; 3666 } 3667 } 3668 if (isa<CXXThisExpr>(E)) { 3669 if (UniformedLinearThis) { 3670 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3671 << getOpenMPClauseName(OMPC_linear) 3672 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 3673 << E->getSourceRange(); 3674 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 3675 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 3676 : OMPC_linear); 3677 continue; 3678 } 3679 UniformedLinearThis = E; 3680 if (E->isValueDependent() || E->isTypeDependent() || 3681 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 3682 continue; 3683 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 3684 E->getType()); 3685 continue; 3686 } 3687 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3688 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3689 } 3690 Expr *Step = nullptr; 3691 Expr *NewStep = nullptr; 3692 SmallVector<Expr *, 4> NewSteps; 3693 for (Expr *E : Steps) { 3694 // Skip the same step expression, it was checked already. 3695 if (Step == E || !E) { 3696 NewSteps.push_back(E ? NewStep : nullptr); 3697 continue; 3698 } 3699 Step = E; 3700 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 3701 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3702 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3703 if (UniformedArgs.count(CanonPVD) == 0) { 3704 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 3705 << Step->getSourceRange(); 3706 } else if (E->isValueDependent() || E->isTypeDependent() || 3707 E->isInstantiationDependent() || 3708 E->containsUnexpandedParameterPack() || 3709 CanonPVD->getType()->hasIntegerRepresentation()) { 3710 NewSteps.push_back(Step); 3711 } else { 3712 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 3713 << Step->getSourceRange(); 3714 } 3715 continue; 3716 } 3717 NewStep = Step; 3718 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 3719 !Step->isInstantiationDependent() && 3720 !Step->containsUnexpandedParameterPack()) { 3721 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 3722 .get(); 3723 if (NewStep) 3724 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 3725 } 3726 NewSteps.push_back(NewStep); 3727 } 3728 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3729 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 3730 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 3731 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 3732 const_cast<Expr **>(Linears.data()), Linears.size(), 3733 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 3734 NewSteps.data(), NewSteps.size(), SR); 3735 ADecl->addAttr(NewAttr); 3736 return ConvertDeclToDeclGroup(ADecl); 3737 } 3738 3739 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3740 Stmt *AStmt, 3741 SourceLocation StartLoc, 3742 SourceLocation EndLoc) { 3743 if (!AStmt) 3744 return StmtError(); 3745 3746 auto *CS = cast<CapturedStmt>(AStmt); 3747 // 1.2.2 OpenMP Language Terminology 3748 // Structured block - An executable statement with a single entry at the 3749 // top and a single exit at the bottom. 3750 // The point of exit cannot be a branch out of the structured block. 3751 // longjmp() and throw() must not violate the entry/exit criteria. 3752 CS->getCapturedDecl()->setNothrow(); 3753 3754 setFunctionHasBranchProtectedScope(); 3755 3756 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3757 DSAStack->isCancelRegion()); 3758 } 3759 3760 namespace { 3761 /// Helper class for checking canonical form of the OpenMP loops and 3762 /// extracting iteration space of each loop in the loop nest, that will be used 3763 /// for IR generation. 3764 class OpenMPIterationSpaceChecker { 3765 /// Reference to Sema. 3766 Sema &SemaRef; 3767 /// A location for diagnostics (when there is no some better location). 3768 SourceLocation DefaultLoc; 3769 /// A location for diagnostics (when increment is not compatible). 3770 SourceLocation ConditionLoc; 3771 /// A source location for referring to loop init later. 3772 SourceRange InitSrcRange; 3773 /// A source location for referring to condition later. 3774 SourceRange ConditionSrcRange; 3775 /// A source location for referring to increment later. 3776 SourceRange IncrementSrcRange; 3777 /// Loop variable. 3778 ValueDecl *LCDecl = nullptr; 3779 /// Reference to loop variable. 3780 Expr *LCRef = nullptr; 3781 /// Lower bound (initializer for the var). 3782 Expr *LB = nullptr; 3783 /// Upper bound. 3784 Expr *UB = nullptr; 3785 /// Loop step (increment). 3786 Expr *Step = nullptr; 3787 /// This flag is true when condition is one of: 3788 /// Var < UB 3789 /// Var <= UB 3790 /// UB > Var 3791 /// UB >= Var 3792 bool TestIsLessOp = false; 3793 /// This flag is true when condition is strict ( < or > ). 3794 bool TestIsStrictOp = false; 3795 /// This flag is true when step is subtracted on each iteration. 3796 bool SubtractStep = false; 3797 3798 public: 3799 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3800 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3801 /// Check init-expr for canonical loop form and save loop counter 3802 /// variable - #Var and its initialization value - #LB. 3803 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 3804 /// Check test-expr for canonical form, save upper-bound (#UB), flags 3805 /// for less/greater and for strict/non-strict comparison. 3806 bool checkAndSetCond(Expr *S); 3807 /// Check incr-expr for canonical loop form and return true if it 3808 /// does not conform, otherwise save loop step (#Step). 3809 bool checkAndSetInc(Expr *S); 3810 /// Return the loop counter variable. 3811 ValueDecl *getLoopDecl() const { return LCDecl; } 3812 /// Return the reference expression to loop counter variable. 3813 Expr *getLoopDeclRefExpr() const { return LCRef; } 3814 /// Source range of the loop init. 3815 SourceRange getInitSrcRange() const { return InitSrcRange; } 3816 /// Source range of the loop condition. 3817 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 3818 /// Source range of the loop increment. 3819 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 3820 /// True if the step should be subtracted. 3821 bool shouldSubtractStep() const { return SubtractStep; } 3822 /// Build the expression to calculate the number of iterations. 3823 Expr *buildNumIterations( 3824 Scope *S, const bool LimitedType, 3825 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 3826 /// Build the precondition expression for the loops. 3827 Expr * 3828 buildPreCond(Scope *S, Expr *Cond, 3829 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 3830 /// Build reference expression to the counter be used for codegen. 3831 DeclRefExpr * 3832 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 3833 DSAStackTy &DSA) const; 3834 /// Build reference expression to the private counter be used for 3835 /// codegen. 3836 Expr *buildPrivateCounterVar() const; 3837 /// Build initialization of the counter be used for codegen. 3838 Expr *buildCounterInit() const; 3839 /// Build step of the counter be used for codegen. 3840 Expr *buildCounterStep() const; 3841 /// Build loop data with counter value for depend clauses in ordered 3842 /// directives. 3843 Expr * 3844 buildOrderedLoopData(Scope *S, Expr *Counter, 3845 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 3846 SourceLocation Loc, Expr *Inc = nullptr, 3847 OverloadedOperatorKind OOK = OO_Amp); 3848 /// Return true if any expression is dependent. 3849 bool dependent() const; 3850 3851 private: 3852 /// Check the right-hand side of an assignment in the increment 3853 /// expression. 3854 bool checkAndSetIncRHS(Expr *RHS); 3855 /// Helper to set loop counter variable and its initializer. 3856 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3857 /// Helper to set upper bound. 3858 bool setUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3859 SourceLocation SL); 3860 /// Helper to set loop increment. 3861 bool setStep(Expr *NewStep, bool Subtract); 3862 }; 3863 3864 bool OpenMPIterationSpaceChecker::dependent() const { 3865 if (!LCDecl) { 3866 assert(!LB && !UB && !Step); 3867 return false; 3868 } 3869 return LCDecl->getType()->isDependentType() || 3870 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3871 (Step && Step->isValueDependent()); 3872 } 3873 3874 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 3875 Expr *NewLCRefExpr, 3876 Expr *NewLB) { 3877 // State consistency checking to ensure correct usage. 3878 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3879 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3880 if (!NewLCDecl || !NewLB) 3881 return true; 3882 LCDecl = getCanonicalDecl(NewLCDecl); 3883 LCRef = NewLCRefExpr; 3884 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3885 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3886 if ((Ctor->isCopyOrMoveConstructor() || 3887 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3888 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3889 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3890 LB = NewLB; 3891 return false; 3892 } 3893 3894 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, bool LessOp, bool StrictOp, 3895 SourceRange SR, SourceLocation SL) { 3896 // State consistency checking to ensure correct usage. 3897 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3898 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3899 if (!NewUB) 3900 return true; 3901 UB = NewUB; 3902 TestIsLessOp = LessOp; 3903 TestIsStrictOp = StrictOp; 3904 ConditionSrcRange = SR; 3905 ConditionLoc = SL; 3906 return false; 3907 } 3908 3909 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 3910 // State consistency checking to ensure correct usage. 3911 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3912 if (!NewStep) 3913 return true; 3914 if (!NewStep->isValueDependent()) { 3915 // Check that the step is integer expression. 3916 SourceLocation StepLoc = NewStep->getBeginLoc(); 3917 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 3918 StepLoc, getExprAsWritten(NewStep)); 3919 if (Val.isInvalid()) 3920 return true; 3921 NewStep = Val.get(); 3922 3923 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3924 // If test-expr is of form var relational-op b and relational-op is < or 3925 // <= then incr-expr must cause var to increase on each iteration of the 3926 // loop. If test-expr is of form var relational-op b and relational-op is 3927 // > or >= then incr-expr must cause var to decrease on each iteration of 3928 // the loop. 3929 // If test-expr is of form b relational-op var and relational-op is < or 3930 // <= then incr-expr must cause var to decrease on each iteration of the 3931 // loop. If test-expr is of form b relational-op var and relational-op is 3932 // > or >= then incr-expr must cause var to increase on each iteration of 3933 // the loop. 3934 llvm::APSInt Result; 3935 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3936 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3937 bool IsConstNeg = 3938 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3939 bool IsConstPos = 3940 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3941 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3942 if (UB && (IsConstZero || 3943 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3944 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3945 SemaRef.Diag(NewStep->getExprLoc(), 3946 diag::err_omp_loop_incr_not_compatible) 3947 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3948 SemaRef.Diag(ConditionLoc, 3949 diag::note_omp_loop_cond_requres_compatible_incr) 3950 << TestIsLessOp << ConditionSrcRange; 3951 return true; 3952 } 3953 if (TestIsLessOp == Subtract) { 3954 NewStep = 3955 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 3956 .get(); 3957 Subtract = !Subtract; 3958 } 3959 } 3960 3961 Step = NewStep; 3962 SubtractStep = Subtract; 3963 return false; 3964 } 3965 3966 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 3967 // Check init-expr for canonical loop form and save loop counter 3968 // variable - #Var and its initialization value - #LB. 3969 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3970 // var = lb 3971 // integer-type var = lb 3972 // random-access-iterator-type var = lb 3973 // pointer-type var = lb 3974 // 3975 if (!S) { 3976 if (EmitDiags) { 3977 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3978 } 3979 return true; 3980 } 3981 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3982 if (!ExprTemp->cleanupsHaveSideEffects()) 3983 S = ExprTemp->getSubExpr(); 3984 3985 InitSrcRange = S->getSourceRange(); 3986 if (Expr *E = dyn_cast<Expr>(S)) 3987 S = E->IgnoreParens(); 3988 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3989 if (BO->getOpcode() == BO_Assign) { 3990 Expr *LHS = BO->getLHS()->IgnoreParens(); 3991 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3992 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3993 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3994 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3995 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3996 } 3997 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3998 if (ME->isArrow() && 3999 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4000 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4001 } 4002 } 4003 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4004 if (DS->isSingleDecl()) { 4005 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4006 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4007 // Accept non-canonical init form here but emit ext. warning. 4008 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4009 SemaRef.Diag(S->getBeginLoc(), 4010 diag::ext_omp_loop_not_canonical_init) 4011 << S->getSourceRange(); 4012 return setLCDeclAndLB( 4013 Var, 4014 buildDeclRefExpr(SemaRef, Var, 4015 Var->getType().getNonReferenceType(), 4016 DS->getBeginLoc()), 4017 Var->getInit()); 4018 } 4019 } 4020 } 4021 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4022 if (CE->getOperator() == OO_Equal) { 4023 Expr *LHS = CE->getArg(0); 4024 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4025 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4026 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4027 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4028 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 4029 } 4030 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4031 if (ME->isArrow() && 4032 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4033 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4034 } 4035 } 4036 } 4037 4038 if (dependent() || SemaRef.CurContext->isDependentContext()) 4039 return false; 4040 if (EmitDiags) { 4041 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 4042 << S->getSourceRange(); 4043 } 4044 return true; 4045 } 4046 4047 /// Ignore parenthesizes, implicit casts, copy constructor and return the 4048 /// variable (which may be the loop variable) if possible. 4049 static const ValueDecl *getInitLCDecl(const Expr *E) { 4050 if (!E) 4051 return nullptr; 4052 E = getExprAsWritten(E); 4053 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 4054 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4055 if ((Ctor->isCopyOrMoveConstructor() || 4056 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4057 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4058 E = CE->getArg(0)->IgnoreParenImpCasts(); 4059 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 4060 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 4061 return getCanonicalDecl(VD); 4062 } 4063 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 4064 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4065 return getCanonicalDecl(ME->getMemberDecl()); 4066 return nullptr; 4067 } 4068 4069 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 4070 // Check test-expr for canonical form, save upper-bound UB, flags for 4071 // less/greater and for strict/non-strict comparison. 4072 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4073 // var relational-op b 4074 // b relational-op var 4075 // 4076 if (!S) { 4077 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 4078 return true; 4079 } 4080 S = getExprAsWritten(S); 4081 SourceLocation CondLoc = S->getBeginLoc(); 4082 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4083 if (BO->isRelationalOp()) { 4084 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4085 return setUB(BO->getRHS(), 4086 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4087 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4088 BO->getSourceRange(), BO->getOperatorLoc()); 4089 if (getInitLCDecl(BO->getRHS()) == LCDecl) 4090 return setUB(BO->getLHS(), 4091 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4092 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4093 BO->getSourceRange(), BO->getOperatorLoc()); 4094 } 4095 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4096 if (CE->getNumArgs() == 2) { 4097 auto Op = CE->getOperator(); 4098 switch (Op) { 4099 case OO_Greater: 4100 case OO_GreaterEqual: 4101 case OO_Less: 4102 case OO_LessEqual: 4103 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4104 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4105 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4106 CE->getOperatorLoc()); 4107 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 4108 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4109 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4110 CE->getOperatorLoc()); 4111 break; 4112 default: 4113 break; 4114 } 4115 } 4116 } 4117 if (dependent() || SemaRef.CurContext->isDependentContext()) 4118 return false; 4119 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4120 << S->getSourceRange() << LCDecl; 4121 return true; 4122 } 4123 4124 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 4125 // RHS of canonical loop form increment can be: 4126 // var + incr 4127 // incr + var 4128 // var - incr 4129 // 4130 RHS = RHS->IgnoreParenImpCasts(); 4131 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 4132 if (BO->isAdditiveOp()) { 4133 bool IsAdd = BO->getOpcode() == BO_Add; 4134 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4135 return setStep(BO->getRHS(), !IsAdd); 4136 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 4137 return setStep(BO->getLHS(), /*Subtract=*/false); 4138 } 4139 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 4140 bool IsAdd = CE->getOperator() == OO_Plus; 4141 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 4142 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4143 return setStep(CE->getArg(1), !IsAdd); 4144 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 4145 return setStep(CE->getArg(0), /*Subtract=*/false); 4146 } 4147 } 4148 if (dependent() || SemaRef.CurContext->isDependentContext()) 4149 return false; 4150 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4151 << RHS->getSourceRange() << LCDecl; 4152 return true; 4153 } 4154 4155 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 4156 // Check incr-expr for canonical loop form and return true if it 4157 // does not conform. 4158 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4159 // ++var 4160 // var++ 4161 // --var 4162 // var-- 4163 // var += incr 4164 // var -= incr 4165 // var = var + incr 4166 // var = incr + var 4167 // var = var - incr 4168 // 4169 if (!S) { 4170 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 4171 return true; 4172 } 4173 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4174 if (!ExprTemp->cleanupsHaveSideEffects()) 4175 S = ExprTemp->getSubExpr(); 4176 4177 IncrementSrcRange = S->getSourceRange(); 4178 S = S->IgnoreParens(); 4179 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 4180 if (UO->isIncrementDecrementOp() && 4181 getInitLCDecl(UO->getSubExpr()) == LCDecl) 4182 return setStep(SemaRef 4183 .ActOnIntegerConstant(UO->getBeginLoc(), 4184 (UO->isDecrementOp() ? -1 : 1)) 4185 .get(), 4186 /*Subtract=*/false); 4187 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4188 switch (BO->getOpcode()) { 4189 case BO_AddAssign: 4190 case BO_SubAssign: 4191 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4192 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4193 break; 4194 case BO_Assign: 4195 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4196 return checkAndSetIncRHS(BO->getRHS()); 4197 break; 4198 default: 4199 break; 4200 } 4201 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4202 switch (CE->getOperator()) { 4203 case OO_PlusPlus: 4204 case OO_MinusMinus: 4205 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4206 return setStep(SemaRef 4207 .ActOnIntegerConstant( 4208 CE->getBeginLoc(), 4209 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 4210 .get(), 4211 /*Subtract=*/false); 4212 break; 4213 case OO_PlusEqual: 4214 case OO_MinusEqual: 4215 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4216 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4217 break; 4218 case OO_Equal: 4219 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4220 return checkAndSetIncRHS(CE->getArg(1)); 4221 break; 4222 default: 4223 break; 4224 } 4225 } 4226 if (dependent() || SemaRef.CurContext->isDependentContext()) 4227 return false; 4228 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4229 << S->getSourceRange() << LCDecl; 4230 return true; 4231 } 4232 4233 static ExprResult 4234 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4235 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4236 if (SemaRef.CurContext->isDependentContext()) 4237 return ExprResult(Capture); 4238 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4239 return SemaRef.PerformImplicitConversion( 4240 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4241 /*AllowExplicit=*/true); 4242 auto I = Captures.find(Capture); 4243 if (I != Captures.end()) 4244 return buildCapture(SemaRef, Capture, I->second); 4245 DeclRefExpr *Ref = nullptr; 4246 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4247 Captures[Capture] = Ref; 4248 return Res; 4249 } 4250 4251 /// Build the expression to calculate the number of iterations. 4252 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 4253 Scope *S, const bool LimitedType, 4254 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4255 ExprResult Diff; 4256 QualType VarType = LCDecl->getType().getNonReferenceType(); 4257 if (VarType->isIntegerType() || VarType->isPointerType() || 4258 SemaRef.getLangOpts().CPlusPlus) { 4259 // Upper - Lower 4260 Expr *UBExpr = TestIsLessOp ? UB : LB; 4261 Expr *LBExpr = TestIsLessOp ? LB : UB; 4262 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4263 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4264 if (!Upper || !Lower) 4265 return nullptr; 4266 4267 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4268 4269 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4270 // BuildBinOp already emitted error, this one is to point user to upper 4271 // and lower bound, and to tell what is passed to 'operator-'. 4272 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4273 << Upper->getSourceRange() << Lower->getSourceRange(); 4274 return nullptr; 4275 } 4276 } 4277 4278 if (!Diff.isUsable()) 4279 return nullptr; 4280 4281 // Upper - Lower [- 1] 4282 if (TestIsStrictOp) 4283 Diff = SemaRef.BuildBinOp( 4284 S, DefaultLoc, BO_Sub, Diff.get(), 4285 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4286 if (!Diff.isUsable()) 4287 return nullptr; 4288 4289 // Upper - Lower [- 1] + Step 4290 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4291 if (!NewStep.isUsable()) 4292 return nullptr; 4293 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4294 if (!Diff.isUsable()) 4295 return nullptr; 4296 4297 // Parentheses (for dumping/debugging purposes only). 4298 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4299 if (!Diff.isUsable()) 4300 return nullptr; 4301 4302 // (Upper - Lower [- 1] + Step) / Step 4303 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4304 if (!Diff.isUsable()) 4305 return nullptr; 4306 4307 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4308 QualType Type = Diff.get()->getType(); 4309 ASTContext &C = SemaRef.Context; 4310 bool UseVarType = VarType->hasIntegerRepresentation() && 4311 C.getTypeSize(Type) > C.getTypeSize(VarType); 4312 if (!Type->isIntegerType() || UseVarType) { 4313 unsigned NewSize = 4314 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4315 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4316 : Type->hasSignedIntegerRepresentation(); 4317 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4318 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4319 Diff = SemaRef.PerformImplicitConversion( 4320 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4321 if (!Diff.isUsable()) 4322 return nullptr; 4323 } 4324 } 4325 if (LimitedType) { 4326 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4327 if (NewSize != C.getTypeSize(Type)) { 4328 if (NewSize < C.getTypeSize(Type)) { 4329 assert(NewSize == 64 && "incorrect loop var size"); 4330 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4331 << InitSrcRange << ConditionSrcRange; 4332 } 4333 QualType NewType = C.getIntTypeForBitwidth( 4334 NewSize, Type->hasSignedIntegerRepresentation() || 4335 C.getTypeSize(Type) < NewSize); 4336 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4337 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4338 Sema::AA_Converting, true); 4339 if (!Diff.isUsable()) 4340 return nullptr; 4341 } 4342 } 4343 } 4344 4345 return Diff.get(); 4346 } 4347 4348 Expr *OpenMPIterationSpaceChecker::buildPreCond( 4349 Scope *S, Expr *Cond, 4350 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4351 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4352 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4353 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4354 4355 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 4356 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 4357 if (!NewLB.isUsable() || !NewUB.isUsable()) 4358 return nullptr; 4359 4360 ExprResult CondExpr = 4361 SemaRef.BuildBinOp(S, DefaultLoc, 4362 TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 4363 : (TestIsStrictOp ? BO_GT : BO_GE), 4364 NewLB.get(), NewUB.get()); 4365 if (CondExpr.isUsable()) { 4366 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4367 SemaRef.Context.BoolTy)) 4368 CondExpr = SemaRef.PerformImplicitConversion( 4369 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4370 /*AllowExplicit=*/true); 4371 } 4372 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4373 // Otherwise use original loop conditon and evaluate it in runtime. 4374 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4375 } 4376 4377 /// Build reference expression to the counter be used for codegen. 4378 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 4379 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4380 DSAStackTy &DSA) const { 4381 auto *VD = dyn_cast<VarDecl>(LCDecl); 4382 if (!VD) { 4383 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 4384 DeclRefExpr *Ref = buildDeclRefExpr( 4385 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4386 const DSAStackTy::DSAVarData Data = 4387 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4388 // If the loop control decl is explicitly marked as private, do not mark it 4389 // as captured again. 4390 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4391 Captures.insert(std::make_pair(LCRef, Ref)); 4392 return Ref; 4393 } 4394 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 4395 DefaultLoc); 4396 } 4397 4398 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 4399 if (LCDecl && !LCDecl->isInvalidDecl()) { 4400 QualType Type = LCDecl->getType().getNonReferenceType(); 4401 VarDecl *PrivateVar = buildVarDecl( 4402 SemaRef, DefaultLoc, Type, LCDecl->getName(), 4403 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 4404 isa<VarDecl>(LCDecl) 4405 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 4406 : nullptr); 4407 if (PrivateVar->isInvalidDecl()) 4408 return nullptr; 4409 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4410 } 4411 return nullptr; 4412 } 4413 4414 /// Build initialization of the counter to be used for codegen. 4415 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 4416 4417 /// Build step of the counter be used for codegen. 4418 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 4419 4420 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 4421 Scope *S, Expr *Counter, 4422 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 4423 Expr *Inc, OverloadedOperatorKind OOK) { 4424 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 4425 if (!Cnt) 4426 return nullptr; 4427 if (Inc) { 4428 assert((OOK == OO_Plus || OOK == OO_Minus) && 4429 "Expected only + or - operations for depend clauses."); 4430 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 4431 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 4432 if (!Cnt) 4433 return nullptr; 4434 } 4435 ExprResult Diff; 4436 QualType VarType = LCDecl->getType().getNonReferenceType(); 4437 if (VarType->isIntegerType() || VarType->isPointerType() || 4438 SemaRef.getLangOpts().CPlusPlus) { 4439 // Upper - Lower 4440 Expr *Upper = 4441 TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get(); 4442 Expr *Lower = 4443 TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; 4444 if (!Upper || !Lower) 4445 return nullptr; 4446 4447 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4448 4449 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4450 // BuildBinOp already emitted error, this one is to point user to upper 4451 // and lower bound, and to tell what is passed to 'operator-'. 4452 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4453 << Upper->getSourceRange() << Lower->getSourceRange(); 4454 return nullptr; 4455 } 4456 } 4457 4458 if (!Diff.isUsable()) 4459 return nullptr; 4460 4461 // Parentheses (for dumping/debugging purposes only). 4462 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4463 if (!Diff.isUsable()) 4464 return nullptr; 4465 4466 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4467 if (!NewStep.isUsable()) 4468 return nullptr; 4469 // (Upper - Lower) / Step 4470 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4471 if (!Diff.isUsable()) 4472 return nullptr; 4473 4474 return Diff.get(); 4475 } 4476 4477 /// Iteration space of a single for loop. 4478 struct LoopIterationSpace final { 4479 /// Condition of the loop. 4480 Expr *PreCond = nullptr; 4481 /// This expression calculates the number of iterations in the loop. 4482 /// It is always possible to calculate it before starting the loop. 4483 Expr *NumIterations = nullptr; 4484 /// The loop counter variable. 4485 Expr *CounterVar = nullptr; 4486 /// Private loop counter variable. 4487 Expr *PrivateCounterVar = nullptr; 4488 /// This is initializer for the initial value of #CounterVar. 4489 Expr *CounterInit = nullptr; 4490 /// This is step for the #CounterVar used to generate its update: 4491 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4492 Expr *CounterStep = nullptr; 4493 /// Should step be subtracted? 4494 bool Subtract = false; 4495 /// Source range of the loop init. 4496 SourceRange InitSrcRange; 4497 /// Source range of the loop condition. 4498 SourceRange CondSrcRange; 4499 /// Source range of the loop increment. 4500 SourceRange IncSrcRange; 4501 }; 4502 4503 } // namespace 4504 4505 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4506 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4507 assert(Init && "Expected loop in canonical form."); 4508 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4509 if (AssociatedLoops > 0 && 4510 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4511 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4512 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 4513 if (ValueDecl *D = ISC.getLoopDecl()) { 4514 auto *VD = dyn_cast<VarDecl>(D); 4515 if (!VD) { 4516 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 4517 VD = Private; 4518 } else { 4519 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 4520 /*WithInit=*/false); 4521 VD = cast<VarDecl>(Ref->getDecl()); 4522 } 4523 } 4524 DSAStack->addLoopControlVariable(D, VD); 4525 } 4526 } 4527 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4528 } 4529 } 4530 4531 /// Called on a for stmt to check and extract its iteration space 4532 /// for further processing (such as collapsing). 4533 static bool checkOpenMPIterationSpace( 4534 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4535 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4536 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 4537 Expr *OrderedLoopCountExpr, 4538 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 4539 LoopIterationSpace &ResultIterSpace, 4540 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4541 // OpenMP [2.6, Canonical Loop Form] 4542 // for (init-expr; test-expr; incr-expr) structured-block 4543 auto *For = dyn_cast_or_null<ForStmt>(S); 4544 if (!For) { 4545 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 4546 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4547 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 4548 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4549 if (TotalNestedLoopCount > 1) { 4550 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4551 SemaRef.Diag(DSA.getConstructLoc(), 4552 diag::note_omp_collapse_ordered_expr) 4553 << 2 << CollapseLoopCountExpr->getSourceRange() 4554 << OrderedLoopCountExpr->getSourceRange(); 4555 else if (CollapseLoopCountExpr) 4556 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4557 diag::note_omp_collapse_ordered_expr) 4558 << 0 << CollapseLoopCountExpr->getSourceRange(); 4559 else 4560 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4561 diag::note_omp_collapse_ordered_expr) 4562 << 1 << OrderedLoopCountExpr->getSourceRange(); 4563 } 4564 return true; 4565 } 4566 assert(For->getBody()); 4567 4568 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4569 4570 // Check init. 4571 Stmt *Init = For->getInit(); 4572 if (ISC.checkAndSetInit(Init)) 4573 return true; 4574 4575 bool HasErrors = false; 4576 4577 // Check loop variable's type. 4578 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 4579 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 4580 4581 // OpenMP [2.6, Canonical Loop Form] 4582 // Var is one of the following: 4583 // A variable of signed or unsigned integer type. 4584 // For C++, a variable of a random access iterator type. 4585 // For C, a variable of a pointer type. 4586 QualType VarType = LCDecl->getType().getNonReferenceType(); 4587 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4588 !VarType->isPointerType() && 4589 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4590 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 4591 << SemaRef.getLangOpts().CPlusPlus; 4592 HasErrors = true; 4593 } 4594 4595 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4596 // a Construct 4597 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4598 // parallel for construct is (are) private. 4599 // The loop iteration variable in the associated for-loop of a simd 4600 // construct with just one associated for-loop is linear with a 4601 // constant-linear-step that is the increment of the associated for-loop. 4602 // Exclude loop var from the list of variables with implicitly defined data 4603 // sharing attributes. 4604 VarsWithImplicitDSA.erase(LCDecl); 4605 4606 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4607 // in a Construct, C/C++]. 4608 // The loop iteration variable in the associated for-loop of a simd 4609 // construct with just one associated for-loop may be listed in a linear 4610 // clause with a constant-linear-step that is the increment of the 4611 // associated for-loop. 4612 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4613 // parallel for construct may be listed in a private or lastprivate clause. 4614 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4615 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4616 // declared in the loop and it is predetermined as a private. 4617 OpenMPClauseKind PredeterminedCKind = 4618 isOpenMPSimdDirective(DKind) 4619 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4620 : OMPC_private; 4621 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4622 DVar.CKind != PredeterminedCKind) || 4623 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4624 isOpenMPDistributeDirective(DKind)) && 4625 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4626 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4627 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4628 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 4629 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4630 << getOpenMPClauseName(PredeterminedCKind); 4631 if (DVar.RefExpr == nullptr) 4632 DVar.CKind = PredeterminedCKind; 4633 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4634 HasErrors = true; 4635 } else if (LoopDeclRefExpr != nullptr) { 4636 // Make the loop iteration variable private (for worksharing constructs), 4637 // linear (for simd directives with the only one associated loop) or 4638 // lastprivate (for simd directives with several collapsed or ordered 4639 // loops). 4640 if (DVar.CKind == OMPC_unknown) 4641 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 4642 [](OpenMPDirectiveKind) -> bool { return true; }, 4643 /*FromParent=*/false); 4644 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4645 } 4646 4647 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4648 4649 // Check test-expr. 4650 HasErrors |= ISC.checkAndSetCond(For->getCond()); 4651 4652 // Check incr-expr. 4653 HasErrors |= ISC.checkAndSetInc(For->getInc()); 4654 } 4655 4656 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4657 return HasErrors; 4658 4659 // Build the loop's iteration space representation. 4660 ResultIterSpace.PreCond = 4661 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4662 ResultIterSpace.NumIterations = ISC.buildNumIterations( 4663 DSA.getCurScope(), 4664 (isOpenMPWorksharingDirective(DKind) || 4665 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4666 Captures); 4667 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 4668 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 4669 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 4670 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 4671 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 4672 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 4673 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 4674 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 4675 4676 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4677 ResultIterSpace.NumIterations == nullptr || 4678 ResultIterSpace.CounterVar == nullptr || 4679 ResultIterSpace.PrivateCounterVar == nullptr || 4680 ResultIterSpace.CounterInit == nullptr || 4681 ResultIterSpace.CounterStep == nullptr); 4682 if (!HasErrors && DSA.isOrderedRegion()) { 4683 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 4684 if (CurrentNestedLoopCount < 4685 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 4686 DSA.getOrderedRegionParam().second->setLoopNumIterations( 4687 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 4688 DSA.getOrderedRegionParam().second->setLoopCounter( 4689 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 4690 } 4691 } 4692 for (auto &Pair : DSA.getDoacrossDependClauses()) { 4693 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 4694 // Erroneous case - clause has some problems. 4695 continue; 4696 } 4697 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 4698 Pair.second.size() <= CurrentNestedLoopCount) { 4699 // Erroneous case - clause has some problems. 4700 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 4701 continue; 4702 } 4703 Expr *CntValue; 4704 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 4705 CntValue = ISC.buildOrderedLoopData( 4706 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 4707 Pair.first->getDependencyLoc()); 4708 else 4709 CntValue = ISC.buildOrderedLoopData( 4710 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 4711 Pair.first->getDependencyLoc(), 4712 Pair.second[CurrentNestedLoopCount].first, 4713 Pair.second[CurrentNestedLoopCount].second); 4714 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 4715 } 4716 } 4717 4718 return HasErrors; 4719 } 4720 4721 /// Build 'VarRef = Start. 4722 static ExprResult 4723 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4724 ExprResult Start, 4725 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4726 // Build 'VarRef = Start. 4727 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4728 if (!NewStart.isUsable()) 4729 return ExprError(); 4730 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4731 VarRef.get()->getType())) { 4732 NewStart = SemaRef.PerformImplicitConversion( 4733 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4734 /*AllowExplicit=*/true); 4735 if (!NewStart.isUsable()) 4736 return ExprError(); 4737 } 4738 4739 ExprResult Init = 4740 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4741 return Init; 4742 } 4743 4744 /// Build 'VarRef = Start + Iter * Step'. 4745 static ExprResult buildCounterUpdate( 4746 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4747 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 4748 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 4749 // Add parentheses (for debugging purposes only). 4750 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4751 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4752 !Step.isUsable()) 4753 return ExprError(); 4754 4755 ExprResult NewStep = Step; 4756 if (Captures) 4757 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4758 if (NewStep.isInvalid()) 4759 return ExprError(); 4760 ExprResult Update = 4761 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4762 if (!Update.isUsable()) 4763 return ExprError(); 4764 4765 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4766 // 'VarRef = Start (+|-) Iter * Step'. 4767 ExprResult NewStart = Start; 4768 if (Captures) 4769 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4770 if (NewStart.isInvalid()) 4771 return ExprError(); 4772 4773 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4774 ExprResult SavedUpdate = Update; 4775 ExprResult UpdateVal; 4776 if (VarRef.get()->getType()->isOverloadableType() || 4777 NewStart.get()->getType()->isOverloadableType() || 4778 Update.get()->getType()->isOverloadableType()) { 4779 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4780 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4781 Update = 4782 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4783 if (Update.isUsable()) { 4784 UpdateVal = 4785 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4786 VarRef.get(), SavedUpdate.get()); 4787 if (UpdateVal.isUsable()) { 4788 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4789 UpdateVal.get()); 4790 } 4791 } 4792 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4793 } 4794 4795 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4796 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4797 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4798 NewStart.get(), SavedUpdate.get()); 4799 if (!Update.isUsable()) 4800 return ExprError(); 4801 4802 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4803 VarRef.get()->getType())) { 4804 Update = SemaRef.PerformImplicitConversion( 4805 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4806 if (!Update.isUsable()) 4807 return ExprError(); 4808 } 4809 4810 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4811 } 4812 return Update; 4813 } 4814 4815 /// Convert integer expression \a E to make it have at least \a Bits 4816 /// bits. 4817 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 4818 if (E == nullptr) 4819 return ExprError(); 4820 ASTContext &C = SemaRef.Context; 4821 QualType OldType = E->getType(); 4822 unsigned HasBits = C.getTypeSize(OldType); 4823 if (HasBits >= Bits) 4824 return ExprResult(E); 4825 // OK to convert to signed, because new type has more bits than old. 4826 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4827 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4828 true); 4829 } 4830 4831 /// Check if the given expression \a E is a constant integer that fits 4832 /// into \a Bits bits. 4833 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 4834 if (E == nullptr) 4835 return false; 4836 llvm::APSInt Result; 4837 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4838 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4839 return false; 4840 } 4841 4842 /// Build preinits statement for the given declarations. 4843 static Stmt *buildPreInits(ASTContext &Context, 4844 MutableArrayRef<Decl *> PreInits) { 4845 if (!PreInits.empty()) { 4846 return new (Context) DeclStmt( 4847 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4848 SourceLocation(), SourceLocation()); 4849 } 4850 return nullptr; 4851 } 4852 4853 /// Build preinits statement for the given declarations. 4854 static Stmt * 4855 buildPreInits(ASTContext &Context, 4856 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4857 if (!Captures.empty()) { 4858 SmallVector<Decl *, 16> PreInits; 4859 for (const auto &Pair : Captures) 4860 PreInits.push_back(Pair.second->getDecl()); 4861 return buildPreInits(Context, PreInits); 4862 } 4863 return nullptr; 4864 } 4865 4866 /// Build postupdate expression for the given list of postupdates expressions. 4867 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4868 Expr *PostUpdate = nullptr; 4869 if (!PostUpdates.empty()) { 4870 for (Expr *E : PostUpdates) { 4871 Expr *ConvE = S.BuildCStyleCastExpr( 4872 E->getExprLoc(), 4873 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4874 E->getExprLoc(), E) 4875 .get(); 4876 PostUpdate = PostUpdate 4877 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4878 PostUpdate, ConvE) 4879 .get() 4880 : ConvE; 4881 } 4882 } 4883 return PostUpdate; 4884 } 4885 4886 /// Called on a for stmt to check itself and nested loops (if any). 4887 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4888 /// number of collapsed loops otherwise. 4889 static unsigned 4890 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4891 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4892 DSAStackTy &DSA, 4893 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 4894 OMPLoopDirective::HelperExprs &Built) { 4895 unsigned NestedLoopCount = 1; 4896 if (CollapseLoopCountExpr) { 4897 // Found 'collapse' clause - calculate collapse number. 4898 llvm::APSInt Result; 4899 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4900 NestedLoopCount = Result.getLimitedValue(); 4901 } 4902 unsigned OrderedLoopCount = 1; 4903 if (OrderedLoopCountExpr) { 4904 // Found 'ordered' clause - calculate collapse number. 4905 llvm::APSInt Result; 4906 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4907 if (Result.getLimitedValue() < NestedLoopCount) { 4908 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4909 diag::err_omp_wrong_ordered_loop_count) 4910 << OrderedLoopCountExpr->getSourceRange(); 4911 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4912 diag::note_collapse_loop_count) 4913 << CollapseLoopCountExpr->getSourceRange(); 4914 } 4915 OrderedLoopCount = Result.getLimitedValue(); 4916 } 4917 } 4918 // This is helper routine for loop directives (e.g., 'for', 'simd', 4919 // 'for simd', etc.). 4920 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 4921 SmallVector<LoopIterationSpace, 4> IterSpaces; 4922 IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount)); 4923 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4924 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4925 if (checkOpenMPIterationSpace( 4926 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 4927 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 4928 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 4929 Captures)) 4930 return 0; 4931 // Move on to the next nested for loop, or to the loop body. 4932 // OpenMP [2.8.1, simd construct, Restrictions] 4933 // All loops associated with the construct must be perfectly nested; that 4934 // is, there must be no intervening code nor any OpenMP directive between 4935 // any two loops. 4936 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4937 } 4938 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 4939 if (checkOpenMPIterationSpace( 4940 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 4941 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 4942 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 4943 Captures)) 4944 return 0; 4945 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 4946 // Handle initialization of captured loop iterator variables. 4947 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 4948 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 4949 Captures[DRE] = DRE; 4950 } 4951 } 4952 // Move on to the next nested for loop, or to the loop body. 4953 // OpenMP [2.8.1, simd construct, Restrictions] 4954 // All loops associated with the construct must be perfectly nested; that 4955 // is, there must be no intervening code nor any OpenMP directive between 4956 // any two loops. 4957 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4958 } 4959 4960 Built.clear(/* size */ NestedLoopCount); 4961 4962 if (SemaRef.CurContext->isDependentContext()) 4963 return NestedLoopCount; 4964 4965 // An example of what is generated for the following code: 4966 // 4967 // #pragma omp simd collapse(2) ordered(2) 4968 // for (i = 0; i < NI; ++i) 4969 // for (k = 0; k < NK; ++k) 4970 // for (j = J0; j < NJ; j+=2) { 4971 // <loop body> 4972 // } 4973 // 4974 // We generate the code below. 4975 // Note: the loop body may be outlined in CodeGen. 4976 // Note: some counters may be C++ classes, operator- is used to find number of 4977 // iterations and operator+= to calculate counter value. 4978 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4979 // or i64 is currently supported). 4980 // 4981 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4982 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4983 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4984 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4985 // // similar updates for vars in clauses (e.g. 'linear') 4986 // <loop body (using local i and j)> 4987 // } 4988 // i = NI; // assign final values of counters 4989 // j = NJ; 4990 // 4991 4992 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4993 // the iteration counts of the collapsed for loops. 4994 // Precondition tests if there is at least one iteration (all conditions are 4995 // true). 4996 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4997 Expr *N0 = IterSpaces[0].NumIterations; 4998 ExprResult LastIteration32 = 4999 widenIterationCount(/*Bits=*/32, 5000 SemaRef 5001 .PerformImplicitConversion( 5002 N0->IgnoreImpCasts(), N0->getType(), 5003 Sema::AA_Converting, /*AllowExplicit=*/true) 5004 .get(), 5005 SemaRef); 5006 ExprResult LastIteration64 = widenIterationCount( 5007 /*Bits=*/64, 5008 SemaRef 5009 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 5010 Sema::AA_Converting, 5011 /*AllowExplicit=*/true) 5012 .get(), 5013 SemaRef); 5014 5015 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 5016 return NestedLoopCount; 5017 5018 ASTContext &C = SemaRef.Context; 5019 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 5020 5021 Scope *CurScope = DSA.getCurScope(); 5022 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 5023 if (PreCond.isUsable()) { 5024 PreCond = 5025 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 5026 PreCond.get(), IterSpaces[Cnt].PreCond); 5027 } 5028 Expr *N = IterSpaces[Cnt].NumIterations; 5029 SourceLocation Loc = N->getExprLoc(); 5030 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 5031 if (LastIteration32.isUsable()) 5032 LastIteration32 = SemaRef.BuildBinOp( 5033 CurScope, Loc, BO_Mul, LastIteration32.get(), 5034 SemaRef 5035 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5036 Sema::AA_Converting, 5037 /*AllowExplicit=*/true) 5038 .get()); 5039 if (LastIteration64.isUsable()) 5040 LastIteration64 = SemaRef.BuildBinOp( 5041 CurScope, Loc, BO_Mul, LastIteration64.get(), 5042 SemaRef 5043 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5044 Sema::AA_Converting, 5045 /*AllowExplicit=*/true) 5046 .get()); 5047 } 5048 5049 // Choose either the 32-bit or 64-bit version. 5050 ExprResult LastIteration = LastIteration64; 5051 if (LastIteration32.isUsable() && 5052 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 5053 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 5054 fitsInto( 5055 /*Bits=*/32, 5056 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 5057 LastIteration64.get(), SemaRef))) 5058 LastIteration = LastIteration32; 5059 QualType VType = LastIteration.get()->getType(); 5060 QualType RealVType = VType; 5061 QualType StrideVType = VType; 5062 if (isOpenMPTaskLoopDirective(DKind)) { 5063 VType = 5064 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 5065 StrideVType = 5066 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 5067 } 5068 5069 if (!LastIteration.isUsable()) 5070 return 0; 5071 5072 // Save the number of iterations. 5073 ExprResult NumIterations = LastIteration; 5074 { 5075 LastIteration = SemaRef.BuildBinOp( 5076 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 5077 LastIteration.get(), 5078 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5079 if (!LastIteration.isUsable()) 5080 return 0; 5081 } 5082 5083 // Calculate the last iteration number beforehand instead of doing this on 5084 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5085 llvm::APSInt Result; 5086 bool IsConstant = 5087 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5088 ExprResult CalcLastIteration; 5089 if (!IsConstant) { 5090 ExprResult SaveRef = 5091 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5092 LastIteration = SaveRef; 5093 5094 // Prepare SaveRef + 1. 5095 NumIterations = SemaRef.BuildBinOp( 5096 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 5097 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5098 if (!NumIterations.isUsable()) 5099 return 0; 5100 } 5101 5102 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5103 5104 // Build variables passed into runtime, necessary for worksharing directives. 5105 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 5106 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5107 isOpenMPDistributeDirective(DKind)) { 5108 // Lower bound variable, initialized with zero. 5109 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5110 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5111 SemaRef.AddInitializerToDecl(LBDecl, 5112 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5113 /*DirectInit*/ false); 5114 5115 // Upper bound variable, initialized with last iteration number. 5116 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 5117 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 5118 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 5119 /*DirectInit*/ false); 5120 5121 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 5122 // This will be used to implement clause 'lastprivate'. 5123 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 5124 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 5125 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 5126 SemaRef.AddInitializerToDecl(ILDecl, 5127 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5128 /*DirectInit*/ false); 5129 5130 // Stride variable returned by runtime (we initialize it to 1 by default). 5131 VarDecl *STDecl = 5132 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 5133 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 5134 SemaRef.AddInitializerToDecl(STDecl, 5135 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 5136 /*DirectInit*/ false); 5137 5138 // Build expression: UB = min(UB, LastIteration) 5139 // It is necessary for CodeGen of directives with static scheduling. 5140 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 5141 UB.get(), LastIteration.get()); 5142 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5143 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 5144 LastIteration.get(), UB.get()); 5145 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 5146 CondOp.get()); 5147 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 5148 5149 // If we have a combined directive that combines 'distribute', 'for' or 5150 // 'simd' we need to be able to access the bounds of the schedule of the 5151 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 5152 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 5153 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5154 // Lower bound variable, initialized with zero. 5155 VarDecl *CombLBDecl = 5156 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 5157 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 5158 SemaRef.AddInitializerToDecl( 5159 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5160 /*DirectInit*/ false); 5161 5162 // Upper bound variable, initialized with last iteration number. 5163 VarDecl *CombUBDecl = 5164 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 5165 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 5166 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 5167 /*DirectInit*/ false); 5168 5169 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 5170 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 5171 ExprResult CombCondOp = 5172 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 5173 LastIteration.get(), CombUB.get()); 5174 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 5175 CombCondOp.get()); 5176 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); 5177 5178 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 5179 // We expect to have at least 2 more parameters than the 'parallel' 5180 // directive does - the lower and upper bounds of the previous schedule. 5181 assert(CD->getNumParams() >= 4 && 5182 "Unexpected number of parameters in loop combined directive"); 5183 5184 // Set the proper type for the bounds given what we learned from the 5185 // enclosed loops. 5186 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 5187 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 5188 5189 // Previous lower and upper bounds are obtained from the region 5190 // parameters. 5191 PrevLB = 5192 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 5193 PrevUB = 5194 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 5195 } 5196 } 5197 5198 // Build the iteration variable and its initialization before loop. 5199 ExprResult IV; 5200 ExprResult Init, CombInit; 5201 { 5202 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 5203 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 5204 Expr *RHS = 5205 (isOpenMPWorksharingDirective(DKind) || 5206 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5207 ? LB.get() 5208 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5209 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 5210 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 5211 5212 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5213 Expr *CombRHS = 5214 (isOpenMPWorksharingDirective(DKind) || 5215 isOpenMPTaskLoopDirective(DKind) || 5216 isOpenMPDistributeDirective(DKind)) 5217 ? CombLB.get() 5218 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5219 CombInit = 5220 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 5221 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); 5222 } 5223 } 5224 5225 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 5226 SourceLocation CondLoc = AStmt->getBeginLoc(); 5227 ExprResult Cond = 5228 (isOpenMPWorksharingDirective(DKind) || 5229 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5230 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 5231 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5232 NumIterations.get()); 5233 ExprResult CombCond; 5234 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5235 CombCond = 5236 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get()); 5237 } 5238 // Loop increment (IV = IV + 1) 5239 SourceLocation IncLoc = AStmt->getBeginLoc(); 5240 ExprResult Inc = 5241 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 5242 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 5243 if (!Inc.isUsable()) 5244 return 0; 5245 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 5246 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 5247 if (!Inc.isUsable()) 5248 return 0; 5249 5250 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 5251 // Used for directives with static scheduling. 5252 // In combined construct, add combined version that use CombLB and CombUB 5253 // base variables for the update 5254 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 5255 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5256 isOpenMPDistributeDirective(DKind)) { 5257 // LB + ST 5258 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 5259 if (!NextLB.isUsable()) 5260 return 0; 5261 // LB = LB + ST 5262 NextLB = 5263 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 5264 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 5265 if (!NextLB.isUsable()) 5266 return 0; 5267 // UB + ST 5268 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 5269 if (!NextUB.isUsable()) 5270 return 0; 5271 // UB = UB + ST 5272 NextUB = 5273 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 5274 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 5275 if (!NextUB.isUsable()) 5276 return 0; 5277 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5278 CombNextLB = 5279 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 5280 if (!NextLB.isUsable()) 5281 return 0; 5282 // LB = LB + ST 5283 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 5284 CombNextLB.get()); 5285 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); 5286 if (!CombNextLB.isUsable()) 5287 return 0; 5288 // UB + ST 5289 CombNextUB = 5290 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 5291 if (!CombNextUB.isUsable()) 5292 return 0; 5293 // UB = UB + ST 5294 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 5295 CombNextUB.get()); 5296 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); 5297 if (!CombNextUB.isUsable()) 5298 return 0; 5299 } 5300 } 5301 5302 // Create increment expression for distribute loop when combined in a same 5303 // directive with for as IV = IV + ST; ensure upper bound expression based 5304 // on PrevUB instead of NumIterations - used to implement 'for' when found 5305 // in combination with 'distribute', like in 'distribute parallel for' 5306 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 5307 ExprResult DistCond, DistInc, PrevEUB; 5308 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5309 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); 5310 assert(DistCond.isUsable() && "distribute cond expr was not built"); 5311 5312 DistInc = 5313 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 5314 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5315 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 5316 DistInc.get()); 5317 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); 5318 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5319 5320 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 5321 // construct 5322 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 5323 ExprResult IsUBGreater = 5324 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 5325 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5326 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 5327 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 5328 CondOp.get()); 5329 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); 5330 } 5331 5332 // Build updates and final values of the loop counters. 5333 bool HasErrors = false; 5334 Built.Counters.resize(NestedLoopCount); 5335 Built.Inits.resize(NestedLoopCount); 5336 Built.Updates.resize(NestedLoopCount); 5337 Built.Finals.resize(NestedLoopCount); 5338 { 5339 ExprResult Div; 5340 // Go from inner nested loop to outer. 5341 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 5342 LoopIterationSpace &IS = IterSpaces[Cnt]; 5343 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 5344 // Build: Iter = (IV / Div) % IS.NumIters 5345 // where Div is product of previous iterations' IS.NumIters. 5346 ExprResult Iter; 5347 if (Div.isUsable()) { 5348 Iter = 5349 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 5350 } else { 5351 Iter = IV; 5352 assert((Cnt == (int)NestedLoopCount - 1) && 5353 "unusable div expected on first iteration only"); 5354 } 5355 5356 if (Cnt != 0 && Iter.isUsable()) 5357 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 5358 IS.NumIterations); 5359 if (!Iter.isUsable()) { 5360 HasErrors = true; 5361 break; 5362 } 5363 5364 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 5365 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 5366 DeclRefExpr *CounterVar = buildDeclRefExpr( 5367 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 5368 /*RefersToCapture=*/true); 5369 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 5370 IS.CounterInit, Captures); 5371 if (!Init.isUsable()) { 5372 HasErrors = true; 5373 break; 5374 } 5375 ExprResult Update = buildCounterUpdate( 5376 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 5377 IS.CounterStep, IS.Subtract, &Captures); 5378 if (!Update.isUsable()) { 5379 HasErrors = true; 5380 break; 5381 } 5382 5383 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 5384 ExprResult Final = buildCounterUpdate( 5385 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 5386 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 5387 if (!Final.isUsable()) { 5388 HasErrors = true; 5389 break; 5390 } 5391 5392 // Build Div for the next iteration: Div <- Div * IS.NumIters 5393 if (Cnt != 0) { 5394 if (Div.isUnset()) 5395 Div = IS.NumIterations; 5396 else 5397 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 5398 IS.NumIterations); 5399 5400 // Add parentheses (for debugging purposes only). 5401 if (Div.isUsable()) 5402 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 5403 if (!Div.isUsable()) { 5404 HasErrors = true; 5405 break; 5406 } 5407 } 5408 if (!Update.isUsable() || !Final.isUsable()) { 5409 HasErrors = true; 5410 break; 5411 } 5412 // Save results 5413 Built.Counters[Cnt] = IS.CounterVar; 5414 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 5415 Built.Inits[Cnt] = Init.get(); 5416 Built.Updates[Cnt] = Update.get(); 5417 Built.Finals[Cnt] = Final.get(); 5418 } 5419 } 5420 5421 if (HasErrors) 5422 return 0; 5423 5424 // Save results 5425 Built.IterationVarRef = IV.get(); 5426 Built.LastIteration = LastIteration.get(); 5427 Built.NumIterations = NumIterations.get(); 5428 Built.CalcLastIteration = 5429 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 5430 Built.PreCond = PreCond.get(); 5431 Built.PreInits = buildPreInits(C, Captures); 5432 Built.Cond = Cond.get(); 5433 Built.Init = Init.get(); 5434 Built.Inc = Inc.get(); 5435 Built.LB = LB.get(); 5436 Built.UB = UB.get(); 5437 Built.IL = IL.get(); 5438 Built.ST = ST.get(); 5439 Built.EUB = EUB.get(); 5440 Built.NLB = NextLB.get(); 5441 Built.NUB = NextUB.get(); 5442 Built.PrevLB = PrevLB.get(); 5443 Built.PrevUB = PrevUB.get(); 5444 Built.DistInc = DistInc.get(); 5445 Built.PrevEUB = PrevEUB.get(); 5446 Built.DistCombinedFields.LB = CombLB.get(); 5447 Built.DistCombinedFields.UB = CombUB.get(); 5448 Built.DistCombinedFields.EUB = CombEUB.get(); 5449 Built.DistCombinedFields.Init = CombInit.get(); 5450 Built.DistCombinedFields.Cond = CombCond.get(); 5451 Built.DistCombinedFields.NLB = CombNextLB.get(); 5452 Built.DistCombinedFields.NUB = CombNextUB.get(); 5453 5454 return NestedLoopCount; 5455 } 5456 5457 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 5458 auto CollapseClauses = 5459 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 5460 if (CollapseClauses.begin() != CollapseClauses.end()) 5461 return (*CollapseClauses.begin())->getNumForLoops(); 5462 return nullptr; 5463 } 5464 5465 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 5466 auto OrderedClauses = 5467 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 5468 if (OrderedClauses.begin() != OrderedClauses.end()) 5469 return (*OrderedClauses.begin())->getNumForLoops(); 5470 return nullptr; 5471 } 5472 5473 static bool checkSimdlenSafelenSpecified(Sema &S, 5474 const ArrayRef<OMPClause *> Clauses) { 5475 const OMPSafelenClause *Safelen = nullptr; 5476 const OMPSimdlenClause *Simdlen = nullptr; 5477 5478 for (const OMPClause *Clause : Clauses) { 5479 if (Clause->getClauseKind() == OMPC_safelen) 5480 Safelen = cast<OMPSafelenClause>(Clause); 5481 else if (Clause->getClauseKind() == OMPC_simdlen) 5482 Simdlen = cast<OMPSimdlenClause>(Clause); 5483 if (Safelen && Simdlen) 5484 break; 5485 } 5486 5487 if (Simdlen && Safelen) { 5488 llvm::APSInt SimdlenRes, SafelenRes; 5489 const Expr *SimdlenLength = Simdlen->getSimdlen(); 5490 const Expr *SafelenLength = Safelen->getSafelen(); 5491 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 5492 SimdlenLength->isInstantiationDependent() || 5493 SimdlenLength->containsUnexpandedParameterPack()) 5494 return false; 5495 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 5496 SafelenLength->isInstantiationDependent() || 5497 SafelenLength->containsUnexpandedParameterPack()) 5498 return false; 5499 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); 5500 SafelenLength->EvaluateAsInt(SafelenRes, S.Context); 5501 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 5502 // If both simdlen and safelen clauses are specified, the value of the 5503 // simdlen parameter must be less than or equal to the value of the safelen 5504 // parameter. 5505 if (SimdlenRes > SafelenRes) { 5506 S.Diag(SimdlenLength->getExprLoc(), 5507 diag::err_omp_wrong_simdlen_safelen_values) 5508 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 5509 return true; 5510 } 5511 } 5512 return false; 5513 } 5514 5515 StmtResult 5516 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 5517 SourceLocation StartLoc, SourceLocation EndLoc, 5518 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5519 if (!AStmt) 5520 return StmtError(); 5521 5522 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5523 OMPLoopDirective::HelperExprs B; 5524 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5525 // define the nested loops number. 5526 unsigned NestedLoopCount = checkOpenMPLoop( 5527 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5528 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5529 if (NestedLoopCount == 0) 5530 return StmtError(); 5531 5532 assert((CurContext->isDependentContext() || B.builtAll()) && 5533 "omp simd loop exprs were not built"); 5534 5535 if (!CurContext->isDependentContext()) { 5536 // Finalize the clauses that need pre-built expressions for CodeGen. 5537 for (OMPClause *C : Clauses) { 5538 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5539 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5540 B.NumIterations, *this, CurScope, 5541 DSAStack)) 5542 return StmtError(); 5543 } 5544 } 5545 5546 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5547 return StmtError(); 5548 5549 setFunctionHasBranchProtectedScope(); 5550 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5551 Clauses, AStmt, B); 5552 } 5553 5554 StmtResult 5555 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 5556 SourceLocation StartLoc, SourceLocation EndLoc, 5557 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5558 if (!AStmt) 5559 return StmtError(); 5560 5561 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5562 OMPLoopDirective::HelperExprs B; 5563 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5564 // define the nested loops number. 5565 unsigned NestedLoopCount = checkOpenMPLoop( 5566 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5567 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5568 if (NestedLoopCount == 0) 5569 return StmtError(); 5570 5571 assert((CurContext->isDependentContext() || B.builtAll()) && 5572 "omp for loop exprs were not built"); 5573 5574 if (!CurContext->isDependentContext()) { 5575 // Finalize the clauses that need pre-built expressions for CodeGen. 5576 for (OMPClause *C : Clauses) { 5577 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5578 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5579 B.NumIterations, *this, CurScope, 5580 DSAStack)) 5581 return StmtError(); 5582 } 5583 } 5584 5585 setFunctionHasBranchProtectedScope(); 5586 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5587 Clauses, AStmt, B, DSAStack->isCancelRegion()); 5588 } 5589 5590 StmtResult Sema::ActOnOpenMPForSimdDirective( 5591 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5592 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5593 if (!AStmt) 5594 return StmtError(); 5595 5596 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5597 OMPLoopDirective::HelperExprs B; 5598 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5599 // define the nested loops number. 5600 unsigned NestedLoopCount = 5601 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5602 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5603 VarsWithImplicitDSA, B); 5604 if (NestedLoopCount == 0) 5605 return StmtError(); 5606 5607 assert((CurContext->isDependentContext() || B.builtAll()) && 5608 "omp for simd loop exprs were not built"); 5609 5610 if (!CurContext->isDependentContext()) { 5611 // Finalize the clauses that need pre-built expressions for CodeGen. 5612 for (OMPClause *C : Clauses) { 5613 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5614 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5615 B.NumIterations, *this, CurScope, 5616 DSAStack)) 5617 return StmtError(); 5618 } 5619 } 5620 5621 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5622 return StmtError(); 5623 5624 setFunctionHasBranchProtectedScope(); 5625 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5626 Clauses, AStmt, B); 5627 } 5628 5629 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5630 Stmt *AStmt, 5631 SourceLocation StartLoc, 5632 SourceLocation EndLoc) { 5633 if (!AStmt) 5634 return StmtError(); 5635 5636 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5637 auto BaseStmt = AStmt; 5638 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5639 BaseStmt = CS->getCapturedStmt(); 5640 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5641 auto S = C->children(); 5642 if (S.begin() == S.end()) 5643 return StmtError(); 5644 // All associated statements must be '#pragma omp section' except for 5645 // the first one. 5646 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5647 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5648 if (SectionStmt) 5649 Diag(SectionStmt->getBeginLoc(), 5650 diag::err_omp_sections_substmt_not_section); 5651 return StmtError(); 5652 } 5653 cast<OMPSectionDirective>(SectionStmt) 5654 ->setHasCancel(DSAStack->isCancelRegion()); 5655 } 5656 } else { 5657 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 5658 return StmtError(); 5659 } 5660 5661 setFunctionHasBranchProtectedScope(); 5662 5663 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5664 DSAStack->isCancelRegion()); 5665 } 5666 5667 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5668 SourceLocation StartLoc, 5669 SourceLocation EndLoc) { 5670 if (!AStmt) 5671 return StmtError(); 5672 5673 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5674 5675 setFunctionHasBranchProtectedScope(); 5676 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5677 5678 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5679 DSAStack->isCancelRegion()); 5680 } 5681 5682 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5683 Stmt *AStmt, 5684 SourceLocation StartLoc, 5685 SourceLocation EndLoc) { 5686 if (!AStmt) 5687 return StmtError(); 5688 5689 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5690 5691 setFunctionHasBranchProtectedScope(); 5692 5693 // OpenMP [2.7.3, single Construct, Restrictions] 5694 // The copyprivate clause must not be used with the nowait clause. 5695 const OMPClause *Nowait = nullptr; 5696 const OMPClause *Copyprivate = nullptr; 5697 for (const OMPClause *Clause : Clauses) { 5698 if (Clause->getClauseKind() == OMPC_nowait) 5699 Nowait = Clause; 5700 else if (Clause->getClauseKind() == OMPC_copyprivate) 5701 Copyprivate = Clause; 5702 if (Copyprivate && Nowait) { 5703 Diag(Copyprivate->getBeginLoc(), 5704 diag::err_omp_single_copyprivate_with_nowait); 5705 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 5706 return StmtError(); 5707 } 5708 } 5709 5710 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5711 } 5712 5713 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5714 SourceLocation StartLoc, 5715 SourceLocation EndLoc) { 5716 if (!AStmt) 5717 return StmtError(); 5718 5719 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5720 5721 setFunctionHasBranchProtectedScope(); 5722 5723 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5724 } 5725 5726 StmtResult Sema::ActOnOpenMPCriticalDirective( 5727 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5728 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5729 if (!AStmt) 5730 return StmtError(); 5731 5732 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5733 5734 bool ErrorFound = false; 5735 llvm::APSInt Hint; 5736 SourceLocation HintLoc; 5737 bool DependentHint = false; 5738 for (const OMPClause *C : Clauses) { 5739 if (C->getClauseKind() == OMPC_hint) { 5740 if (!DirName.getName()) { 5741 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 5742 ErrorFound = true; 5743 } 5744 Expr *E = cast<OMPHintClause>(C)->getHint(); 5745 if (E->isTypeDependent() || E->isValueDependent() || 5746 E->isInstantiationDependent()) { 5747 DependentHint = true; 5748 } else { 5749 Hint = E->EvaluateKnownConstInt(Context); 5750 HintLoc = C->getBeginLoc(); 5751 } 5752 } 5753 } 5754 if (ErrorFound) 5755 return StmtError(); 5756 const auto Pair = DSAStack->getCriticalWithHint(DirName); 5757 if (Pair.first && DirName.getName() && !DependentHint) { 5758 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 5759 Diag(StartLoc, diag::err_omp_critical_with_hint); 5760 if (HintLoc.isValid()) 5761 Diag(HintLoc, diag::note_omp_critical_hint_here) 5762 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 5763 else 5764 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 5765 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 5766 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 5767 << 1 5768 << C->getHint()->EvaluateKnownConstInt(Context).toString( 5769 /*Radix=*/10, /*Signed=*/false); 5770 } else { 5771 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 5772 } 5773 } 5774 } 5775 5776 setFunctionHasBranchProtectedScope(); 5777 5778 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 5779 Clauses, AStmt); 5780 if (!Pair.first && DirName.getName() && !DependentHint) 5781 DSAStack->addCriticalWithHint(Dir, Hint); 5782 return Dir; 5783 } 5784 5785 StmtResult Sema::ActOnOpenMPParallelForDirective( 5786 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5787 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5788 if (!AStmt) 5789 return StmtError(); 5790 5791 auto *CS = cast<CapturedStmt>(AStmt); 5792 // 1.2.2 OpenMP Language Terminology 5793 // Structured block - An executable statement with a single entry at the 5794 // top and a single exit at the bottom. 5795 // The point of exit cannot be a branch out of the structured block. 5796 // longjmp() and throw() must not violate the entry/exit criteria. 5797 CS->getCapturedDecl()->setNothrow(); 5798 5799 OMPLoopDirective::HelperExprs B; 5800 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5801 // define the nested loops number. 5802 unsigned NestedLoopCount = 5803 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 5804 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5805 VarsWithImplicitDSA, B); 5806 if (NestedLoopCount == 0) 5807 return StmtError(); 5808 5809 assert((CurContext->isDependentContext() || B.builtAll()) && 5810 "omp parallel for loop exprs were not built"); 5811 5812 if (!CurContext->isDependentContext()) { 5813 // Finalize the clauses that need pre-built expressions for CodeGen. 5814 for (OMPClause *C : Clauses) { 5815 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5816 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5817 B.NumIterations, *this, CurScope, 5818 DSAStack)) 5819 return StmtError(); 5820 } 5821 } 5822 5823 setFunctionHasBranchProtectedScope(); 5824 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 5825 NestedLoopCount, Clauses, AStmt, B, 5826 DSAStack->isCancelRegion()); 5827 } 5828 5829 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 5830 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5831 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5832 if (!AStmt) 5833 return StmtError(); 5834 5835 auto *CS = cast<CapturedStmt>(AStmt); 5836 // 1.2.2 OpenMP Language Terminology 5837 // Structured block - An executable statement with a single entry at the 5838 // top and a single exit at the bottom. 5839 // The point of exit cannot be a branch out of the structured block. 5840 // longjmp() and throw() must not violate the entry/exit criteria. 5841 CS->getCapturedDecl()->setNothrow(); 5842 5843 OMPLoopDirective::HelperExprs B; 5844 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5845 // define the nested loops number. 5846 unsigned NestedLoopCount = 5847 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 5848 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5849 VarsWithImplicitDSA, B); 5850 if (NestedLoopCount == 0) 5851 return StmtError(); 5852 5853 if (!CurContext->isDependentContext()) { 5854 // Finalize the clauses that need pre-built expressions for CodeGen. 5855 for (OMPClause *C : Clauses) { 5856 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5857 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5858 B.NumIterations, *this, CurScope, 5859 DSAStack)) 5860 return StmtError(); 5861 } 5862 } 5863 5864 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5865 return StmtError(); 5866 5867 setFunctionHasBranchProtectedScope(); 5868 return OMPParallelForSimdDirective::Create( 5869 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5870 } 5871 5872 StmtResult 5873 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5874 Stmt *AStmt, SourceLocation StartLoc, 5875 SourceLocation EndLoc) { 5876 if (!AStmt) 5877 return StmtError(); 5878 5879 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5880 auto BaseStmt = AStmt; 5881 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5882 BaseStmt = CS->getCapturedStmt(); 5883 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5884 auto S = C->children(); 5885 if (S.begin() == S.end()) 5886 return StmtError(); 5887 // All associated statements must be '#pragma omp section' except for 5888 // the first one. 5889 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5890 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5891 if (SectionStmt) 5892 Diag(SectionStmt->getBeginLoc(), 5893 diag::err_omp_parallel_sections_substmt_not_section); 5894 return StmtError(); 5895 } 5896 cast<OMPSectionDirective>(SectionStmt) 5897 ->setHasCancel(DSAStack->isCancelRegion()); 5898 } 5899 } else { 5900 Diag(AStmt->getBeginLoc(), 5901 diag::err_omp_parallel_sections_not_compound_stmt); 5902 return StmtError(); 5903 } 5904 5905 setFunctionHasBranchProtectedScope(); 5906 5907 return OMPParallelSectionsDirective::Create( 5908 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5909 } 5910 5911 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5912 Stmt *AStmt, SourceLocation StartLoc, 5913 SourceLocation EndLoc) { 5914 if (!AStmt) 5915 return StmtError(); 5916 5917 auto *CS = cast<CapturedStmt>(AStmt); 5918 // 1.2.2 OpenMP Language Terminology 5919 // Structured block - An executable statement with a single entry at the 5920 // top and a single exit at the bottom. 5921 // The point of exit cannot be a branch out of the structured block. 5922 // longjmp() and throw() must not violate the entry/exit criteria. 5923 CS->getCapturedDecl()->setNothrow(); 5924 5925 setFunctionHasBranchProtectedScope(); 5926 5927 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5928 DSAStack->isCancelRegion()); 5929 } 5930 5931 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5932 SourceLocation EndLoc) { 5933 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5934 } 5935 5936 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5937 SourceLocation EndLoc) { 5938 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5939 } 5940 5941 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5942 SourceLocation EndLoc) { 5943 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5944 } 5945 5946 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 5947 Stmt *AStmt, 5948 SourceLocation StartLoc, 5949 SourceLocation EndLoc) { 5950 if (!AStmt) 5951 return StmtError(); 5952 5953 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5954 5955 setFunctionHasBranchProtectedScope(); 5956 5957 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 5958 AStmt, 5959 DSAStack->getTaskgroupReductionRef()); 5960 } 5961 5962 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5963 SourceLocation StartLoc, 5964 SourceLocation EndLoc) { 5965 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5966 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5967 } 5968 5969 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5970 Stmt *AStmt, 5971 SourceLocation StartLoc, 5972 SourceLocation EndLoc) { 5973 const OMPClause *DependFound = nullptr; 5974 const OMPClause *DependSourceClause = nullptr; 5975 const OMPClause *DependSinkClause = nullptr; 5976 bool ErrorFound = false; 5977 const OMPThreadsClause *TC = nullptr; 5978 const OMPSIMDClause *SC = nullptr; 5979 for (const OMPClause *C : Clauses) { 5980 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5981 DependFound = C; 5982 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5983 if (DependSourceClause) { 5984 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5985 << getOpenMPDirectiveName(OMPD_ordered) 5986 << getOpenMPClauseName(OMPC_depend) << 2; 5987 ErrorFound = true; 5988 } else { 5989 DependSourceClause = C; 5990 } 5991 if (DependSinkClause) { 5992 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 5993 << 0; 5994 ErrorFound = true; 5995 } 5996 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5997 if (DependSourceClause) { 5998 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 5999 << 1; 6000 ErrorFound = true; 6001 } 6002 DependSinkClause = C; 6003 } 6004 } else if (C->getClauseKind() == OMPC_threads) { 6005 TC = cast<OMPThreadsClause>(C); 6006 } else if (C->getClauseKind() == OMPC_simd) { 6007 SC = cast<OMPSIMDClause>(C); 6008 } 6009 } 6010 if (!ErrorFound && !SC && 6011 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 6012 // OpenMP [2.8.1,simd Construct, Restrictions] 6013 // An ordered construct with the simd clause is the only OpenMP construct 6014 // that can appear in the simd region. 6015 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 6016 ErrorFound = true; 6017 } else if (DependFound && (TC || SC)) { 6018 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 6019 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 6020 ErrorFound = true; 6021 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 6022 Diag(DependFound->getBeginLoc(), 6023 diag::err_omp_ordered_directive_without_param); 6024 ErrorFound = true; 6025 } else if (TC || Clauses.empty()) { 6026 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 6027 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 6028 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 6029 << (TC != nullptr); 6030 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 6031 ErrorFound = true; 6032 } 6033 } 6034 if ((!AStmt && !DependFound) || ErrorFound) 6035 return StmtError(); 6036 6037 if (AStmt) { 6038 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6039 6040 setFunctionHasBranchProtectedScope(); 6041 } 6042 6043 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6044 } 6045 6046 namespace { 6047 /// Helper class for checking expression in 'omp atomic [update]' 6048 /// construct. 6049 class OpenMPAtomicUpdateChecker { 6050 /// Error results for atomic update expressions. 6051 enum ExprAnalysisErrorCode { 6052 /// A statement is not an expression statement. 6053 NotAnExpression, 6054 /// Expression is not builtin binary or unary operation. 6055 NotABinaryOrUnaryExpression, 6056 /// Unary operation is not post-/pre- increment/decrement operation. 6057 NotAnUnaryIncDecExpression, 6058 /// An expression is not of scalar type. 6059 NotAScalarType, 6060 /// A binary operation is not an assignment operation. 6061 NotAnAssignmentOp, 6062 /// RHS part of the binary operation is not a binary expression. 6063 NotABinaryExpression, 6064 /// RHS part is not additive/multiplicative/shift/biwise binary 6065 /// expression. 6066 NotABinaryOperator, 6067 /// RHS binary operation does not have reference to the updated LHS 6068 /// part. 6069 NotAnUpdateExpression, 6070 /// No errors is found. 6071 NoError 6072 }; 6073 /// Reference to Sema. 6074 Sema &SemaRef; 6075 /// A location for note diagnostics (when error is found). 6076 SourceLocation NoteLoc; 6077 /// 'x' lvalue part of the source atomic expression. 6078 Expr *X; 6079 /// 'expr' rvalue part of the source atomic expression. 6080 Expr *E; 6081 /// Helper expression of the form 6082 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6083 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6084 Expr *UpdateExpr; 6085 /// Is 'x' a LHS in a RHS part of full update expression. It is 6086 /// important for non-associative operations. 6087 bool IsXLHSInRHSPart; 6088 BinaryOperatorKind Op; 6089 SourceLocation OpLoc; 6090 /// true if the source expression is a postfix unary operation, false 6091 /// if it is a prefix unary operation. 6092 bool IsPostfixUpdate; 6093 6094 public: 6095 OpenMPAtomicUpdateChecker(Sema &SemaRef) 6096 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 6097 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 6098 /// Check specified statement that it is suitable for 'atomic update' 6099 /// constructs and extract 'x', 'expr' and Operation from the original 6100 /// expression. If DiagId and NoteId == 0, then only check is performed 6101 /// without error notification. 6102 /// \param DiagId Diagnostic which should be emitted if error is found. 6103 /// \param NoteId Diagnostic note for the main error message. 6104 /// \return true if statement is not an update expression, false otherwise. 6105 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 6106 /// Return the 'x' lvalue part of the source atomic expression. 6107 Expr *getX() const { return X; } 6108 /// Return the 'expr' rvalue part of the source atomic expression. 6109 Expr *getExpr() const { return E; } 6110 /// Return the update expression used in calculation of the updated 6111 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6112 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6113 Expr *getUpdateExpr() const { return UpdateExpr; } 6114 /// Return true if 'x' is LHS in RHS part of full update expression, 6115 /// false otherwise. 6116 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 6117 6118 /// true if the source expression is a postfix unary operation, false 6119 /// if it is a prefix unary operation. 6120 bool isPostfixUpdate() const { return IsPostfixUpdate; } 6121 6122 private: 6123 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 6124 unsigned NoteId = 0); 6125 }; 6126 } // namespace 6127 6128 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 6129 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 6130 ExprAnalysisErrorCode ErrorFound = NoError; 6131 SourceLocation ErrorLoc, NoteLoc; 6132 SourceRange ErrorRange, NoteRange; 6133 // Allowed constructs are: 6134 // x = x binop expr; 6135 // x = expr binop x; 6136 if (AtomicBinOp->getOpcode() == BO_Assign) { 6137 X = AtomicBinOp->getLHS(); 6138 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 6139 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 6140 if (AtomicInnerBinOp->isMultiplicativeOp() || 6141 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 6142 AtomicInnerBinOp->isBitwiseOp()) { 6143 Op = AtomicInnerBinOp->getOpcode(); 6144 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 6145 Expr *LHS = AtomicInnerBinOp->getLHS(); 6146 Expr *RHS = AtomicInnerBinOp->getRHS(); 6147 llvm::FoldingSetNodeID XId, LHSId, RHSId; 6148 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 6149 /*Canonical=*/true); 6150 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 6151 /*Canonical=*/true); 6152 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 6153 /*Canonical=*/true); 6154 if (XId == LHSId) { 6155 E = RHS; 6156 IsXLHSInRHSPart = true; 6157 } else if (XId == RHSId) { 6158 E = LHS; 6159 IsXLHSInRHSPart = false; 6160 } else { 6161 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6162 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6163 NoteLoc = X->getExprLoc(); 6164 NoteRange = X->getSourceRange(); 6165 ErrorFound = NotAnUpdateExpression; 6166 } 6167 } else { 6168 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6169 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6170 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 6171 NoteRange = SourceRange(NoteLoc, NoteLoc); 6172 ErrorFound = NotABinaryOperator; 6173 } 6174 } else { 6175 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 6176 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 6177 ErrorFound = NotABinaryExpression; 6178 } 6179 } else { 6180 ErrorLoc = AtomicBinOp->getExprLoc(); 6181 ErrorRange = AtomicBinOp->getSourceRange(); 6182 NoteLoc = AtomicBinOp->getOperatorLoc(); 6183 NoteRange = SourceRange(NoteLoc, NoteLoc); 6184 ErrorFound = NotAnAssignmentOp; 6185 } 6186 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6187 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6188 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6189 return true; 6190 } 6191 if (SemaRef.CurContext->isDependentContext()) 6192 E = X = UpdateExpr = nullptr; 6193 return ErrorFound != NoError; 6194 } 6195 6196 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 6197 unsigned NoteId) { 6198 ExprAnalysisErrorCode ErrorFound = NoError; 6199 SourceLocation ErrorLoc, NoteLoc; 6200 SourceRange ErrorRange, NoteRange; 6201 // Allowed constructs are: 6202 // x++; 6203 // x--; 6204 // ++x; 6205 // --x; 6206 // x binop= expr; 6207 // x = x binop expr; 6208 // x = expr binop x; 6209 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 6210 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 6211 if (AtomicBody->getType()->isScalarType() || 6212 AtomicBody->isInstantiationDependent()) { 6213 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 6214 AtomicBody->IgnoreParenImpCasts())) { 6215 // Check for Compound Assignment Operation 6216 Op = BinaryOperator::getOpForCompoundAssignment( 6217 AtomicCompAssignOp->getOpcode()); 6218 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 6219 E = AtomicCompAssignOp->getRHS(); 6220 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 6221 IsXLHSInRHSPart = true; 6222 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 6223 AtomicBody->IgnoreParenImpCasts())) { 6224 // Check for Binary Operation 6225 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 6226 return true; 6227 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 6228 AtomicBody->IgnoreParenImpCasts())) { 6229 // Check for Unary Operation 6230 if (AtomicUnaryOp->isIncrementDecrementOp()) { 6231 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 6232 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 6233 OpLoc = AtomicUnaryOp->getOperatorLoc(); 6234 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 6235 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 6236 IsXLHSInRHSPart = true; 6237 } else { 6238 ErrorFound = NotAnUnaryIncDecExpression; 6239 ErrorLoc = AtomicUnaryOp->getExprLoc(); 6240 ErrorRange = AtomicUnaryOp->getSourceRange(); 6241 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 6242 NoteRange = SourceRange(NoteLoc, NoteLoc); 6243 } 6244 } else if (!AtomicBody->isInstantiationDependent()) { 6245 ErrorFound = NotABinaryOrUnaryExpression; 6246 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 6247 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 6248 } 6249 } else { 6250 ErrorFound = NotAScalarType; 6251 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 6252 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6253 } 6254 } else { 6255 ErrorFound = NotAnExpression; 6256 NoteLoc = ErrorLoc = S->getBeginLoc(); 6257 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6258 } 6259 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6260 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6261 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6262 return true; 6263 } 6264 if (SemaRef.CurContext->isDependentContext()) 6265 E = X = UpdateExpr = nullptr; 6266 if (ErrorFound == NoError && E && X) { 6267 // Build an update expression of form 'OpaqueValueExpr(x) binop 6268 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 6269 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 6270 auto *OVEX = new (SemaRef.getASTContext()) 6271 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 6272 auto *OVEExpr = new (SemaRef.getASTContext()) 6273 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 6274 ExprResult Update = 6275 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 6276 IsXLHSInRHSPart ? OVEExpr : OVEX); 6277 if (Update.isInvalid()) 6278 return true; 6279 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 6280 Sema::AA_Casting); 6281 if (Update.isInvalid()) 6282 return true; 6283 UpdateExpr = Update.get(); 6284 } 6285 return ErrorFound != NoError; 6286 } 6287 6288 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 6289 Stmt *AStmt, 6290 SourceLocation StartLoc, 6291 SourceLocation EndLoc) { 6292 if (!AStmt) 6293 return StmtError(); 6294 6295 auto *CS = cast<CapturedStmt>(AStmt); 6296 // 1.2.2 OpenMP Language Terminology 6297 // Structured block - An executable statement with a single entry at the 6298 // top and a single exit at the bottom. 6299 // The point of exit cannot be a branch out of the structured block. 6300 // longjmp() and throw() must not violate the entry/exit criteria. 6301 OpenMPClauseKind AtomicKind = OMPC_unknown; 6302 SourceLocation AtomicKindLoc; 6303 for (const OMPClause *C : Clauses) { 6304 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 6305 C->getClauseKind() == OMPC_update || 6306 C->getClauseKind() == OMPC_capture) { 6307 if (AtomicKind != OMPC_unknown) { 6308 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 6309 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 6310 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 6311 << getOpenMPClauseName(AtomicKind); 6312 } else { 6313 AtomicKind = C->getClauseKind(); 6314 AtomicKindLoc = C->getBeginLoc(); 6315 } 6316 } 6317 } 6318 6319 Stmt *Body = CS->getCapturedStmt(); 6320 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 6321 Body = EWC->getSubExpr(); 6322 6323 Expr *X = nullptr; 6324 Expr *V = nullptr; 6325 Expr *E = nullptr; 6326 Expr *UE = nullptr; 6327 bool IsXLHSInRHSPart = false; 6328 bool IsPostfixUpdate = false; 6329 // OpenMP [2.12.6, atomic Construct] 6330 // In the next expressions: 6331 // * x and v (as applicable) are both l-value expressions with scalar type. 6332 // * During the execution of an atomic region, multiple syntactic 6333 // occurrences of x must designate the same storage location. 6334 // * Neither of v and expr (as applicable) may access the storage location 6335 // designated by x. 6336 // * Neither of x and expr (as applicable) may access the storage location 6337 // designated by v. 6338 // * expr is an expression with scalar type. 6339 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 6340 // * binop, binop=, ++, and -- are not overloaded operators. 6341 // * The expression x binop expr must be numerically equivalent to x binop 6342 // (expr). This requirement is satisfied if the operators in expr have 6343 // precedence greater than binop, or by using parentheses around expr or 6344 // subexpressions of expr. 6345 // * The expression expr binop x must be numerically equivalent to (expr) 6346 // binop x. This requirement is satisfied if the operators in expr have 6347 // precedence equal to or greater than binop, or by using parentheses around 6348 // expr or subexpressions of expr. 6349 // * For forms that allow multiple occurrences of x, the number of times 6350 // that x is evaluated is unspecified. 6351 if (AtomicKind == OMPC_read) { 6352 enum { 6353 NotAnExpression, 6354 NotAnAssignmentOp, 6355 NotAScalarType, 6356 NotAnLValue, 6357 NoError 6358 } ErrorFound = NoError; 6359 SourceLocation ErrorLoc, NoteLoc; 6360 SourceRange ErrorRange, NoteRange; 6361 // If clause is read: 6362 // v = x; 6363 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6364 const auto *AtomicBinOp = 6365 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6366 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6367 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6368 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 6369 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6370 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 6371 if (!X->isLValue() || !V->isLValue()) { 6372 const Expr *NotLValueExpr = X->isLValue() ? V : X; 6373 ErrorFound = NotAnLValue; 6374 ErrorLoc = AtomicBinOp->getExprLoc(); 6375 ErrorRange = AtomicBinOp->getSourceRange(); 6376 NoteLoc = NotLValueExpr->getExprLoc(); 6377 NoteRange = NotLValueExpr->getSourceRange(); 6378 } 6379 } else if (!X->isInstantiationDependent() || 6380 !V->isInstantiationDependent()) { 6381 const Expr *NotScalarExpr = 6382 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6383 ? V 6384 : X; 6385 ErrorFound = NotAScalarType; 6386 ErrorLoc = AtomicBinOp->getExprLoc(); 6387 ErrorRange = AtomicBinOp->getSourceRange(); 6388 NoteLoc = NotScalarExpr->getExprLoc(); 6389 NoteRange = NotScalarExpr->getSourceRange(); 6390 } 6391 } else if (!AtomicBody->isInstantiationDependent()) { 6392 ErrorFound = NotAnAssignmentOp; 6393 ErrorLoc = AtomicBody->getExprLoc(); 6394 ErrorRange = AtomicBody->getSourceRange(); 6395 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6396 : AtomicBody->getExprLoc(); 6397 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6398 : AtomicBody->getSourceRange(); 6399 } 6400 } else { 6401 ErrorFound = NotAnExpression; 6402 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6403 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6404 } 6405 if (ErrorFound != NoError) { 6406 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 6407 << ErrorRange; 6408 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6409 << NoteRange; 6410 return StmtError(); 6411 } 6412 if (CurContext->isDependentContext()) 6413 V = X = nullptr; 6414 } else if (AtomicKind == OMPC_write) { 6415 enum { 6416 NotAnExpression, 6417 NotAnAssignmentOp, 6418 NotAScalarType, 6419 NotAnLValue, 6420 NoError 6421 } ErrorFound = NoError; 6422 SourceLocation ErrorLoc, NoteLoc; 6423 SourceRange ErrorRange, NoteRange; 6424 // If clause is write: 6425 // x = expr; 6426 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6427 const auto *AtomicBinOp = 6428 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6429 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6430 X = AtomicBinOp->getLHS(); 6431 E = AtomicBinOp->getRHS(); 6432 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6433 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 6434 if (!X->isLValue()) { 6435 ErrorFound = NotAnLValue; 6436 ErrorLoc = AtomicBinOp->getExprLoc(); 6437 ErrorRange = AtomicBinOp->getSourceRange(); 6438 NoteLoc = X->getExprLoc(); 6439 NoteRange = X->getSourceRange(); 6440 } 6441 } else if (!X->isInstantiationDependent() || 6442 !E->isInstantiationDependent()) { 6443 const Expr *NotScalarExpr = 6444 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6445 ? E 6446 : X; 6447 ErrorFound = NotAScalarType; 6448 ErrorLoc = AtomicBinOp->getExprLoc(); 6449 ErrorRange = AtomicBinOp->getSourceRange(); 6450 NoteLoc = NotScalarExpr->getExprLoc(); 6451 NoteRange = NotScalarExpr->getSourceRange(); 6452 } 6453 } else if (!AtomicBody->isInstantiationDependent()) { 6454 ErrorFound = NotAnAssignmentOp; 6455 ErrorLoc = AtomicBody->getExprLoc(); 6456 ErrorRange = AtomicBody->getSourceRange(); 6457 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6458 : AtomicBody->getExprLoc(); 6459 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6460 : AtomicBody->getSourceRange(); 6461 } 6462 } else { 6463 ErrorFound = NotAnExpression; 6464 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6465 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6466 } 6467 if (ErrorFound != NoError) { 6468 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 6469 << ErrorRange; 6470 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6471 << NoteRange; 6472 return StmtError(); 6473 } 6474 if (CurContext->isDependentContext()) 6475 E = X = nullptr; 6476 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 6477 // If clause is update: 6478 // x++; 6479 // x--; 6480 // ++x; 6481 // --x; 6482 // x binop= expr; 6483 // x = x binop expr; 6484 // x = expr binop x; 6485 OpenMPAtomicUpdateChecker Checker(*this); 6486 if (Checker.checkStatement( 6487 Body, (AtomicKind == OMPC_update) 6488 ? diag::err_omp_atomic_update_not_expression_statement 6489 : diag::err_omp_atomic_not_expression_statement, 6490 diag::note_omp_atomic_update)) 6491 return StmtError(); 6492 if (!CurContext->isDependentContext()) { 6493 E = Checker.getExpr(); 6494 X = Checker.getX(); 6495 UE = Checker.getUpdateExpr(); 6496 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6497 } 6498 } else if (AtomicKind == OMPC_capture) { 6499 enum { 6500 NotAnAssignmentOp, 6501 NotACompoundStatement, 6502 NotTwoSubstatements, 6503 NotASpecificExpression, 6504 NoError 6505 } ErrorFound = NoError; 6506 SourceLocation ErrorLoc, NoteLoc; 6507 SourceRange ErrorRange, NoteRange; 6508 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6509 // If clause is a capture: 6510 // v = x++; 6511 // v = x--; 6512 // v = ++x; 6513 // v = --x; 6514 // v = x binop= expr; 6515 // v = x = x binop expr; 6516 // v = x = expr binop x; 6517 const auto *AtomicBinOp = 6518 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6519 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6520 V = AtomicBinOp->getLHS(); 6521 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6522 OpenMPAtomicUpdateChecker Checker(*this); 6523 if (Checker.checkStatement( 6524 Body, diag::err_omp_atomic_capture_not_expression_statement, 6525 diag::note_omp_atomic_update)) 6526 return StmtError(); 6527 E = Checker.getExpr(); 6528 X = Checker.getX(); 6529 UE = Checker.getUpdateExpr(); 6530 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6531 IsPostfixUpdate = Checker.isPostfixUpdate(); 6532 } else if (!AtomicBody->isInstantiationDependent()) { 6533 ErrorLoc = AtomicBody->getExprLoc(); 6534 ErrorRange = AtomicBody->getSourceRange(); 6535 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6536 : AtomicBody->getExprLoc(); 6537 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6538 : AtomicBody->getSourceRange(); 6539 ErrorFound = NotAnAssignmentOp; 6540 } 6541 if (ErrorFound != NoError) { 6542 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 6543 << ErrorRange; 6544 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6545 return StmtError(); 6546 } 6547 if (CurContext->isDependentContext()) 6548 UE = V = E = X = nullptr; 6549 } else { 6550 // If clause is a capture: 6551 // { v = x; x = expr; } 6552 // { v = x; x++; } 6553 // { v = x; x--; } 6554 // { v = x; ++x; } 6555 // { v = x; --x; } 6556 // { v = x; x binop= expr; } 6557 // { v = x; x = x binop expr; } 6558 // { v = x; x = expr binop x; } 6559 // { x++; v = x; } 6560 // { x--; v = x; } 6561 // { ++x; v = x; } 6562 // { --x; v = x; } 6563 // { x binop= expr; v = x; } 6564 // { x = x binop expr; v = x; } 6565 // { x = expr binop x; v = x; } 6566 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 6567 // Check that this is { expr1; expr2; } 6568 if (CS->size() == 2) { 6569 Stmt *First = CS->body_front(); 6570 Stmt *Second = CS->body_back(); 6571 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6572 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6573 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6574 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6575 // Need to find what subexpression is 'v' and what is 'x'. 6576 OpenMPAtomicUpdateChecker Checker(*this); 6577 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6578 BinaryOperator *BinOp = nullptr; 6579 if (IsUpdateExprFound) { 6580 BinOp = dyn_cast<BinaryOperator>(First); 6581 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6582 } 6583 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6584 // { v = x; x++; } 6585 // { v = x; x--; } 6586 // { v = x; ++x; } 6587 // { v = x; --x; } 6588 // { v = x; x binop= expr; } 6589 // { v = x; x = x binop expr; } 6590 // { v = x; x = expr binop x; } 6591 // Check that the first expression has form v = x. 6592 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6593 llvm::FoldingSetNodeID XId, PossibleXId; 6594 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6595 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6596 IsUpdateExprFound = XId == PossibleXId; 6597 if (IsUpdateExprFound) { 6598 V = BinOp->getLHS(); 6599 X = Checker.getX(); 6600 E = Checker.getExpr(); 6601 UE = Checker.getUpdateExpr(); 6602 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6603 IsPostfixUpdate = true; 6604 } 6605 } 6606 if (!IsUpdateExprFound) { 6607 IsUpdateExprFound = !Checker.checkStatement(First); 6608 BinOp = nullptr; 6609 if (IsUpdateExprFound) { 6610 BinOp = dyn_cast<BinaryOperator>(Second); 6611 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6612 } 6613 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6614 // { x++; v = x; } 6615 // { x--; v = x; } 6616 // { ++x; v = x; } 6617 // { --x; v = x; } 6618 // { x binop= expr; v = x; } 6619 // { x = x binop expr; v = x; } 6620 // { x = expr binop x; v = x; } 6621 // Check that the second expression has form v = x. 6622 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6623 llvm::FoldingSetNodeID XId, PossibleXId; 6624 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6625 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6626 IsUpdateExprFound = XId == PossibleXId; 6627 if (IsUpdateExprFound) { 6628 V = BinOp->getLHS(); 6629 X = Checker.getX(); 6630 E = Checker.getExpr(); 6631 UE = Checker.getUpdateExpr(); 6632 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6633 IsPostfixUpdate = false; 6634 } 6635 } 6636 } 6637 if (!IsUpdateExprFound) { 6638 // { v = x; x = expr; } 6639 auto *FirstExpr = dyn_cast<Expr>(First); 6640 auto *SecondExpr = dyn_cast<Expr>(Second); 6641 if (!FirstExpr || !SecondExpr || 6642 !(FirstExpr->isInstantiationDependent() || 6643 SecondExpr->isInstantiationDependent())) { 6644 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6645 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6646 ErrorFound = NotAnAssignmentOp; 6647 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6648 : First->getBeginLoc(); 6649 NoteRange = ErrorRange = FirstBinOp 6650 ? FirstBinOp->getSourceRange() 6651 : SourceRange(ErrorLoc, ErrorLoc); 6652 } else { 6653 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6654 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6655 ErrorFound = NotAnAssignmentOp; 6656 NoteLoc = ErrorLoc = SecondBinOp 6657 ? SecondBinOp->getOperatorLoc() 6658 : Second->getBeginLoc(); 6659 NoteRange = ErrorRange = 6660 SecondBinOp ? SecondBinOp->getSourceRange() 6661 : SourceRange(ErrorLoc, ErrorLoc); 6662 } else { 6663 Expr *PossibleXRHSInFirst = 6664 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6665 Expr *PossibleXLHSInSecond = 6666 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6667 llvm::FoldingSetNodeID X1Id, X2Id; 6668 PossibleXRHSInFirst->Profile(X1Id, Context, 6669 /*Canonical=*/true); 6670 PossibleXLHSInSecond->Profile(X2Id, Context, 6671 /*Canonical=*/true); 6672 IsUpdateExprFound = X1Id == X2Id; 6673 if (IsUpdateExprFound) { 6674 V = FirstBinOp->getLHS(); 6675 X = SecondBinOp->getLHS(); 6676 E = SecondBinOp->getRHS(); 6677 UE = nullptr; 6678 IsXLHSInRHSPart = false; 6679 IsPostfixUpdate = true; 6680 } else { 6681 ErrorFound = NotASpecificExpression; 6682 ErrorLoc = FirstBinOp->getExprLoc(); 6683 ErrorRange = FirstBinOp->getSourceRange(); 6684 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6685 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6686 } 6687 } 6688 } 6689 } 6690 } 6691 } else { 6692 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6693 NoteRange = ErrorRange = 6694 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 6695 ErrorFound = NotTwoSubstatements; 6696 } 6697 } else { 6698 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6699 NoteRange = ErrorRange = 6700 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 6701 ErrorFound = NotACompoundStatement; 6702 } 6703 if (ErrorFound != NoError) { 6704 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6705 << ErrorRange; 6706 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6707 return StmtError(); 6708 } 6709 if (CurContext->isDependentContext()) 6710 UE = V = E = X = nullptr; 6711 } 6712 } 6713 6714 setFunctionHasBranchProtectedScope(); 6715 6716 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6717 X, V, E, UE, IsXLHSInRHSPart, 6718 IsPostfixUpdate); 6719 } 6720 6721 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6722 Stmt *AStmt, 6723 SourceLocation StartLoc, 6724 SourceLocation EndLoc) { 6725 if (!AStmt) 6726 return StmtError(); 6727 6728 auto *CS = cast<CapturedStmt>(AStmt); 6729 // 1.2.2 OpenMP Language Terminology 6730 // Structured block - An executable statement with a single entry at the 6731 // top and a single exit at the bottom. 6732 // The point of exit cannot be a branch out of the structured block. 6733 // longjmp() and throw() must not violate the entry/exit criteria. 6734 CS->getCapturedDecl()->setNothrow(); 6735 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 6736 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6737 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6738 // 1.2.2 OpenMP Language Terminology 6739 // Structured block - An executable statement with a single entry at the 6740 // top and a single exit at the bottom. 6741 // The point of exit cannot be a branch out of the structured block. 6742 // longjmp() and throw() must not violate the entry/exit criteria. 6743 CS->getCapturedDecl()->setNothrow(); 6744 } 6745 6746 // OpenMP [2.16, Nesting of Regions] 6747 // If specified, a teams construct must be contained within a target 6748 // construct. That target construct must contain no statements or directives 6749 // outside of the teams construct. 6750 if (DSAStack->hasInnerTeamsRegion()) { 6751 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 6752 bool OMPTeamsFound = true; 6753 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 6754 auto I = CS->body_begin(); 6755 while (I != CS->body_end()) { 6756 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 6757 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 6758 OMPTeamsFound = false; 6759 break; 6760 } 6761 ++I; 6762 } 6763 assert(I != CS->body_end() && "Not found statement"); 6764 S = *I; 6765 } else { 6766 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 6767 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 6768 } 6769 if (!OMPTeamsFound) { 6770 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 6771 Diag(DSAStack->getInnerTeamsRegionLoc(), 6772 diag::note_omp_nested_teams_construct_here); 6773 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 6774 << isa<OMPExecutableDirective>(S); 6775 return StmtError(); 6776 } 6777 } 6778 6779 setFunctionHasBranchProtectedScope(); 6780 6781 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6782 } 6783 6784 StmtResult 6785 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 6786 Stmt *AStmt, SourceLocation StartLoc, 6787 SourceLocation EndLoc) { 6788 if (!AStmt) 6789 return StmtError(); 6790 6791 auto *CS = cast<CapturedStmt>(AStmt); 6792 // 1.2.2 OpenMP Language Terminology 6793 // Structured block - An executable statement with a single entry at the 6794 // top and a single exit at the bottom. 6795 // The point of exit cannot be a branch out of the structured block. 6796 // longjmp() and throw() must not violate the entry/exit criteria. 6797 CS->getCapturedDecl()->setNothrow(); 6798 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 6799 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6800 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6801 // 1.2.2 OpenMP Language Terminology 6802 // Structured block - An executable statement with a single entry at the 6803 // top and a single exit at the bottom. 6804 // The point of exit cannot be a branch out of the structured block. 6805 // longjmp() and throw() must not violate the entry/exit criteria. 6806 CS->getCapturedDecl()->setNothrow(); 6807 } 6808 6809 setFunctionHasBranchProtectedScope(); 6810 6811 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6812 AStmt); 6813 } 6814 6815 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 6816 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6817 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6818 if (!AStmt) 6819 return StmtError(); 6820 6821 auto *CS = cast<CapturedStmt>(AStmt); 6822 // 1.2.2 OpenMP Language Terminology 6823 // Structured block - An executable statement with a single entry at the 6824 // top and a single exit at the bottom. 6825 // The point of exit cannot be a branch out of the structured block. 6826 // longjmp() and throw() must not violate the entry/exit criteria. 6827 CS->getCapturedDecl()->setNothrow(); 6828 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 6829 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6830 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6831 // 1.2.2 OpenMP Language Terminology 6832 // Structured block - An executable statement with a single entry at the 6833 // top and a single exit at the bottom. 6834 // The point of exit cannot be a branch out of the structured block. 6835 // longjmp() and throw() must not violate the entry/exit criteria. 6836 CS->getCapturedDecl()->setNothrow(); 6837 } 6838 6839 OMPLoopDirective::HelperExprs B; 6840 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6841 // define the nested loops number. 6842 unsigned NestedLoopCount = 6843 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 6844 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 6845 VarsWithImplicitDSA, B); 6846 if (NestedLoopCount == 0) 6847 return StmtError(); 6848 6849 assert((CurContext->isDependentContext() || B.builtAll()) && 6850 "omp target parallel for loop exprs were not built"); 6851 6852 if (!CurContext->isDependentContext()) { 6853 // Finalize the clauses that need pre-built expressions for CodeGen. 6854 for (OMPClause *C : Clauses) { 6855 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6856 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6857 B.NumIterations, *this, CurScope, 6858 DSAStack)) 6859 return StmtError(); 6860 } 6861 } 6862 6863 setFunctionHasBranchProtectedScope(); 6864 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 6865 NestedLoopCount, Clauses, AStmt, 6866 B, DSAStack->isCancelRegion()); 6867 } 6868 6869 /// Check for existence of a map clause in the list of clauses. 6870 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 6871 const OpenMPClauseKind K) { 6872 return llvm::any_of( 6873 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 6874 } 6875 6876 template <typename... Params> 6877 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 6878 const Params... ClauseTypes) { 6879 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 6880 } 6881 6882 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 6883 Stmt *AStmt, 6884 SourceLocation StartLoc, 6885 SourceLocation EndLoc) { 6886 if (!AStmt) 6887 return StmtError(); 6888 6889 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6890 6891 // OpenMP [2.10.1, Restrictions, p. 97] 6892 // At least one map clause must appear on the directive. 6893 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 6894 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6895 << "'map' or 'use_device_ptr'" 6896 << getOpenMPDirectiveName(OMPD_target_data); 6897 return StmtError(); 6898 } 6899 6900 setFunctionHasBranchProtectedScope(); 6901 6902 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6903 AStmt); 6904 } 6905 6906 StmtResult 6907 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6908 SourceLocation StartLoc, 6909 SourceLocation EndLoc, Stmt *AStmt) { 6910 if (!AStmt) 6911 return StmtError(); 6912 6913 auto *CS = cast<CapturedStmt>(AStmt); 6914 // 1.2.2 OpenMP Language Terminology 6915 // Structured block - An executable statement with a single entry at the 6916 // top and a single exit at the bottom. 6917 // The point of exit cannot be a branch out of the structured block. 6918 // longjmp() and throw() must not violate the entry/exit criteria. 6919 CS->getCapturedDecl()->setNothrow(); 6920 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 6921 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6922 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6923 // 1.2.2 OpenMP Language Terminology 6924 // Structured block - An executable statement with a single entry at the 6925 // top and a single exit at the bottom. 6926 // The point of exit cannot be a branch out of the structured block. 6927 // longjmp() and throw() must not violate the entry/exit criteria. 6928 CS->getCapturedDecl()->setNothrow(); 6929 } 6930 6931 // OpenMP [2.10.2, Restrictions, p. 99] 6932 // At least one map clause must appear on the directive. 6933 if (!hasClauses(Clauses, OMPC_map)) { 6934 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6935 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 6936 return StmtError(); 6937 } 6938 6939 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6940 AStmt); 6941 } 6942 6943 StmtResult 6944 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6945 SourceLocation StartLoc, 6946 SourceLocation EndLoc, Stmt *AStmt) { 6947 if (!AStmt) 6948 return StmtError(); 6949 6950 auto *CS = cast<CapturedStmt>(AStmt); 6951 // 1.2.2 OpenMP Language Terminology 6952 // Structured block - An executable statement with a single entry at the 6953 // top and a single exit at the bottom. 6954 // The point of exit cannot be a branch out of the structured block. 6955 // longjmp() and throw() must not violate the entry/exit criteria. 6956 CS->getCapturedDecl()->setNothrow(); 6957 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 6958 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6959 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6960 // 1.2.2 OpenMP Language Terminology 6961 // Structured block - An executable statement with a single entry at the 6962 // top and a single exit at the bottom. 6963 // The point of exit cannot be a branch out of the structured block. 6964 // longjmp() and throw() must not violate the entry/exit criteria. 6965 CS->getCapturedDecl()->setNothrow(); 6966 } 6967 6968 // OpenMP [2.10.3, Restrictions, p. 102] 6969 // At least one map clause must appear on the directive. 6970 if (!hasClauses(Clauses, OMPC_map)) { 6971 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6972 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 6973 return StmtError(); 6974 } 6975 6976 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6977 AStmt); 6978 } 6979 6980 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 6981 SourceLocation StartLoc, 6982 SourceLocation EndLoc, 6983 Stmt *AStmt) { 6984 if (!AStmt) 6985 return StmtError(); 6986 6987 auto *CS = cast<CapturedStmt>(AStmt); 6988 // 1.2.2 OpenMP Language Terminology 6989 // Structured block - An executable statement with a single entry at the 6990 // top and a single exit at the bottom. 6991 // The point of exit cannot be a branch out of the structured block. 6992 // longjmp() and throw() must not violate the entry/exit criteria. 6993 CS->getCapturedDecl()->setNothrow(); 6994 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 6995 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6996 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6997 // 1.2.2 OpenMP Language Terminology 6998 // Structured block - An executable statement with a single entry at the 6999 // top and a single exit at the bottom. 7000 // The point of exit cannot be a branch out of the structured block. 7001 // longjmp() and throw() must not violate the entry/exit criteria. 7002 CS->getCapturedDecl()->setNothrow(); 7003 } 7004 7005 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 7006 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 7007 return StmtError(); 7008 } 7009 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 7010 AStmt); 7011 } 7012 7013 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 7014 Stmt *AStmt, SourceLocation StartLoc, 7015 SourceLocation EndLoc) { 7016 if (!AStmt) 7017 return StmtError(); 7018 7019 auto *CS = cast<CapturedStmt>(AStmt); 7020 // 1.2.2 OpenMP Language Terminology 7021 // Structured block - An executable statement with a single entry at the 7022 // top and a single exit at the bottom. 7023 // The point of exit cannot be a branch out of the structured block. 7024 // longjmp() and throw() must not violate the entry/exit criteria. 7025 CS->getCapturedDecl()->setNothrow(); 7026 7027 setFunctionHasBranchProtectedScope(); 7028 7029 DSAStack->setParentTeamsRegionLoc(StartLoc); 7030 7031 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7032 } 7033 7034 StmtResult 7035 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 7036 SourceLocation EndLoc, 7037 OpenMPDirectiveKind CancelRegion) { 7038 if (DSAStack->isParentNowaitRegion()) { 7039 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 7040 return StmtError(); 7041 } 7042 if (DSAStack->isParentOrderedRegion()) { 7043 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 7044 return StmtError(); 7045 } 7046 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 7047 CancelRegion); 7048 } 7049 7050 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 7051 SourceLocation StartLoc, 7052 SourceLocation EndLoc, 7053 OpenMPDirectiveKind CancelRegion) { 7054 if (DSAStack->isParentNowaitRegion()) { 7055 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 7056 return StmtError(); 7057 } 7058 if (DSAStack->isParentOrderedRegion()) { 7059 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 7060 return StmtError(); 7061 } 7062 DSAStack->setParentCancelRegion(/*Cancel=*/true); 7063 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7064 CancelRegion); 7065 } 7066 7067 static bool checkGrainsizeNumTasksClauses(Sema &S, 7068 ArrayRef<OMPClause *> Clauses) { 7069 const OMPClause *PrevClause = nullptr; 7070 bool ErrorFound = false; 7071 for (const OMPClause *C : Clauses) { 7072 if (C->getClauseKind() == OMPC_grainsize || 7073 C->getClauseKind() == OMPC_num_tasks) { 7074 if (!PrevClause) 7075 PrevClause = C; 7076 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 7077 S.Diag(C->getBeginLoc(), 7078 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 7079 << getOpenMPClauseName(C->getClauseKind()) 7080 << getOpenMPClauseName(PrevClause->getClauseKind()); 7081 S.Diag(PrevClause->getBeginLoc(), 7082 diag::note_omp_previous_grainsize_num_tasks) 7083 << getOpenMPClauseName(PrevClause->getClauseKind()); 7084 ErrorFound = true; 7085 } 7086 } 7087 } 7088 return ErrorFound; 7089 } 7090 7091 static bool checkReductionClauseWithNogroup(Sema &S, 7092 ArrayRef<OMPClause *> Clauses) { 7093 const OMPClause *ReductionClause = nullptr; 7094 const OMPClause *NogroupClause = nullptr; 7095 for (const OMPClause *C : Clauses) { 7096 if (C->getClauseKind() == OMPC_reduction) { 7097 ReductionClause = C; 7098 if (NogroupClause) 7099 break; 7100 continue; 7101 } 7102 if (C->getClauseKind() == OMPC_nogroup) { 7103 NogroupClause = C; 7104 if (ReductionClause) 7105 break; 7106 continue; 7107 } 7108 } 7109 if (ReductionClause && NogroupClause) { 7110 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 7111 << SourceRange(NogroupClause->getBeginLoc(), 7112 NogroupClause->getEndLoc()); 7113 return true; 7114 } 7115 return false; 7116 } 7117 7118 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 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' or 'ordered' with number of loops, it will 7127 // define the nested loops number. 7128 unsigned NestedLoopCount = 7129 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 7130 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7131 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 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7139 // The grainsize clause and num_tasks clause are mutually exclusive and may 7140 // not appear on the same taskloop directive. 7141 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7142 return StmtError(); 7143 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7144 // If a reduction clause is present on the taskloop directive, the nogroup 7145 // clause must not be specified. 7146 if (checkReductionClauseWithNogroup(*this, Clauses)) 7147 return StmtError(); 7148 7149 setFunctionHasBranchProtectedScope(); 7150 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 7151 NestedLoopCount, Clauses, AStmt, B); 7152 } 7153 7154 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 7155 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7156 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7157 if (!AStmt) 7158 return StmtError(); 7159 7160 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7161 OMPLoopDirective::HelperExprs B; 7162 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7163 // define the nested loops number. 7164 unsigned NestedLoopCount = 7165 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 7166 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7167 VarsWithImplicitDSA, B); 7168 if (NestedLoopCount == 0) 7169 return StmtError(); 7170 7171 assert((CurContext->isDependentContext() || B.builtAll()) && 7172 "omp for loop exprs were not built"); 7173 7174 if (!CurContext->isDependentContext()) { 7175 // Finalize the clauses that need pre-built expressions for CodeGen. 7176 for (OMPClause *C : Clauses) { 7177 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7178 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7179 B.NumIterations, *this, CurScope, 7180 DSAStack)) 7181 return StmtError(); 7182 } 7183 } 7184 7185 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7186 // The grainsize clause and num_tasks clause are mutually exclusive and may 7187 // not appear on the same taskloop directive. 7188 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7189 return StmtError(); 7190 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7191 // If a reduction clause is present on the taskloop directive, the nogroup 7192 // clause must not be specified. 7193 if (checkReductionClauseWithNogroup(*this, Clauses)) 7194 return StmtError(); 7195 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7196 return StmtError(); 7197 7198 setFunctionHasBranchProtectedScope(); 7199 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 7200 NestedLoopCount, Clauses, AStmt, B); 7201 } 7202 7203 StmtResult Sema::ActOnOpenMPDistributeDirective( 7204 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7205 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7206 if (!AStmt) 7207 return StmtError(); 7208 7209 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7210 OMPLoopDirective::HelperExprs B; 7211 // In presence of clause 'collapse' with number of loops, it will 7212 // define the nested loops number. 7213 unsigned NestedLoopCount = 7214 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 7215 nullptr /*ordered not a clause on distribute*/, AStmt, 7216 *this, *DSAStack, VarsWithImplicitDSA, B); 7217 if (NestedLoopCount == 0) 7218 return StmtError(); 7219 7220 assert((CurContext->isDependentContext() || B.builtAll()) && 7221 "omp for loop exprs were not built"); 7222 7223 setFunctionHasBranchProtectedScope(); 7224 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 7225 NestedLoopCount, Clauses, AStmt, B); 7226 } 7227 7228 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 7229 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7230 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7231 if (!AStmt) 7232 return StmtError(); 7233 7234 auto *CS = cast<CapturedStmt>(AStmt); 7235 // 1.2.2 OpenMP Language Terminology 7236 // Structured block - An executable statement with a single entry at the 7237 // top and a single exit at the bottom. 7238 // The point of exit cannot be a branch out of the structured block. 7239 // longjmp() and throw() must not violate the entry/exit criteria. 7240 CS->getCapturedDecl()->setNothrow(); 7241 for (int ThisCaptureLevel = 7242 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 7243 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7244 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7245 // 1.2.2 OpenMP Language Terminology 7246 // Structured block - An executable statement with a single entry at the 7247 // top and a single exit at the bottom. 7248 // The point of exit cannot be a branch out of the structured block. 7249 // longjmp() and throw() must not violate the entry/exit criteria. 7250 CS->getCapturedDecl()->setNothrow(); 7251 } 7252 7253 OMPLoopDirective::HelperExprs B; 7254 // In presence of clause 'collapse' with number of loops, it will 7255 // define the nested loops number. 7256 unsigned NestedLoopCount = checkOpenMPLoop( 7257 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7258 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7259 VarsWithImplicitDSA, B); 7260 if (NestedLoopCount == 0) 7261 return StmtError(); 7262 7263 assert((CurContext->isDependentContext() || B.builtAll()) && 7264 "omp for loop exprs were not built"); 7265 7266 setFunctionHasBranchProtectedScope(); 7267 return OMPDistributeParallelForDirective::Create( 7268 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7269 DSAStack->isCancelRegion()); 7270 } 7271 7272 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 7273 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7274 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7275 if (!AStmt) 7276 return StmtError(); 7277 7278 auto *CS = cast<CapturedStmt>(AStmt); 7279 // 1.2.2 OpenMP Language Terminology 7280 // Structured block - An executable statement with a single entry at the 7281 // top and a single exit at the bottom. 7282 // The point of exit cannot be a branch out of the structured block. 7283 // longjmp() and throw() must not violate the entry/exit criteria. 7284 CS->getCapturedDecl()->setNothrow(); 7285 for (int ThisCaptureLevel = 7286 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 7287 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7288 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7289 // 1.2.2 OpenMP Language Terminology 7290 // Structured block - An executable statement with a single entry at the 7291 // top and a single exit at the bottom. 7292 // The point of exit cannot be a branch out of the structured block. 7293 // longjmp() and throw() must not violate the entry/exit criteria. 7294 CS->getCapturedDecl()->setNothrow(); 7295 } 7296 7297 OMPLoopDirective::HelperExprs B; 7298 // In presence of clause 'collapse' with number of loops, it will 7299 // define the nested loops number. 7300 unsigned NestedLoopCount = checkOpenMPLoop( 7301 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7302 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7303 VarsWithImplicitDSA, B); 7304 if (NestedLoopCount == 0) 7305 return StmtError(); 7306 7307 assert((CurContext->isDependentContext() || B.builtAll()) && 7308 "omp for loop exprs were not built"); 7309 7310 if (!CurContext->isDependentContext()) { 7311 // Finalize the clauses that need pre-built expressions for CodeGen. 7312 for (OMPClause *C : Clauses) { 7313 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7314 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7315 B.NumIterations, *this, CurScope, 7316 DSAStack)) 7317 return StmtError(); 7318 } 7319 } 7320 7321 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7322 return StmtError(); 7323 7324 setFunctionHasBranchProtectedScope(); 7325 return OMPDistributeParallelForSimdDirective::Create( 7326 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7327 } 7328 7329 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 7330 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7331 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7332 if (!AStmt) 7333 return StmtError(); 7334 7335 auto *CS = cast<CapturedStmt>(AStmt); 7336 // 1.2.2 OpenMP Language Terminology 7337 // Structured block - An executable statement with a single entry at the 7338 // top and a single exit at the bottom. 7339 // The point of exit cannot be a branch out of the structured block. 7340 // longjmp() and throw() must not violate the entry/exit criteria. 7341 CS->getCapturedDecl()->setNothrow(); 7342 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 7343 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7344 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7345 // 1.2.2 OpenMP Language Terminology 7346 // Structured block - An executable statement with a single entry at the 7347 // top and a single exit at the bottom. 7348 // The point of exit cannot be a branch out of the structured block. 7349 // longjmp() and throw() must not violate the entry/exit criteria. 7350 CS->getCapturedDecl()->setNothrow(); 7351 } 7352 7353 OMPLoopDirective::HelperExprs B; 7354 // In presence of clause 'collapse' with number of loops, it will 7355 // define the nested loops number. 7356 unsigned NestedLoopCount = 7357 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 7358 nullptr /*ordered not a clause on distribute*/, CS, *this, 7359 *DSAStack, VarsWithImplicitDSA, B); 7360 if (NestedLoopCount == 0) 7361 return StmtError(); 7362 7363 assert((CurContext->isDependentContext() || B.builtAll()) && 7364 "omp for loop exprs were not built"); 7365 7366 if (!CurContext->isDependentContext()) { 7367 // Finalize the clauses that need pre-built expressions for CodeGen. 7368 for (OMPClause *C : Clauses) { 7369 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7370 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7371 B.NumIterations, *this, CurScope, 7372 DSAStack)) 7373 return StmtError(); 7374 } 7375 } 7376 7377 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7378 return StmtError(); 7379 7380 setFunctionHasBranchProtectedScope(); 7381 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 7382 NestedLoopCount, Clauses, AStmt, B); 7383 } 7384 7385 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 7386 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7387 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7388 if (!AStmt) 7389 return StmtError(); 7390 7391 auto *CS = cast<CapturedStmt>(AStmt); 7392 // 1.2.2 OpenMP Language Terminology 7393 // Structured block - An executable statement with a single entry at the 7394 // top and a single exit at the bottom. 7395 // The point of exit cannot be a branch out of the structured block. 7396 // longjmp() and throw() must not violate the entry/exit criteria. 7397 CS->getCapturedDecl()->setNothrow(); 7398 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7399 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7400 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7401 // 1.2.2 OpenMP Language Terminology 7402 // Structured block - An executable statement with a single entry at the 7403 // top and a single exit at the bottom. 7404 // The point of exit cannot be a branch out of the structured block. 7405 // longjmp() and throw() must not violate the entry/exit criteria. 7406 CS->getCapturedDecl()->setNothrow(); 7407 } 7408 7409 OMPLoopDirective::HelperExprs B; 7410 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7411 // define the nested loops number. 7412 unsigned NestedLoopCount = checkOpenMPLoop( 7413 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 7414 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7415 VarsWithImplicitDSA, B); 7416 if (NestedLoopCount == 0) 7417 return StmtError(); 7418 7419 assert((CurContext->isDependentContext() || B.builtAll()) && 7420 "omp target parallel for simd loop exprs were not built"); 7421 7422 if (!CurContext->isDependentContext()) { 7423 // Finalize the clauses that need pre-built expressions for CodeGen. 7424 for (OMPClause *C : Clauses) { 7425 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7426 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7427 B.NumIterations, *this, CurScope, 7428 DSAStack)) 7429 return StmtError(); 7430 } 7431 } 7432 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7433 return StmtError(); 7434 7435 setFunctionHasBranchProtectedScope(); 7436 return OMPTargetParallelForSimdDirective::Create( 7437 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7438 } 7439 7440 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 7441 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7442 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7443 if (!AStmt) 7444 return StmtError(); 7445 7446 auto *CS = cast<CapturedStmt>(AStmt); 7447 // 1.2.2 OpenMP Language Terminology 7448 // Structured block - An executable statement with a single entry at the 7449 // top and a single exit at the bottom. 7450 // The point of exit cannot be a branch out of the structured block. 7451 // longjmp() and throw() must not violate the entry/exit criteria. 7452 CS->getCapturedDecl()->setNothrow(); 7453 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 7454 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7455 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7456 // 1.2.2 OpenMP Language Terminology 7457 // Structured block - An executable statement with a single entry at the 7458 // top and a single exit at the bottom. 7459 // The point of exit cannot be a branch out of the structured block. 7460 // longjmp() and throw() must not violate the entry/exit criteria. 7461 CS->getCapturedDecl()->setNothrow(); 7462 } 7463 7464 OMPLoopDirective::HelperExprs B; 7465 // In presence of clause 'collapse' with number of loops, it will define the 7466 // nested loops number. 7467 unsigned NestedLoopCount = 7468 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 7469 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7470 VarsWithImplicitDSA, B); 7471 if (NestedLoopCount == 0) 7472 return StmtError(); 7473 7474 assert((CurContext->isDependentContext() || B.builtAll()) && 7475 "omp target simd loop exprs were not built"); 7476 7477 if (!CurContext->isDependentContext()) { 7478 // Finalize the clauses that need pre-built expressions for CodeGen. 7479 for (OMPClause *C : Clauses) { 7480 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7481 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7482 B.NumIterations, *this, CurScope, 7483 DSAStack)) 7484 return StmtError(); 7485 } 7486 } 7487 7488 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7489 return StmtError(); 7490 7491 setFunctionHasBranchProtectedScope(); 7492 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 7493 NestedLoopCount, Clauses, AStmt, B); 7494 } 7495 7496 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 7497 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7498 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7499 if (!AStmt) 7500 return StmtError(); 7501 7502 auto *CS = cast<CapturedStmt>(AStmt); 7503 // 1.2.2 OpenMP Language Terminology 7504 // Structured block - An executable statement with a single entry at the 7505 // top and a single exit at the bottom. 7506 // The point of exit cannot be a branch out of the structured block. 7507 // longjmp() and throw() must not violate the entry/exit criteria. 7508 CS->getCapturedDecl()->setNothrow(); 7509 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 7510 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7511 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7512 // 1.2.2 OpenMP Language Terminology 7513 // Structured block - An executable statement with a single entry at the 7514 // top and a single exit at the bottom. 7515 // The point of exit cannot be a branch out of the structured block. 7516 // longjmp() and throw() must not violate the entry/exit criteria. 7517 CS->getCapturedDecl()->setNothrow(); 7518 } 7519 7520 OMPLoopDirective::HelperExprs B; 7521 // In presence of clause 'collapse' with number of loops, it will 7522 // define the nested loops number. 7523 unsigned NestedLoopCount = 7524 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 7525 nullptr /*ordered not a clause on distribute*/, CS, *this, 7526 *DSAStack, VarsWithImplicitDSA, B); 7527 if (NestedLoopCount == 0) 7528 return StmtError(); 7529 7530 assert((CurContext->isDependentContext() || B.builtAll()) && 7531 "omp teams distribute loop exprs were not built"); 7532 7533 setFunctionHasBranchProtectedScope(); 7534 7535 DSAStack->setParentTeamsRegionLoc(StartLoc); 7536 7537 return OMPTeamsDistributeDirective::Create( 7538 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7539 } 7540 7541 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 7542 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7543 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7544 if (!AStmt) 7545 return StmtError(); 7546 7547 auto *CS = cast<CapturedStmt>(AStmt); 7548 // 1.2.2 OpenMP Language Terminology 7549 // Structured block - An executable statement with a single entry at the 7550 // top and a single exit at the bottom. 7551 // The point of exit cannot be a branch out of the structured block. 7552 // longjmp() and throw() must not violate the entry/exit criteria. 7553 CS->getCapturedDecl()->setNothrow(); 7554 for (int ThisCaptureLevel = 7555 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 7556 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7557 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7558 // 1.2.2 OpenMP Language Terminology 7559 // Structured block - An executable statement with a single entry at the 7560 // top and a single exit at the bottom. 7561 // The point of exit cannot be a branch out of the structured block. 7562 // longjmp() and throw() must not violate the entry/exit criteria. 7563 CS->getCapturedDecl()->setNothrow(); 7564 } 7565 7566 7567 OMPLoopDirective::HelperExprs B; 7568 // In presence of clause 'collapse' with number of loops, it will 7569 // define the nested loops number. 7570 unsigned NestedLoopCount = checkOpenMPLoop( 7571 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7572 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7573 VarsWithImplicitDSA, B); 7574 7575 if (NestedLoopCount == 0) 7576 return StmtError(); 7577 7578 assert((CurContext->isDependentContext() || B.builtAll()) && 7579 "omp teams distribute simd loop exprs were not built"); 7580 7581 if (!CurContext->isDependentContext()) { 7582 // Finalize the clauses that need pre-built expressions for CodeGen. 7583 for (OMPClause *C : Clauses) { 7584 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7585 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7586 B.NumIterations, *this, CurScope, 7587 DSAStack)) 7588 return StmtError(); 7589 } 7590 } 7591 7592 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7593 return StmtError(); 7594 7595 setFunctionHasBranchProtectedScope(); 7596 7597 DSAStack->setParentTeamsRegionLoc(StartLoc); 7598 7599 return OMPTeamsDistributeSimdDirective::Create( 7600 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7601 } 7602 7603 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 7604 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7605 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7606 if (!AStmt) 7607 return StmtError(); 7608 7609 auto *CS = cast<CapturedStmt>(AStmt); 7610 // 1.2.2 OpenMP Language Terminology 7611 // Structured block - An executable statement with a single entry at the 7612 // top and a single exit at the bottom. 7613 // The point of exit cannot be a branch out of the structured block. 7614 // longjmp() and throw() must not violate the entry/exit criteria. 7615 CS->getCapturedDecl()->setNothrow(); 7616 7617 for (int ThisCaptureLevel = 7618 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 7619 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7620 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7621 // 1.2.2 OpenMP Language Terminology 7622 // Structured block - An executable statement with a single entry at the 7623 // top and a single exit at the bottom. 7624 // The point of exit cannot be a branch out of the structured block. 7625 // longjmp() and throw() must not violate the entry/exit criteria. 7626 CS->getCapturedDecl()->setNothrow(); 7627 } 7628 7629 OMPLoopDirective::HelperExprs B; 7630 // In presence of clause 'collapse' with number of loops, it will 7631 // define the nested loops number. 7632 unsigned NestedLoopCount = checkOpenMPLoop( 7633 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7634 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7635 VarsWithImplicitDSA, B); 7636 7637 if (NestedLoopCount == 0) 7638 return StmtError(); 7639 7640 assert((CurContext->isDependentContext() || B.builtAll()) && 7641 "omp for loop exprs were not built"); 7642 7643 if (!CurContext->isDependentContext()) { 7644 // Finalize the clauses that need pre-built expressions for CodeGen. 7645 for (OMPClause *C : Clauses) { 7646 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7647 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7648 B.NumIterations, *this, CurScope, 7649 DSAStack)) 7650 return StmtError(); 7651 } 7652 } 7653 7654 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7655 return StmtError(); 7656 7657 setFunctionHasBranchProtectedScope(); 7658 7659 DSAStack->setParentTeamsRegionLoc(StartLoc); 7660 7661 return OMPTeamsDistributeParallelForSimdDirective::Create( 7662 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7663 } 7664 7665 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 7666 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7667 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7668 if (!AStmt) 7669 return StmtError(); 7670 7671 auto *CS = cast<CapturedStmt>(AStmt); 7672 // 1.2.2 OpenMP Language Terminology 7673 // Structured block - An executable statement with a single entry at the 7674 // top and a single exit at the bottom. 7675 // The point of exit cannot be a branch out of the structured block. 7676 // longjmp() and throw() must not violate the entry/exit criteria. 7677 CS->getCapturedDecl()->setNothrow(); 7678 7679 for (int ThisCaptureLevel = 7680 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 7681 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7682 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7683 // 1.2.2 OpenMP Language Terminology 7684 // Structured block - An executable statement with a single entry at the 7685 // top and a single exit at the bottom. 7686 // The point of exit cannot be a branch out of the structured block. 7687 // longjmp() and throw() must not violate the entry/exit criteria. 7688 CS->getCapturedDecl()->setNothrow(); 7689 } 7690 7691 OMPLoopDirective::HelperExprs B; 7692 // In presence of clause 'collapse' with number of loops, it will 7693 // define the nested loops number. 7694 unsigned NestedLoopCount = checkOpenMPLoop( 7695 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7696 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7697 VarsWithImplicitDSA, B); 7698 7699 if (NestedLoopCount == 0) 7700 return StmtError(); 7701 7702 assert((CurContext->isDependentContext() || B.builtAll()) && 7703 "omp for loop exprs were not built"); 7704 7705 setFunctionHasBranchProtectedScope(); 7706 7707 DSAStack->setParentTeamsRegionLoc(StartLoc); 7708 7709 return OMPTeamsDistributeParallelForDirective::Create( 7710 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7711 DSAStack->isCancelRegion()); 7712 } 7713 7714 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 7715 Stmt *AStmt, 7716 SourceLocation StartLoc, 7717 SourceLocation EndLoc) { 7718 if (!AStmt) 7719 return StmtError(); 7720 7721 auto *CS = cast<CapturedStmt>(AStmt); 7722 // 1.2.2 OpenMP Language Terminology 7723 // Structured block - An executable statement with a single entry at the 7724 // top and a single exit at the bottom. 7725 // The point of exit cannot be a branch out of the structured block. 7726 // longjmp() and throw() must not violate the entry/exit criteria. 7727 CS->getCapturedDecl()->setNothrow(); 7728 7729 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 7730 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7731 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7732 // 1.2.2 OpenMP Language Terminology 7733 // Structured block - An executable statement with a single entry at the 7734 // top and a single exit at the bottom. 7735 // The point of exit cannot be a branch out of the structured block. 7736 // longjmp() and throw() must not violate the entry/exit criteria. 7737 CS->getCapturedDecl()->setNothrow(); 7738 } 7739 setFunctionHasBranchProtectedScope(); 7740 7741 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 7742 AStmt); 7743 } 7744 7745 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 7746 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7747 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7748 if (!AStmt) 7749 return StmtError(); 7750 7751 auto *CS = cast<CapturedStmt>(AStmt); 7752 // 1.2.2 OpenMP Language Terminology 7753 // Structured block - An executable statement with a single entry at the 7754 // top and a single exit at the bottom. 7755 // The point of exit cannot be a branch out of the structured block. 7756 // longjmp() and throw() must not violate the entry/exit criteria. 7757 CS->getCapturedDecl()->setNothrow(); 7758 for (int ThisCaptureLevel = 7759 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 7760 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7761 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7762 // 1.2.2 OpenMP Language Terminology 7763 // Structured block - An executable statement with a single entry at the 7764 // top and a single exit at the bottom. 7765 // The point of exit cannot be a branch out of the structured block. 7766 // longjmp() and throw() must not violate the entry/exit criteria. 7767 CS->getCapturedDecl()->setNothrow(); 7768 } 7769 7770 OMPLoopDirective::HelperExprs B; 7771 // In presence of clause 'collapse' with number of loops, it will 7772 // define the nested loops number. 7773 unsigned NestedLoopCount = checkOpenMPLoop( 7774 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 7775 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7776 VarsWithImplicitDSA, B); 7777 if (NestedLoopCount == 0) 7778 return StmtError(); 7779 7780 assert((CurContext->isDependentContext() || B.builtAll()) && 7781 "omp target teams distribute loop exprs were not built"); 7782 7783 setFunctionHasBranchProtectedScope(); 7784 return OMPTargetTeamsDistributeDirective::Create( 7785 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7786 } 7787 7788 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 7789 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7790 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7791 if (!AStmt) 7792 return StmtError(); 7793 7794 auto *CS = cast<CapturedStmt>(AStmt); 7795 // 1.2.2 OpenMP Language Terminology 7796 // Structured block - An executable statement with a single entry at the 7797 // top and a single exit at the bottom. 7798 // The point of exit cannot be a branch out of the structured block. 7799 // longjmp() and throw() must not violate the entry/exit criteria. 7800 CS->getCapturedDecl()->setNothrow(); 7801 for (int ThisCaptureLevel = 7802 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 7803 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7804 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7805 // 1.2.2 OpenMP Language Terminology 7806 // Structured block - An executable statement with a single entry at the 7807 // top and a single exit at the bottom. 7808 // The point of exit cannot be a branch out of the structured block. 7809 // longjmp() and throw() must not violate the entry/exit criteria. 7810 CS->getCapturedDecl()->setNothrow(); 7811 } 7812 7813 OMPLoopDirective::HelperExprs B; 7814 // In presence of clause 'collapse' with number of loops, it will 7815 // define the nested loops number. 7816 unsigned NestedLoopCount = checkOpenMPLoop( 7817 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7818 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7819 VarsWithImplicitDSA, B); 7820 if (NestedLoopCount == 0) 7821 return StmtError(); 7822 7823 assert((CurContext->isDependentContext() || B.builtAll()) && 7824 "omp target teams distribute parallel for loop exprs were not built"); 7825 7826 if (!CurContext->isDependentContext()) { 7827 // Finalize the clauses that need pre-built expressions for CodeGen. 7828 for (OMPClause *C : Clauses) { 7829 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7830 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7831 B.NumIterations, *this, CurScope, 7832 DSAStack)) 7833 return StmtError(); 7834 } 7835 } 7836 7837 setFunctionHasBranchProtectedScope(); 7838 return OMPTargetTeamsDistributeParallelForDirective::Create( 7839 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7840 DSAStack->isCancelRegion()); 7841 } 7842 7843 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 7844 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7845 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7846 if (!AStmt) 7847 return StmtError(); 7848 7849 auto *CS = cast<CapturedStmt>(AStmt); 7850 // 1.2.2 OpenMP Language Terminology 7851 // Structured block - An executable statement with a single entry at the 7852 // top and a single exit at the bottom. 7853 // The point of exit cannot be a branch out of the structured block. 7854 // longjmp() and throw() must not violate the entry/exit criteria. 7855 CS->getCapturedDecl()->setNothrow(); 7856 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 7857 OMPD_target_teams_distribute_parallel_for_simd); 7858 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7859 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7860 // 1.2.2 OpenMP Language Terminology 7861 // Structured block - An executable statement with a single entry at the 7862 // top and a single exit at the bottom. 7863 // The point of exit cannot be a branch out of the structured block. 7864 // longjmp() and throw() must not violate the entry/exit criteria. 7865 CS->getCapturedDecl()->setNothrow(); 7866 } 7867 7868 OMPLoopDirective::HelperExprs B; 7869 // In presence of clause 'collapse' with number of loops, it will 7870 // define the nested loops number. 7871 unsigned NestedLoopCount = 7872 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 7873 getCollapseNumberExpr(Clauses), 7874 nullptr /*ordered not a clause on distribute*/, CS, *this, 7875 *DSAStack, VarsWithImplicitDSA, B); 7876 if (NestedLoopCount == 0) 7877 return StmtError(); 7878 7879 assert((CurContext->isDependentContext() || B.builtAll()) && 7880 "omp target teams distribute parallel for simd loop exprs were not " 7881 "built"); 7882 7883 if (!CurContext->isDependentContext()) { 7884 // Finalize the clauses that need pre-built expressions for CodeGen. 7885 for (OMPClause *C : Clauses) { 7886 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7887 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7888 B.NumIterations, *this, CurScope, 7889 DSAStack)) 7890 return StmtError(); 7891 } 7892 } 7893 7894 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7895 return StmtError(); 7896 7897 setFunctionHasBranchProtectedScope(); 7898 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 7899 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7900 } 7901 7902 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 7903 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7904 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7905 if (!AStmt) 7906 return StmtError(); 7907 7908 auto *CS = cast<CapturedStmt>(AStmt); 7909 // 1.2.2 OpenMP Language Terminology 7910 // Structured block - An executable statement with a single entry at the 7911 // top and a single exit at the bottom. 7912 // The point of exit cannot be a branch out of the structured block. 7913 // longjmp() and throw() must not violate the entry/exit criteria. 7914 CS->getCapturedDecl()->setNothrow(); 7915 for (int ThisCaptureLevel = 7916 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 7917 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7918 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7919 // 1.2.2 OpenMP Language Terminology 7920 // Structured block - An executable statement with a single entry at the 7921 // top and a single exit at the bottom. 7922 // The point of exit cannot be a branch out of the structured block. 7923 // longjmp() and throw() must not violate the entry/exit criteria. 7924 CS->getCapturedDecl()->setNothrow(); 7925 } 7926 7927 OMPLoopDirective::HelperExprs B; 7928 // In presence of clause 'collapse' with number of loops, it will 7929 // define the nested loops number. 7930 unsigned NestedLoopCount = checkOpenMPLoop( 7931 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7932 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7933 VarsWithImplicitDSA, B); 7934 if (NestedLoopCount == 0) 7935 return StmtError(); 7936 7937 assert((CurContext->isDependentContext() || B.builtAll()) && 7938 "omp target teams distribute simd loop exprs were not built"); 7939 7940 if (!CurContext->isDependentContext()) { 7941 // Finalize the clauses that need pre-built expressions for CodeGen. 7942 for (OMPClause *C : Clauses) { 7943 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7944 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7945 B.NumIterations, *this, CurScope, 7946 DSAStack)) 7947 return StmtError(); 7948 } 7949 } 7950 7951 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7952 return StmtError(); 7953 7954 setFunctionHasBranchProtectedScope(); 7955 return OMPTargetTeamsDistributeSimdDirective::Create( 7956 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7957 } 7958 7959 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 7960 SourceLocation StartLoc, 7961 SourceLocation LParenLoc, 7962 SourceLocation EndLoc) { 7963 OMPClause *Res = nullptr; 7964 switch (Kind) { 7965 case OMPC_final: 7966 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 7967 break; 7968 case OMPC_num_threads: 7969 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 7970 break; 7971 case OMPC_safelen: 7972 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 7973 break; 7974 case OMPC_simdlen: 7975 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 7976 break; 7977 case OMPC_collapse: 7978 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 7979 break; 7980 case OMPC_ordered: 7981 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 7982 break; 7983 case OMPC_device: 7984 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 7985 break; 7986 case OMPC_num_teams: 7987 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 7988 break; 7989 case OMPC_thread_limit: 7990 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 7991 break; 7992 case OMPC_priority: 7993 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 7994 break; 7995 case OMPC_grainsize: 7996 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 7997 break; 7998 case OMPC_num_tasks: 7999 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 8000 break; 8001 case OMPC_hint: 8002 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 8003 break; 8004 case OMPC_if: 8005 case OMPC_default: 8006 case OMPC_proc_bind: 8007 case OMPC_schedule: 8008 case OMPC_private: 8009 case OMPC_firstprivate: 8010 case OMPC_lastprivate: 8011 case OMPC_shared: 8012 case OMPC_reduction: 8013 case OMPC_task_reduction: 8014 case OMPC_in_reduction: 8015 case OMPC_linear: 8016 case OMPC_aligned: 8017 case OMPC_copyin: 8018 case OMPC_copyprivate: 8019 case OMPC_nowait: 8020 case OMPC_untied: 8021 case OMPC_mergeable: 8022 case OMPC_threadprivate: 8023 case OMPC_flush: 8024 case OMPC_read: 8025 case OMPC_write: 8026 case OMPC_update: 8027 case OMPC_capture: 8028 case OMPC_seq_cst: 8029 case OMPC_depend: 8030 case OMPC_threads: 8031 case OMPC_simd: 8032 case OMPC_map: 8033 case OMPC_nogroup: 8034 case OMPC_dist_schedule: 8035 case OMPC_defaultmap: 8036 case OMPC_unknown: 8037 case OMPC_uniform: 8038 case OMPC_to: 8039 case OMPC_from: 8040 case OMPC_use_device_ptr: 8041 case OMPC_is_device_ptr: 8042 case OMPC_unified_address: 8043 case OMPC_unified_shared_memory: 8044 case OMPC_reverse_offload: 8045 case OMPC_dynamic_allocators: 8046 llvm_unreachable("Clause is not allowed."); 8047 } 8048 return Res; 8049 } 8050 8051 // An OpenMP directive such as 'target parallel' has two captured regions: 8052 // for the 'target' and 'parallel' respectively. This function returns 8053 // the region in which to capture expressions associated with a clause. 8054 // A return value of OMPD_unknown signifies that the expression should not 8055 // be captured. 8056 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 8057 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 8058 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 8059 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8060 switch (CKind) { 8061 case OMPC_if: 8062 switch (DKind) { 8063 case OMPD_target_parallel: 8064 case OMPD_target_parallel_for: 8065 case OMPD_target_parallel_for_simd: 8066 // If this clause applies to the nested 'parallel' region, capture within 8067 // the 'target' region, otherwise do not capture. 8068 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8069 CaptureRegion = OMPD_target; 8070 break; 8071 case OMPD_target_teams_distribute_parallel_for: 8072 case OMPD_target_teams_distribute_parallel_for_simd: 8073 // If this clause applies to the nested 'parallel' region, capture within 8074 // the 'teams' region, otherwise do not capture. 8075 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8076 CaptureRegion = OMPD_teams; 8077 break; 8078 case OMPD_teams_distribute_parallel_for: 8079 case OMPD_teams_distribute_parallel_for_simd: 8080 CaptureRegion = OMPD_teams; 8081 break; 8082 case OMPD_target_update: 8083 case OMPD_target_enter_data: 8084 case OMPD_target_exit_data: 8085 CaptureRegion = OMPD_task; 8086 break; 8087 case OMPD_cancel: 8088 case OMPD_parallel: 8089 case OMPD_parallel_sections: 8090 case OMPD_parallel_for: 8091 case OMPD_parallel_for_simd: 8092 case OMPD_target: 8093 case OMPD_target_simd: 8094 case OMPD_target_teams: 8095 case OMPD_target_teams_distribute: 8096 case OMPD_target_teams_distribute_simd: 8097 case OMPD_distribute_parallel_for: 8098 case OMPD_distribute_parallel_for_simd: 8099 case OMPD_task: 8100 case OMPD_taskloop: 8101 case OMPD_taskloop_simd: 8102 case OMPD_target_data: 8103 // Do not capture if-clause expressions. 8104 break; 8105 case OMPD_threadprivate: 8106 case OMPD_taskyield: 8107 case OMPD_barrier: 8108 case OMPD_taskwait: 8109 case OMPD_cancellation_point: 8110 case OMPD_flush: 8111 case OMPD_declare_reduction: 8112 case OMPD_declare_simd: 8113 case OMPD_declare_target: 8114 case OMPD_end_declare_target: 8115 case OMPD_teams: 8116 case OMPD_simd: 8117 case OMPD_for: 8118 case OMPD_for_simd: 8119 case OMPD_sections: 8120 case OMPD_section: 8121 case OMPD_single: 8122 case OMPD_master: 8123 case OMPD_critical: 8124 case OMPD_taskgroup: 8125 case OMPD_distribute: 8126 case OMPD_ordered: 8127 case OMPD_atomic: 8128 case OMPD_distribute_simd: 8129 case OMPD_teams_distribute: 8130 case OMPD_teams_distribute_simd: 8131 case OMPD_requires: 8132 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 8133 case OMPD_unknown: 8134 llvm_unreachable("Unknown OpenMP directive"); 8135 } 8136 break; 8137 case OMPC_num_threads: 8138 switch (DKind) { 8139 case OMPD_target_parallel: 8140 case OMPD_target_parallel_for: 8141 case OMPD_target_parallel_for_simd: 8142 CaptureRegion = OMPD_target; 8143 break; 8144 case OMPD_teams_distribute_parallel_for: 8145 case OMPD_teams_distribute_parallel_for_simd: 8146 case OMPD_target_teams_distribute_parallel_for: 8147 case OMPD_target_teams_distribute_parallel_for_simd: 8148 CaptureRegion = OMPD_teams; 8149 break; 8150 case OMPD_parallel: 8151 case OMPD_parallel_sections: 8152 case OMPD_parallel_for: 8153 case OMPD_parallel_for_simd: 8154 case OMPD_distribute_parallel_for: 8155 case OMPD_distribute_parallel_for_simd: 8156 // Do not capture num_threads-clause expressions. 8157 break; 8158 case OMPD_target_data: 8159 case OMPD_target_enter_data: 8160 case OMPD_target_exit_data: 8161 case OMPD_target_update: 8162 case OMPD_target: 8163 case OMPD_target_simd: 8164 case OMPD_target_teams: 8165 case OMPD_target_teams_distribute: 8166 case OMPD_target_teams_distribute_simd: 8167 case OMPD_cancel: 8168 case OMPD_task: 8169 case OMPD_taskloop: 8170 case OMPD_taskloop_simd: 8171 case OMPD_threadprivate: 8172 case OMPD_taskyield: 8173 case OMPD_barrier: 8174 case OMPD_taskwait: 8175 case OMPD_cancellation_point: 8176 case OMPD_flush: 8177 case OMPD_declare_reduction: 8178 case OMPD_declare_simd: 8179 case OMPD_declare_target: 8180 case OMPD_end_declare_target: 8181 case OMPD_teams: 8182 case OMPD_simd: 8183 case OMPD_for: 8184 case OMPD_for_simd: 8185 case OMPD_sections: 8186 case OMPD_section: 8187 case OMPD_single: 8188 case OMPD_master: 8189 case OMPD_critical: 8190 case OMPD_taskgroup: 8191 case OMPD_distribute: 8192 case OMPD_ordered: 8193 case OMPD_atomic: 8194 case OMPD_distribute_simd: 8195 case OMPD_teams_distribute: 8196 case OMPD_teams_distribute_simd: 8197 case OMPD_requires: 8198 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 8199 case OMPD_unknown: 8200 llvm_unreachable("Unknown OpenMP directive"); 8201 } 8202 break; 8203 case OMPC_num_teams: 8204 switch (DKind) { 8205 case OMPD_target_teams: 8206 case OMPD_target_teams_distribute: 8207 case OMPD_target_teams_distribute_simd: 8208 case OMPD_target_teams_distribute_parallel_for: 8209 case OMPD_target_teams_distribute_parallel_for_simd: 8210 CaptureRegion = OMPD_target; 8211 break; 8212 case OMPD_teams_distribute_parallel_for: 8213 case OMPD_teams_distribute_parallel_for_simd: 8214 case OMPD_teams: 8215 case OMPD_teams_distribute: 8216 case OMPD_teams_distribute_simd: 8217 // Do not capture num_teams-clause expressions. 8218 break; 8219 case OMPD_distribute_parallel_for: 8220 case OMPD_distribute_parallel_for_simd: 8221 case OMPD_task: 8222 case OMPD_taskloop: 8223 case OMPD_taskloop_simd: 8224 case OMPD_target_data: 8225 case OMPD_target_enter_data: 8226 case OMPD_target_exit_data: 8227 case OMPD_target_update: 8228 case OMPD_cancel: 8229 case OMPD_parallel: 8230 case OMPD_parallel_sections: 8231 case OMPD_parallel_for: 8232 case OMPD_parallel_for_simd: 8233 case OMPD_target: 8234 case OMPD_target_simd: 8235 case OMPD_target_parallel: 8236 case OMPD_target_parallel_for: 8237 case OMPD_target_parallel_for_simd: 8238 case OMPD_threadprivate: 8239 case OMPD_taskyield: 8240 case OMPD_barrier: 8241 case OMPD_taskwait: 8242 case OMPD_cancellation_point: 8243 case OMPD_flush: 8244 case OMPD_declare_reduction: 8245 case OMPD_declare_simd: 8246 case OMPD_declare_target: 8247 case OMPD_end_declare_target: 8248 case OMPD_simd: 8249 case OMPD_for: 8250 case OMPD_for_simd: 8251 case OMPD_sections: 8252 case OMPD_section: 8253 case OMPD_single: 8254 case OMPD_master: 8255 case OMPD_critical: 8256 case OMPD_taskgroup: 8257 case OMPD_distribute: 8258 case OMPD_ordered: 8259 case OMPD_atomic: 8260 case OMPD_distribute_simd: 8261 case OMPD_requires: 8262 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8263 case OMPD_unknown: 8264 llvm_unreachable("Unknown OpenMP directive"); 8265 } 8266 break; 8267 case OMPC_thread_limit: 8268 switch (DKind) { 8269 case OMPD_target_teams: 8270 case OMPD_target_teams_distribute: 8271 case OMPD_target_teams_distribute_simd: 8272 case OMPD_target_teams_distribute_parallel_for: 8273 case OMPD_target_teams_distribute_parallel_for_simd: 8274 CaptureRegion = OMPD_target; 8275 break; 8276 case OMPD_teams_distribute_parallel_for: 8277 case OMPD_teams_distribute_parallel_for_simd: 8278 case OMPD_teams: 8279 case OMPD_teams_distribute: 8280 case OMPD_teams_distribute_simd: 8281 // Do not capture thread_limit-clause expressions. 8282 break; 8283 case OMPD_distribute_parallel_for: 8284 case OMPD_distribute_parallel_for_simd: 8285 case OMPD_task: 8286 case OMPD_taskloop: 8287 case OMPD_taskloop_simd: 8288 case OMPD_target_data: 8289 case OMPD_target_enter_data: 8290 case OMPD_target_exit_data: 8291 case OMPD_target_update: 8292 case OMPD_cancel: 8293 case OMPD_parallel: 8294 case OMPD_parallel_sections: 8295 case OMPD_parallel_for: 8296 case OMPD_parallel_for_simd: 8297 case OMPD_target: 8298 case OMPD_target_simd: 8299 case OMPD_target_parallel: 8300 case OMPD_target_parallel_for: 8301 case OMPD_target_parallel_for_simd: 8302 case OMPD_threadprivate: 8303 case OMPD_taskyield: 8304 case OMPD_barrier: 8305 case OMPD_taskwait: 8306 case OMPD_cancellation_point: 8307 case OMPD_flush: 8308 case OMPD_declare_reduction: 8309 case OMPD_declare_simd: 8310 case OMPD_declare_target: 8311 case OMPD_end_declare_target: 8312 case OMPD_simd: 8313 case OMPD_for: 8314 case OMPD_for_simd: 8315 case OMPD_sections: 8316 case OMPD_section: 8317 case OMPD_single: 8318 case OMPD_master: 8319 case OMPD_critical: 8320 case OMPD_taskgroup: 8321 case OMPD_distribute: 8322 case OMPD_ordered: 8323 case OMPD_atomic: 8324 case OMPD_distribute_simd: 8325 case OMPD_requires: 8326 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 8327 case OMPD_unknown: 8328 llvm_unreachable("Unknown OpenMP directive"); 8329 } 8330 break; 8331 case OMPC_schedule: 8332 switch (DKind) { 8333 case OMPD_parallel_for: 8334 case OMPD_parallel_for_simd: 8335 case OMPD_distribute_parallel_for: 8336 case OMPD_distribute_parallel_for_simd: 8337 case OMPD_teams_distribute_parallel_for: 8338 case OMPD_teams_distribute_parallel_for_simd: 8339 case OMPD_target_parallel_for: 8340 case OMPD_target_parallel_for_simd: 8341 case OMPD_target_teams_distribute_parallel_for: 8342 case OMPD_target_teams_distribute_parallel_for_simd: 8343 CaptureRegion = OMPD_parallel; 8344 break; 8345 case OMPD_for: 8346 case OMPD_for_simd: 8347 // Do not capture schedule-clause expressions. 8348 break; 8349 case OMPD_task: 8350 case OMPD_taskloop: 8351 case OMPD_taskloop_simd: 8352 case OMPD_target_data: 8353 case OMPD_target_enter_data: 8354 case OMPD_target_exit_data: 8355 case OMPD_target_update: 8356 case OMPD_teams: 8357 case OMPD_teams_distribute: 8358 case OMPD_teams_distribute_simd: 8359 case OMPD_target_teams_distribute: 8360 case OMPD_target_teams_distribute_simd: 8361 case OMPD_target: 8362 case OMPD_target_simd: 8363 case OMPD_target_parallel: 8364 case OMPD_cancel: 8365 case OMPD_parallel: 8366 case OMPD_parallel_sections: 8367 case OMPD_threadprivate: 8368 case OMPD_taskyield: 8369 case OMPD_barrier: 8370 case OMPD_taskwait: 8371 case OMPD_cancellation_point: 8372 case OMPD_flush: 8373 case OMPD_declare_reduction: 8374 case OMPD_declare_simd: 8375 case OMPD_declare_target: 8376 case OMPD_end_declare_target: 8377 case OMPD_simd: 8378 case OMPD_sections: 8379 case OMPD_section: 8380 case OMPD_single: 8381 case OMPD_master: 8382 case OMPD_critical: 8383 case OMPD_taskgroup: 8384 case OMPD_distribute: 8385 case OMPD_ordered: 8386 case OMPD_atomic: 8387 case OMPD_distribute_simd: 8388 case OMPD_target_teams: 8389 case OMPD_requires: 8390 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8391 case OMPD_unknown: 8392 llvm_unreachable("Unknown OpenMP directive"); 8393 } 8394 break; 8395 case OMPC_dist_schedule: 8396 switch (DKind) { 8397 case OMPD_teams_distribute_parallel_for: 8398 case OMPD_teams_distribute_parallel_for_simd: 8399 case OMPD_teams_distribute: 8400 case OMPD_teams_distribute_simd: 8401 case OMPD_target_teams_distribute_parallel_for: 8402 case OMPD_target_teams_distribute_parallel_for_simd: 8403 case OMPD_target_teams_distribute: 8404 case OMPD_target_teams_distribute_simd: 8405 CaptureRegion = OMPD_teams; 8406 break; 8407 case OMPD_distribute_parallel_for: 8408 case OMPD_distribute_parallel_for_simd: 8409 case OMPD_distribute: 8410 case OMPD_distribute_simd: 8411 // Do not capture thread_limit-clause expressions. 8412 break; 8413 case OMPD_parallel_for: 8414 case OMPD_parallel_for_simd: 8415 case OMPD_target_parallel_for_simd: 8416 case OMPD_target_parallel_for: 8417 case OMPD_task: 8418 case OMPD_taskloop: 8419 case OMPD_taskloop_simd: 8420 case OMPD_target_data: 8421 case OMPD_target_enter_data: 8422 case OMPD_target_exit_data: 8423 case OMPD_target_update: 8424 case OMPD_teams: 8425 case OMPD_target: 8426 case OMPD_target_simd: 8427 case OMPD_target_parallel: 8428 case OMPD_cancel: 8429 case OMPD_parallel: 8430 case OMPD_parallel_sections: 8431 case OMPD_threadprivate: 8432 case OMPD_taskyield: 8433 case OMPD_barrier: 8434 case OMPD_taskwait: 8435 case OMPD_cancellation_point: 8436 case OMPD_flush: 8437 case OMPD_declare_reduction: 8438 case OMPD_declare_simd: 8439 case OMPD_declare_target: 8440 case OMPD_end_declare_target: 8441 case OMPD_simd: 8442 case OMPD_for: 8443 case OMPD_for_simd: 8444 case OMPD_sections: 8445 case OMPD_section: 8446 case OMPD_single: 8447 case OMPD_master: 8448 case OMPD_critical: 8449 case OMPD_taskgroup: 8450 case OMPD_ordered: 8451 case OMPD_atomic: 8452 case OMPD_target_teams: 8453 case OMPD_requires: 8454 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8455 case OMPD_unknown: 8456 llvm_unreachable("Unknown OpenMP directive"); 8457 } 8458 break; 8459 case OMPC_device: 8460 switch (DKind) { 8461 case OMPD_target_update: 8462 case OMPD_target_enter_data: 8463 case OMPD_target_exit_data: 8464 case OMPD_target: 8465 case OMPD_target_simd: 8466 case OMPD_target_teams: 8467 case OMPD_target_parallel: 8468 case OMPD_target_teams_distribute: 8469 case OMPD_target_teams_distribute_simd: 8470 case OMPD_target_parallel_for: 8471 case OMPD_target_parallel_for_simd: 8472 case OMPD_target_teams_distribute_parallel_for: 8473 case OMPD_target_teams_distribute_parallel_for_simd: 8474 CaptureRegion = OMPD_task; 8475 break; 8476 case OMPD_target_data: 8477 // Do not capture device-clause expressions. 8478 break; 8479 case OMPD_teams_distribute_parallel_for: 8480 case OMPD_teams_distribute_parallel_for_simd: 8481 case OMPD_teams: 8482 case OMPD_teams_distribute: 8483 case OMPD_teams_distribute_simd: 8484 case OMPD_distribute_parallel_for: 8485 case OMPD_distribute_parallel_for_simd: 8486 case OMPD_task: 8487 case OMPD_taskloop: 8488 case OMPD_taskloop_simd: 8489 case OMPD_cancel: 8490 case OMPD_parallel: 8491 case OMPD_parallel_sections: 8492 case OMPD_parallel_for: 8493 case OMPD_parallel_for_simd: 8494 case OMPD_threadprivate: 8495 case OMPD_taskyield: 8496 case OMPD_barrier: 8497 case OMPD_taskwait: 8498 case OMPD_cancellation_point: 8499 case OMPD_flush: 8500 case OMPD_declare_reduction: 8501 case OMPD_declare_simd: 8502 case OMPD_declare_target: 8503 case OMPD_end_declare_target: 8504 case OMPD_simd: 8505 case OMPD_for: 8506 case OMPD_for_simd: 8507 case OMPD_sections: 8508 case OMPD_section: 8509 case OMPD_single: 8510 case OMPD_master: 8511 case OMPD_critical: 8512 case OMPD_taskgroup: 8513 case OMPD_distribute: 8514 case OMPD_ordered: 8515 case OMPD_atomic: 8516 case OMPD_distribute_simd: 8517 case OMPD_requires: 8518 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8519 case OMPD_unknown: 8520 llvm_unreachable("Unknown OpenMP directive"); 8521 } 8522 break; 8523 case OMPC_firstprivate: 8524 case OMPC_lastprivate: 8525 case OMPC_reduction: 8526 case OMPC_task_reduction: 8527 case OMPC_in_reduction: 8528 case OMPC_linear: 8529 case OMPC_default: 8530 case OMPC_proc_bind: 8531 case OMPC_final: 8532 case OMPC_safelen: 8533 case OMPC_simdlen: 8534 case OMPC_collapse: 8535 case OMPC_private: 8536 case OMPC_shared: 8537 case OMPC_aligned: 8538 case OMPC_copyin: 8539 case OMPC_copyprivate: 8540 case OMPC_ordered: 8541 case OMPC_nowait: 8542 case OMPC_untied: 8543 case OMPC_mergeable: 8544 case OMPC_threadprivate: 8545 case OMPC_flush: 8546 case OMPC_read: 8547 case OMPC_write: 8548 case OMPC_update: 8549 case OMPC_capture: 8550 case OMPC_seq_cst: 8551 case OMPC_depend: 8552 case OMPC_threads: 8553 case OMPC_simd: 8554 case OMPC_map: 8555 case OMPC_priority: 8556 case OMPC_grainsize: 8557 case OMPC_nogroup: 8558 case OMPC_num_tasks: 8559 case OMPC_hint: 8560 case OMPC_defaultmap: 8561 case OMPC_unknown: 8562 case OMPC_uniform: 8563 case OMPC_to: 8564 case OMPC_from: 8565 case OMPC_use_device_ptr: 8566 case OMPC_is_device_ptr: 8567 case OMPC_unified_address: 8568 case OMPC_unified_shared_memory: 8569 case OMPC_reverse_offload: 8570 case OMPC_dynamic_allocators: 8571 llvm_unreachable("Unexpected OpenMP clause."); 8572 } 8573 return CaptureRegion; 8574 } 8575 8576 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 8577 Expr *Condition, SourceLocation StartLoc, 8578 SourceLocation LParenLoc, 8579 SourceLocation NameModifierLoc, 8580 SourceLocation ColonLoc, 8581 SourceLocation EndLoc) { 8582 Expr *ValExpr = Condition; 8583 Stmt *HelperValStmt = nullptr; 8584 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8585 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 8586 !Condition->isInstantiationDependent() && 8587 !Condition->containsUnexpandedParameterPack()) { 8588 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 8589 if (Val.isInvalid()) 8590 return nullptr; 8591 8592 ValExpr = Val.get(); 8593 8594 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8595 CaptureRegion = 8596 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 8597 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 8598 ValExpr = MakeFullExpr(ValExpr).get(); 8599 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8600 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8601 HelperValStmt = buildPreInits(Context, Captures); 8602 } 8603 } 8604 8605 return new (Context) 8606 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 8607 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 8608 } 8609 8610 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 8611 SourceLocation StartLoc, 8612 SourceLocation LParenLoc, 8613 SourceLocation EndLoc) { 8614 Expr *ValExpr = Condition; 8615 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 8616 !Condition->isInstantiationDependent() && 8617 !Condition->containsUnexpandedParameterPack()) { 8618 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 8619 if (Val.isInvalid()) 8620 return nullptr; 8621 8622 ValExpr = MakeFullExpr(Val.get()).get(); 8623 } 8624 8625 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 8626 } 8627 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 8628 Expr *Op) { 8629 if (!Op) 8630 return ExprError(); 8631 8632 class IntConvertDiagnoser : public ICEConvertDiagnoser { 8633 public: 8634 IntConvertDiagnoser() 8635 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 8636 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 8637 QualType T) override { 8638 return S.Diag(Loc, diag::err_omp_not_integral) << T; 8639 } 8640 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 8641 QualType T) override { 8642 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 8643 } 8644 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 8645 QualType T, 8646 QualType ConvTy) override { 8647 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 8648 } 8649 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 8650 QualType ConvTy) override { 8651 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 8652 << ConvTy->isEnumeralType() << ConvTy; 8653 } 8654 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 8655 QualType T) override { 8656 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 8657 } 8658 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 8659 QualType ConvTy) override { 8660 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 8661 << ConvTy->isEnumeralType() << ConvTy; 8662 } 8663 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 8664 QualType) override { 8665 llvm_unreachable("conversion functions are permitted"); 8666 } 8667 } ConvertDiagnoser; 8668 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 8669 } 8670 8671 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 8672 OpenMPClauseKind CKind, 8673 bool StrictlyPositive) { 8674 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 8675 !ValExpr->isInstantiationDependent()) { 8676 SourceLocation Loc = ValExpr->getExprLoc(); 8677 ExprResult Value = 8678 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 8679 if (Value.isInvalid()) 8680 return false; 8681 8682 ValExpr = Value.get(); 8683 // The expression must evaluate to a non-negative integer value. 8684 llvm::APSInt Result; 8685 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 8686 Result.isSigned() && 8687 !((!StrictlyPositive && Result.isNonNegative()) || 8688 (StrictlyPositive && Result.isStrictlyPositive()))) { 8689 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 8690 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 8691 << ValExpr->getSourceRange(); 8692 return false; 8693 } 8694 } 8695 return true; 8696 } 8697 8698 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 8699 SourceLocation StartLoc, 8700 SourceLocation LParenLoc, 8701 SourceLocation EndLoc) { 8702 Expr *ValExpr = NumThreads; 8703 Stmt *HelperValStmt = nullptr; 8704 8705 // OpenMP [2.5, Restrictions] 8706 // The num_threads expression must evaluate to a positive integer value. 8707 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 8708 /*StrictlyPositive=*/true)) 8709 return nullptr; 8710 8711 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8712 OpenMPDirectiveKind CaptureRegion = 8713 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 8714 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 8715 ValExpr = MakeFullExpr(ValExpr).get(); 8716 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8717 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8718 HelperValStmt = buildPreInits(Context, Captures); 8719 } 8720 8721 return new (Context) OMPNumThreadsClause( 8722 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 8723 } 8724 8725 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 8726 OpenMPClauseKind CKind, 8727 bool StrictlyPositive) { 8728 if (!E) 8729 return ExprError(); 8730 if (E->isValueDependent() || E->isTypeDependent() || 8731 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 8732 return E; 8733 llvm::APSInt Result; 8734 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 8735 if (ICE.isInvalid()) 8736 return ExprError(); 8737 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 8738 (!StrictlyPositive && !Result.isNonNegative())) { 8739 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 8740 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 8741 << E->getSourceRange(); 8742 return ExprError(); 8743 } 8744 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 8745 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 8746 << E->getSourceRange(); 8747 return ExprError(); 8748 } 8749 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 8750 DSAStack->setAssociatedLoops(Result.getExtValue()); 8751 else if (CKind == OMPC_ordered) 8752 DSAStack->setAssociatedLoops(Result.getExtValue()); 8753 return ICE; 8754 } 8755 8756 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 8757 SourceLocation LParenLoc, 8758 SourceLocation EndLoc) { 8759 // OpenMP [2.8.1, simd construct, Description] 8760 // The parameter of the safelen clause must be a constant 8761 // positive integer expression. 8762 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 8763 if (Safelen.isInvalid()) 8764 return nullptr; 8765 return new (Context) 8766 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 8767 } 8768 8769 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 8770 SourceLocation LParenLoc, 8771 SourceLocation EndLoc) { 8772 // OpenMP [2.8.1, simd construct, Description] 8773 // The parameter of the simdlen clause must be a constant 8774 // positive integer expression. 8775 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 8776 if (Simdlen.isInvalid()) 8777 return nullptr; 8778 return new (Context) 8779 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 8780 } 8781 8782 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 8783 SourceLocation StartLoc, 8784 SourceLocation LParenLoc, 8785 SourceLocation EndLoc) { 8786 // OpenMP [2.7.1, loop construct, Description] 8787 // OpenMP [2.8.1, simd construct, Description] 8788 // OpenMP [2.9.6, distribute construct, Description] 8789 // The parameter of the collapse clause must be a constant 8790 // positive integer expression. 8791 ExprResult NumForLoopsResult = 8792 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 8793 if (NumForLoopsResult.isInvalid()) 8794 return nullptr; 8795 return new (Context) 8796 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 8797 } 8798 8799 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 8800 SourceLocation EndLoc, 8801 SourceLocation LParenLoc, 8802 Expr *NumForLoops) { 8803 // OpenMP [2.7.1, loop construct, Description] 8804 // OpenMP [2.8.1, simd construct, Description] 8805 // OpenMP [2.9.6, distribute construct, Description] 8806 // The parameter of the ordered clause must be a constant 8807 // positive integer expression if any. 8808 if (NumForLoops && LParenLoc.isValid()) { 8809 ExprResult NumForLoopsResult = 8810 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 8811 if (NumForLoopsResult.isInvalid()) 8812 return nullptr; 8813 NumForLoops = NumForLoopsResult.get(); 8814 } else { 8815 NumForLoops = nullptr; 8816 } 8817 auto *Clause = OMPOrderedClause::Create( 8818 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 8819 StartLoc, LParenLoc, EndLoc); 8820 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 8821 return Clause; 8822 } 8823 8824 OMPClause *Sema::ActOnOpenMPSimpleClause( 8825 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 8826 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 8827 OMPClause *Res = nullptr; 8828 switch (Kind) { 8829 case OMPC_default: 8830 Res = 8831 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 8832 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 8833 break; 8834 case OMPC_proc_bind: 8835 Res = ActOnOpenMPProcBindClause( 8836 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 8837 LParenLoc, EndLoc); 8838 break; 8839 case OMPC_if: 8840 case OMPC_final: 8841 case OMPC_num_threads: 8842 case OMPC_safelen: 8843 case OMPC_simdlen: 8844 case OMPC_collapse: 8845 case OMPC_schedule: 8846 case OMPC_private: 8847 case OMPC_firstprivate: 8848 case OMPC_lastprivate: 8849 case OMPC_shared: 8850 case OMPC_reduction: 8851 case OMPC_task_reduction: 8852 case OMPC_in_reduction: 8853 case OMPC_linear: 8854 case OMPC_aligned: 8855 case OMPC_copyin: 8856 case OMPC_copyprivate: 8857 case OMPC_ordered: 8858 case OMPC_nowait: 8859 case OMPC_untied: 8860 case OMPC_mergeable: 8861 case OMPC_threadprivate: 8862 case OMPC_flush: 8863 case OMPC_read: 8864 case OMPC_write: 8865 case OMPC_update: 8866 case OMPC_capture: 8867 case OMPC_seq_cst: 8868 case OMPC_depend: 8869 case OMPC_device: 8870 case OMPC_threads: 8871 case OMPC_simd: 8872 case OMPC_map: 8873 case OMPC_num_teams: 8874 case OMPC_thread_limit: 8875 case OMPC_priority: 8876 case OMPC_grainsize: 8877 case OMPC_nogroup: 8878 case OMPC_num_tasks: 8879 case OMPC_hint: 8880 case OMPC_dist_schedule: 8881 case OMPC_defaultmap: 8882 case OMPC_unknown: 8883 case OMPC_uniform: 8884 case OMPC_to: 8885 case OMPC_from: 8886 case OMPC_use_device_ptr: 8887 case OMPC_is_device_ptr: 8888 case OMPC_unified_address: 8889 case OMPC_unified_shared_memory: 8890 case OMPC_reverse_offload: 8891 case OMPC_dynamic_allocators: 8892 llvm_unreachable("Clause is not allowed."); 8893 } 8894 return Res; 8895 } 8896 8897 static std::string 8898 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 8899 ArrayRef<unsigned> Exclude = llvm::None) { 8900 SmallString<256> Buffer; 8901 llvm::raw_svector_ostream Out(Buffer); 8902 unsigned Bound = Last >= 2 ? Last - 2 : 0; 8903 unsigned Skipped = Exclude.size(); 8904 auto S = Exclude.begin(), E = Exclude.end(); 8905 for (unsigned I = First; I < Last; ++I) { 8906 if (std::find(S, E, I) != E) { 8907 --Skipped; 8908 continue; 8909 } 8910 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 8911 if (I == Bound - Skipped) 8912 Out << " or "; 8913 else if (I != Bound + 1 - Skipped) 8914 Out << ", "; 8915 } 8916 return Out.str(); 8917 } 8918 8919 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 8920 SourceLocation KindKwLoc, 8921 SourceLocation StartLoc, 8922 SourceLocation LParenLoc, 8923 SourceLocation EndLoc) { 8924 if (Kind == OMPC_DEFAULT_unknown) { 8925 static_assert(OMPC_DEFAULT_unknown > 0, 8926 "OMPC_DEFAULT_unknown not greater than 0"); 8927 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 8928 << getListOfPossibleValues(OMPC_default, /*First=*/0, 8929 /*Last=*/OMPC_DEFAULT_unknown) 8930 << getOpenMPClauseName(OMPC_default); 8931 return nullptr; 8932 } 8933 switch (Kind) { 8934 case OMPC_DEFAULT_none: 8935 DSAStack->setDefaultDSANone(KindKwLoc); 8936 break; 8937 case OMPC_DEFAULT_shared: 8938 DSAStack->setDefaultDSAShared(KindKwLoc); 8939 break; 8940 case OMPC_DEFAULT_unknown: 8941 llvm_unreachable("Clause kind is not allowed."); 8942 break; 8943 } 8944 return new (Context) 8945 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 8946 } 8947 8948 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 8949 SourceLocation KindKwLoc, 8950 SourceLocation StartLoc, 8951 SourceLocation LParenLoc, 8952 SourceLocation EndLoc) { 8953 if (Kind == OMPC_PROC_BIND_unknown) { 8954 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 8955 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 8956 /*Last=*/OMPC_PROC_BIND_unknown) 8957 << getOpenMPClauseName(OMPC_proc_bind); 8958 return nullptr; 8959 } 8960 return new (Context) 8961 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 8962 } 8963 8964 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 8965 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 8966 SourceLocation StartLoc, SourceLocation LParenLoc, 8967 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 8968 SourceLocation EndLoc) { 8969 OMPClause *Res = nullptr; 8970 switch (Kind) { 8971 case OMPC_schedule: 8972 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 8973 assert(Argument.size() == NumberOfElements && 8974 ArgumentLoc.size() == NumberOfElements); 8975 Res = ActOnOpenMPScheduleClause( 8976 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 8977 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 8978 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 8979 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 8980 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 8981 break; 8982 case OMPC_if: 8983 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 8984 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 8985 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 8986 DelimLoc, EndLoc); 8987 break; 8988 case OMPC_dist_schedule: 8989 Res = ActOnOpenMPDistScheduleClause( 8990 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 8991 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 8992 break; 8993 case OMPC_defaultmap: 8994 enum { Modifier, DefaultmapKind }; 8995 Res = ActOnOpenMPDefaultmapClause( 8996 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 8997 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 8998 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 8999 EndLoc); 9000 break; 9001 case OMPC_final: 9002 case OMPC_num_threads: 9003 case OMPC_safelen: 9004 case OMPC_simdlen: 9005 case OMPC_collapse: 9006 case OMPC_default: 9007 case OMPC_proc_bind: 9008 case OMPC_private: 9009 case OMPC_firstprivate: 9010 case OMPC_lastprivate: 9011 case OMPC_shared: 9012 case OMPC_reduction: 9013 case OMPC_task_reduction: 9014 case OMPC_in_reduction: 9015 case OMPC_linear: 9016 case OMPC_aligned: 9017 case OMPC_copyin: 9018 case OMPC_copyprivate: 9019 case OMPC_ordered: 9020 case OMPC_nowait: 9021 case OMPC_untied: 9022 case OMPC_mergeable: 9023 case OMPC_threadprivate: 9024 case OMPC_flush: 9025 case OMPC_read: 9026 case OMPC_write: 9027 case OMPC_update: 9028 case OMPC_capture: 9029 case OMPC_seq_cst: 9030 case OMPC_depend: 9031 case OMPC_device: 9032 case OMPC_threads: 9033 case OMPC_simd: 9034 case OMPC_map: 9035 case OMPC_num_teams: 9036 case OMPC_thread_limit: 9037 case OMPC_priority: 9038 case OMPC_grainsize: 9039 case OMPC_nogroup: 9040 case OMPC_num_tasks: 9041 case OMPC_hint: 9042 case OMPC_unknown: 9043 case OMPC_uniform: 9044 case OMPC_to: 9045 case OMPC_from: 9046 case OMPC_use_device_ptr: 9047 case OMPC_is_device_ptr: 9048 case OMPC_unified_address: 9049 case OMPC_unified_shared_memory: 9050 case OMPC_reverse_offload: 9051 case OMPC_dynamic_allocators: 9052 llvm_unreachable("Clause is not allowed."); 9053 } 9054 return Res; 9055 } 9056 9057 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 9058 OpenMPScheduleClauseModifier M2, 9059 SourceLocation M1Loc, SourceLocation M2Loc) { 9060 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 9061 SmallVector<unsigned, 2> Excluded; 9062 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 9063 Excluded.push_back(M2); 9064 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 9065 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 9066 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 9067 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 9068 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 9069 << getListOfPossibleValues(OMPC_schedule, 9070 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 9071 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9072 Excluded) 9073 << getOpenMPClauseName(OMPC_schedule); 9074 return true; 9075 } 9076 return false; 9077 } 9078 9079 OMPClause *Sema::ActOnOpenMPScheduleClause( 9080 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 9081 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 9082 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 9083 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 9084 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 9085 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 9086 return nullptr; 9087 // OpenMP, 2.7.1, Loop Construct, Restrictions 9088 // Either the monotonic modifier or the nonmonotonic modifier can be specified 9089 // but not both. 9090 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 9091 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 9092 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 9093 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 9094 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 9095 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 9096 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 9097 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 9098 return nullptr; 9099 } 9100 if (Kind == OMPC_SCHEDULE_unknown) { 9101 std::string Values; 9102 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 9103 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 9104 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9105 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9106 Exclude); 9107 } else { 9108 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9109 /*Last=*/OMPC_SCHEDULE_unknown); 9110 } 9111 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 9112 << Values << getOpenMPClauseName(OMPC_schedule); 9113 return nullptr; 9114 } 9115 // OpenMP, 2.7.1, Loop Construct, Restrictions 9116 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 9117 // schedule(guided). 9118 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 9119 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 9120 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 9121 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 9122 diag::err_omp_schedule_nonmonotonic_static); 9123 return nullptr; 9124 } 9125 Expr *ValExpr = ChunkSize; 9126 Stmt *HelperValStmt = nullptr; 9127 if (ChunkSize) { 9128 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 9129 !ChunkSize->isInstantiationDependent() && 9130 !ChunkSize->containsUnexpandedParameterPack()) { 9131 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 9132 ExprResult Val = 9133 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 9134 if (Val.isInvalid()) 9135 return nullptr; 9136 9137 ValExpr = Val.get(); 9138 9139 // OpenMP [2.7.1, Restrictions] 9140 // chunk_size must be a loop invariant integer expression with a positive 9141 // value. 9142 llvm::APSInt Result; 9143 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 9144 if (Result.isSigned() && !Result.isStrictlyPositive()) { 9145 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 9146 << "schedule" << 1 << ChunkSize->getSourceRange(); 9147 return nullptr; 9148 } 9149 } else if (getOpenMPCaptureRegionForClause( 9150 DSAStack->getCurrentDirective(), OMPC_schedule) != 9151 OMPD_unknown && 9152 !CurContext->isDependentContext()) { 9153 ValExpr = MakeFullExpr(ValExpr).get(); 9154 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9155 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9156 HelperValStmt = buildPreInits(Context, Captures); 9157 } 9158 } 9159 } 9160 9161 return new (Context) 9162 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 9163 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 9164 } 9165 9166 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 9167 SourceLocation StartLoc, 9168 SourceLocation EndLoc) { 9169 OMPClause *Res = nullptr; 9170 switch (Kind) { 9171 case OMPC_ordered: 9172 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 9173 break; 9174 case OMPC_nowait: 9175 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 9176 break; 9177 case OMPC_untied: 9178 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 9179 break; 9180 case OMPC_mergeable: 9181 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 9182 break; 9183 case OMPC_read: 9184 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 9185 break; 9186 case OMPC_write: 9187 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 9188 break; 9189 case OMPC_update: 9190 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 9191 break; 9192 case OMPC_capture: 9193 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 9194 break; 9195 case OMPC_seq_cst: 9196 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 9197 break; 9198 case OMPC_threads: 9199 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 9200 break; 9201 case OMPC_simd: 9202 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 9203 break; 9204 case OMPC_nogroup: 9205 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 9206 break; 9207 case OMPC_unified_address: 9208 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 9209 break; 9210 case OMPC_unified_shared_memory: 9211 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9212 break; 9213 case OMPC_reverse_offload: 9214 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 9215 break; 9216 case OMPC_dynamic_allocators: 9217 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 9218 break; 9219 case OMPC_if: 9220 case OMPC_final: 9221 case OMPC_num_threads: 9222 case OMPC_safelen: 9223 case OMPC_simdlen: 9224 case OMPC_collapse: 9225 case OMPC_schedule: 9226 case OMPC_private: 9227 case OMPC_firstprivate: 9228 case OMPC_lastprivate: 9229 case OMPC_shared: 9230 case OMPC_reduction: 9231 case OMPC_task_reduction: 9232 case OMPC_in_reduction: 9233 case OMPC_linear: 9234 case OMPC_aligned: 9235 case OMPC_copyin: 9236 case OMPC_copyprivate: 9237 case OMPC_default: 9238 case OMPC_proc_bind: 9239 case OMPC_threadprivate: 9240 case OMPC_flush: 9241 case OMPC_depend: 9242 case OMPC_device: 9243 case OMPC_map: 9244 case OMPC_num_teams: 9245 case OMPC_thread_limit: 9246 case OMPC_priority: 9247 case OMPC_grainsize: 9248 case OMPC_num_tasks: 9249 case OMPC_hint: 9250 case OMPC_dist_schedule: 9251 case OMPC_defaultmap: 9252 case OMPC_unknown: 9253 case OMPC_uniform: 9254 case OMPC_to: 9255 case OMPC_from: 9256 case OMPC_use_device_ptr: 9257 case OMPC_is_device_ptr: 9258 llvm_unreachable("Clause is not allowed."); 9259 } 9260 return Res; 9261 } 9262 9263 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 9264 SourceLocation EndLoc) { 9265 DSAStack->setNowaitRegion(); 9266 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 9267 } 9268 9269 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 9270 SourceLocation EndLoc) { 9271 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 9272 } 9273 9274 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 9275 SourceLocation EndLoc) { 9276 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 9277 } 9278 9279 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 9280 SourceLocation EndLoc) { 9281 return new (Context) OMPReadClause(StartLoc, EndLoc); 9282 } 9283 9284 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 9285 SourceLocation EndLoc) { 9286 return new (Context) OMPWriteClause(StartLoc, EndLoc); 9287 } 9288 9289 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 9290 SourceLocation EndLoc) { 9291 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 9292 } 9293 9294 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 9295 SourceLocation EndLoc) { 9296 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 9297 } 9298 9299 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 9300 SourceLocation EndLoc) { 9301 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 9302 } 9303 9304 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 9305 SourceLocation EndLoc) { 9306 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 9307 } 9308 9309 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 9310 SourceLocation EndLoc) { 9311 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 9312 } 9313 9314 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 9315 SourceLocation EndLoc) { 9316 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 9317 } 9318 9319 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 9320 SourceLocation EndLoc) { 9321 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 9322 } 9323 9324 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 9325 SourceLocation EndLoc) { 9326 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9327 } 9328 9329 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 9330 SourceLocation EndLoc) { 9331 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 9332 } 9333 9334 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 9335 SourceLocation EndLoc) { 9336 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 9337 } 9338 9339 OMPClause *Sema::ActOnOpenMPVarListClause( 9340 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 9341 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 9342 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 9343 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 9344 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 9345 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 9346 SourceLocation DepLinMapLoc) { 9347 OMPClause *Res = nullptr; 9348 switch (Kind) { 9349 case OMPC_private: 9350 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9351 break; 9352 case OMPC_firstprivate: 9353 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9354 break; 9355 case OMPC_lastprivate: 9356 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9357 break; 9358 case OMPC_shared: 9359 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 9360 break; 9361 case OMPC_reduction: 9362 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9363 EndLoc, ReductionIdScopeSpec, ReductionId); 9364 break; 9365 case OMPC_task_reduction: 9366 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9367 EndLoc, ReductionIdScopeSpec, 9368 ReductionId); 9369 break; 9370 case OMPC_in_reduction: 9371 Res = 9372 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9373 EndLoc, ReductionIdScopeSpec, ReductionId); 9374 break; 9375 case OMPC_linear: 9376 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 9377 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 9378 break; 9379 case OMPC_aligned: 9380 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 9381 ColonLoc, EndLoc); 9382 break; 9383 case OMPC_copyin: 9384 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 9385 break; 9386 case OMPC_copyprivate: 9387 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9388 break; 9389 case OMPC_flush: 9390 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 9391 break; 9392 case OMPC_depend: 9393 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 9394 StartLoc, LParenLoc, EndLoc); 9395 break; 9396 case OMPC_map: 9397 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 9398 DepLinMapLoc, ColonLoc, VarList, StartLoc, 9399 LParenLoc, EndLoc); 9400 break; 9401 case OMPC_to: 9402 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 9403 break; 9404 case OMPC_from: 9405 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 9406 break; 9407 case OMPC_use_device_ptr: 9408 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 9409 break; 9410 case OMPC_is_device_ptr: 9411 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 9412 break; 9413 case OMPC_if: 9414 case OMPC_final: 9415 case OMPC_num_threads: 9416 case OMPC_safelen: 9417 case OMPC_simdlen: 9418 case OMPC_collapse: 9419 case OMPC_default: 9420 case OMPC_proc_bind: 9421 case OMPC_schedule: 9422 case OMPC_ordered: 9423 case OMPC_nowait: 9424 case OMPC_untied: 9425 case OMPC_mergeable: 9426 case OMPC_threadprivate: 9427 case OMPC_read: 9428 case OMPC_write: 9429 case OMPC_update: 9430 case OMPC_capture: 9431 case OMPC_seq_cst: 9432 case OMPC_device: 9433 case OMPC_threads: 9434 case OMPC_simd: 9435 case OMPC_num_teams: 9436 case OMPC_thread_limit: 9437 case OMPC_priority: 9438 case OMPC_grainsize: 9439 case OMPC_nogroup: 9440 case OMPC_num_tasks: 9441 case OMPC_hint: 9442 case OMPC_dist_schedule: 9443 case OMPC_defaultmap: 9444 case OMPC_unknown: 9445 case OMPC_uniform: 9446 case OMPC_unified_address: 9447 case OMPC_unified_shared_memory: 9448 case OMPC_reverse_offload: 9449 case OMPC_dynamic_allocators: 9450 llvm_unreachable("Clause is not allowed."); 9451 } 9452 return Res; 9453 } 9454 9455 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 9456 ExprObjectKind OK, SourceLocation Loc) { 9457 ExprResult Res = BuildDeclRefExpr( 9458 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 9459 if (!Res.isUsable()) 9460 return ExprError(); 9461 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 9462 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 9463 if (!Res.isUsable()) 9464 return ExprError(); 9465 } 9466 if (VK != VK_LValue && Res.get()->isGLValue()) { 9467 Res = DefaultLvalueConversion(Res.get()); 9468 if (!Res.isUsable()) 9469 return ExprError(); 9470 } 9471 return Res; 9472 } 9473 9474 static std::pair<ValueDecl *, bool> 9475 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 9476 SourceRange &ERange, bool AllowArraySection = false) { 9477 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 9478 RefExpr->containsUnexpandedParameterPack()) 9479 return std::make_pair(nullptr, true); 9480 9481 // OpenMP [3.1, C/C++] 9482 // A list item is a variable name. 9483 // OpenMP [2.9.3.3, Restrictions, p.1] 9484 // A variable that is part of another variable (as an array or 9485 // structure element) cannot appear in a private clause. 9486 RefExpr = RefExpr->IgnoreParens(); 9487 enum { 9488 NoArrayExpr = -1, 9489 ArraySubscript = 0, 9490 OMPArraySection = 1 9491 } IsArrayExpr = NoArrayExpr; 9492 if (AllowArraySection) { 9493 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 9494 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 9495 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 9496 Base = TempASE->getBase()->IgnoreParenImpCasts(); 9497 RefExpr = Base; 9498 IsArrayExpr = ArraySubscript; 9499 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 9500 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 9501 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 9502 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 9503 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 9504 Base = TempASE->getBase()->IgnoreParenImpCasts(); 9505 RefExpr = Base; 9506 IsArrayExpr = OMPArraySection; 9507 } 9508 } 9509 ELoc = RefExpr->getExprLoc(); 9510 ERange = RefExpr->getSourceRange(); 9511 RefExpr = RefExpr->IgnoreParenImpCasts(); 9512 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 9513 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 9514 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 9515 (S.getCurrentThisType().isNull() || !ME || 9516 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 9517 !isa<FieldDecl>(ME->getMemberDecl()))) { 9518 if (IsArrayExpr != NoArrayExpr) { 9519 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 9520 << ERange; 9521 } else { 9522 S.Diag(ELoc, 9523 AllowArraySection 9524 ? diag::err_omp_expected_var_name_member_expr_or_array_item 9525 : diag::err_omp_expected_var_name_member_expr) 9526 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 9527 } 9528 return std::make_pair(nullptr, false); 9529 } 9530 return std::make_pair( 9531 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 9532 } 9533 9534 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 9535 SourceLocation StartLoc, 9536 SourceLocation LParenLoc, 9537 SourceLocation EndLoc) { 9538 SmallVector<Expr *, 8> Vars; 9539 SmallVector<Expr *, 8> PrivateCopies; 9540 for (Expr *RefExpr : VarList) { 9541 assert(RefExpr && "NULL expr in OpenMP private clause."); 9542 SourceLocation ELoc; 9543 SourceRange ERange; 9544 Expr *SimpleRefExpr = RefExpr; 9545 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9546 if (Res.second) { 9547 // It will be analyzed later. 9548 Vars.push_back(RefExpr); 9549 PrivateCopies.push_back(nullptr); 9550 } 9551 ValueDecl *D = Res.first; 9552 if (!D) 9553 continue; 9554 9555 QualType Type = D->getType(); 9556 auto *VD = dyn_cast<VarDecl>(D); 9557 9558 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9559 // A variable that appears in a private clause must not have an incomplete 9560 // type or a reference type. 9561 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 9562 continue; 9563 Type = Type.getNonReferenceType(); 9564 9565 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9566 // in a Construct] 9567 // Variables with the predetermined data-sharing attributes may not be 9568 // listed in data-sharing attributes clauses, except for the cases 9569 // listed below. For these exceptions only, listing a predetermined 9570 // variable in a data-sharing attribute clause is allowed and overrides 9571 // the variable's predetermined data-sharing attributes. 9572 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 9573 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 9574 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9575 << getOpenMPClauseName(OMPC_private); 9576 reportOriginalDsa(*this, DSAStack, D, DVar); 9577 continue; 9578 } 9579 9580 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9581 // Variably modified types are not supported for tasks. 9582 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 9583 isOpenMPTaskingDirective(CurrDir)) { 9584 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9585 << getOpenMPClauseName(OMPC_private) << Type 9586 << getOpenMPDirectiveName(CurrDir); 9587 bool IsDecl = 9588 !VD || 9589 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9590 Diag(D->getLocation(), 9591 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9592 << D; 9593 continue; 9594 } 9595 9596 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9597 // A list item cannot appear in both a map clause and a data-sharing 9598 // attribute clause on the same construct 9599 if (isOpenMPTargetExecutionDirective(CurrDir)) { 9600 OpenMPClauseKind ConflictKind; 9601 if (DSAStack->checkMappableExprComponentListsForDecl( 9602 VD, /*CurrentRegionOnly=*/true, 9603 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 9604 OpenMPClauseKind WhereFoundClauseKind) -> bool { 9605 ConflictKind = WhereFoundClauseKind; 9606 return true; 9607 })) { 9608 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 9609 << getOpenMPClauseName(OMPC_private) 9610 << getOpenMPClauseName(ConflictKind) 9611 << getOpenMPDirectiveName(CurrDir); 9612 reportOriginalDsa(*this, DSAStack, D, DVar); 9613 continue; 9614 } 9615 } 9616 9617 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 9618 // A variable of class type (or array thereof) that appears in a private 9619 // clause requires an accessible, unambiguous default constructor for the 9620 // class type. 9621 // Generate helper private variable and initialize it with the default 9622 // value. The address of the original variable is replaced by the address of 9623 // the new private variable in CodeGen. This new variable is not added to 9624 // IdResolver, so the code in the OpenMP region uses original variable for 9625 // proper diagnostics. 9626 Type = Type.getUnqualifiedType(); 9627 VarDecl *VDPrivate = 9628 buildVarDecl(*this, ELoc, Type, D->getName(), 9629 D->hasAttrs() ? &D->getAttrs() : nullptr, 9630 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 9631 ActOnUninitializedDecl(VDPrivate); 9632 if (VDPrivate->isInvalidDecl()) 9633 continue; 9634 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 9635 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 9636 9637 DeclRefExpr *Ref = nullptr; 9638 if (!VD && !CurContext->isDependentContext()) 9639 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9640 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 9641 Vars.push_back((VD || CurContext->isDependentContext()) 9642 ? RefExpr->IgnoreParens() 9643 : Ref); 9644 PrivateCopies.push_back(VDPrivateRefExpr); 9645 } 9646 9647 if (Vars.empty()) 9648 return nullptr; 9649 9650 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9651 PrivateCopies); 9652 } 9653 9654 namespace { 9655 class DiagsUninitializedSeveretyRAII { 9656 private: 9657 DiagnosticsEngine &Diags; 9658 SourceLocation SavedLoc; 9659 bool IsIgnored = false; 9660 9661 public: 9662 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 9663 bool IsIgnored) 9664 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 9665 if (!IsIgnored) { 9666 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 9667 /*Map*/ diag::Severity::Ignored, Loc); 9668 } 9669 } 9670 ~DiagsUninitializedSeveretyRAII() { 9671 if (!IsIgnored) 9672 Diags.popMappings(SavedLoc); 9673 } 9674 }; 9675 } 9676 9677 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 9678 SourceLocation StartLoc, 9679 SourceLocation LParenLoc, 9680 SourceLocation EndLoc) { 9681 SmallVector<Expr *, 8> Vars; 9682 SmallVector<Expr *, 8> PrivateCopies; 9683 SmallVector<Expr *, 8> Inits; 9684 SmallVector<Decl *, 4> ExprCaptures; 9685 bool IsImplicitClause = 9686 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 9687 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 9688 9689 for (Expr *RefExpr : VarList) { 9690 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 9691 SourceLocation ELoc; 9692 SourceRange ERange; 9693 Expr *SimpleRefExpr = RefExpr; 9694 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9695 if (Res.second) { 9696 // It will be analyzed later. 9697 Vars.push_back(RefExpr); 9698 PrivateCopies.push_back(nullptr); 9699 Inits.push_back(nullptr); 9700 } 9701 ValueDecl *D = Res.first; 9702 if (!D) 9703 continue; 9704 9705 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 9706 QualType Type = D->getType(); 9707 auto *VD = dyn_cast<VarDecl>(D); 9708 9709 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9710 // A variable that appears in a private clause must not have an incomplete 9711 // type or a reference type. 9712 if (RequireCompleteType(ELoc, Type, 9713 diag::err_omp_firstprivate_incomplete_type)) 9714 continue; 9715 Type = Type.getNonReferenceType(); 9716 9717 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 9718 // A variable of class type (or array thereof) that appears in a private 9719 // clause requires an accessible, unambiguous copy constructor for the 9720 // class type. 9721 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 9722 9723 // If an implicit firstprivate variable found it was checked already. 9724 DSAStackTy::DSAVarData TopDVar; 9725 if (!IsImplicitClause) { 9726 DSAStackTy::DSAVarData DVar = 9727 DSAStack->getTopDSA(D, /*FromParent=*/false); 9728 TopDVar = DVar; 9729 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9730 bool IsConstant = ElemType.isConstant(Context); 9731 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 9732 // A list item that specifies a given variable may not appear in more 9733 // than one clause on the same directive, except that a variable may be 9734 // specified in both firstprivate and lastprivate clauses. 9735 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 9736 // A list item may appear in a firstprivate or lastprivate clause but not 9737 // both. 9738 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 9739 (isOpenMPDistributeDirective(CurrDir) || 9740 DVar.CKind != OMPC_lastprivate) && 9741 DVar.RefExpr) { 9742 Diag(ELoc, diag::err_omp_wrong_dsa) 9743 << getOpenMPClauseName(DVar.CKind) 9744 << getOpenMPClauseName(OMPC_firstprivate); 9745 reportOriginalDsa(*this, DSAStack, D, DVar); 9746 continue; 9747 } 9748 9749 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9750 // in a Construct] 9751 // Variables with the predetermined data-sharing attributes may not be 9752 // listed in data-sharing attributes clauses, except for the cases 9753 // listed below. For these exceptions only, listing a predetermined 9754 // variable in a data-sharing attribute clause is allowed and overrides 9755 // the variable's predetermined data-sharing attributes. 9756 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9757 // in a Construct, C/C++, p.2] 9758 // Variables with const-qualified type having no mutable member may be 9759 // listed in a firstprivate clause, even if they are static data members. 9760 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 9761 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 9762 Diag(ELoc, diag::err_omp_wrong_dsa) 9763 << getOpenMPClauseName(DVar.CKind) 9764 << getOpenMPClauseName(OMPC_firstprivate); 9765 reportOriginalDsa(*this, DSAStack, D, DVar); 9766 continue; 9767 } 9768 9769 // OpenMP [2.9.3.4, Restrictions, p.2] 9770 // A list item that is private within a parallel region must not appear 9771 // in a firstprivate clause on a worksharing construct if any of the 9772 // worksharing regions arising from the worksharing construct ever bind 9773 // to any of the parallel regions arising from the parallel construct. 9774 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 9775 // A list item that is private within a teams region must not appear in a 9776 // firstprivate clause on a distribute construct if any of the distribute 9777 // regions arising from the distribute construct ever bind to any of the 9778 // teams regions arising from the teams construct. 9779 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 9780 // A list item that appears in a reduction clause of a teams construct 9781 // must not appear in a firstprivate clause on a distribute construct if 9782 // any of the distribute regions arising from the distribute construct 9783 // ever bind to any of the teams regions arising from the teams construct. 9784 if ((isOpenMPWorksharingDirective(CurrDir) || 9785 isOpenMPDistributeDirective(CurrDir)) && 9786 !isOpenMPParallelDirective(CurrDir) && 9787 !isOpenMPTeamsDirective(CurrDir)) { 9788 DVar = DSAStack->getImplicitDSA(D, true); 9789 if (DVar.CKind != OMPC_shared && 9790 (isOpenMPParallelDirective(DVar.DKind) || 9791 isOpenMPTeamsDirective(DVar.DKind) || 9792 DVar.DKind == OMPD_unknown)) { 9793 Diag(ELoc, diag::err_omp_required_access) 9794 << getOpenMPClauseName(OMPC_firstprivate) 9795 << getOpenMPClauseName(OMPC_shared); 9796 reportOriginalDsa(*this, DSAStack, D, DVar); 9797 continue; 9798 } 9799 } 9800 // OpenMP [2.9.3.4, Restrictions, p.3] 9801 // A list item that appears in a reduction clause of a parallel construct 9802 // must not appear in a firstprivate clause on a worksharing or task 9803 // construct if any of the worksharing or task regions arising from the 9804 // worksharing or task construct ever bind to any of the parallel regions 9805 // arising from the parallel construct. 9806 // OpenMP [2.9.3.4, Restrictions, p.4] 9807 // A list item that appears in a reduction clause in worksharing 9808 // construct must not appear in a firstprivate clause in a task construct 9809 // encountered during execution of any of the worksharing regions arising 9810 // from the worksharing construct. 9811 if (isOpenMPTaskingDirective(CurrDir)) { 9812 DVar = DSAStack->hasInnermostDSA( 9813 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 9814 [](OpenMPDirectiveKind K) { 9815 return isOpenMPParallelDirective(K) || 9816 isOpenMPWorksharingDirective(K) || 9817 isOpenMPTeamsDirective(K); 9818 }, 9819 /*FromParent=*/true); 9820 if (DVar.CKind == OMPC_reduction && 9821 (isOpenMPParallelDirective(DVar.DKind) || 9822 isOpenMPWorksharingDirective(DVar.DKind) || 9823 isOpenMPTeamsDirective(DVar.DKind))) { 9824 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 9825 << getOpenMPDirectiveName(DVar.DKind); 9826 reportOriginalDsa(*this, DSAStack, D, DVar); 9827 continue; 9828 } 9829 } 9830 9831 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9832 // A list item cannot appear in both a map clause and a data-sharing 9833 // attribute clause on the same construct 9834 if (isOpenMPTargetExecutionDirective(CurrDir)) { 9835 OpenMPClauseKind ConflictKind; 9836 if (DSAStack->checkMappableExprComponentListsForDecl( 9837 VD, /*CurrentRegionOnly=*/true, 9838 [&ConflictKind]( 9839 OMPClauseMappableExprCommon::MappableExprComponentListRef, 9840 OpenMPClauseKind WhereFoundClauseKind) { 9841 ConflictKind = WhereFoundClauseKind; 9842 return true; 9843 })) { 9844 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 9845 << getOpenMPClauseName(OMPC_firstprivate) 9846 << getOpenMPClauseName(ConflictKind) 9847 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9848 reportOriginalDsa(*this, DSAStack, D, DVar); 9849 continue; 9850 } 9851 } 9852 } 9853 9854 // Variably modified types are not supported for tasks. 9855 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 9856 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 9857 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9858 << getOpenMPClauseName(OMPC_firstprivate) << Type 9859 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9860 bool IsDecl = 9861 !VD || 9862 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9863 Diag(D->getLocation(), 9864 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9865 << D; 9866 continue; 9867 } 9868 9869 Type = Type.getUnqualifiedType(); 9870 VarDecl *VDPrivate = 9871 buildVarDecl(*this, ELoc, Type, D->getName(), 9872 D->hasAttrs() ? &D->getAttrs() : nullptr, 9873 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 9874 // Generate helper private variable and initialize it with the value of the 9875 // original variable. The address of the original variable is replaced by 9876 // the address of the new private variable in the CodeGen. This new variable 9877 // is not added to IdResolver, so the code in the OpenMP region uses 9878 // original variable for proper diagnostics and variable capturing. 9879 Expr *VDInitRefExpr = nullptr; 9880 // For arrays generate initializer for single element and replace it by the 9881 // original array element in CodeGen. 9882 if (Type->isArrayType()) { 9883 VarDecl *VDInit = 9884 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 9885 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 9886 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 9887 ElemType = ElemType.getUnqualifiedType(); 9888 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 9889 ".firstprivate.temp"); 9890 InitializedEntity Entity = 9891 InitializedEntity::InitializeVariable(VDInitTemp); 9892 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 9893 9894 InitializationSequence InitSeq(*this, Entity, Kind, Init); 9895 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 9896 if (Result.isInvalid()) 9897 VDPrivate->setInvalidDecl(); 9898 else 9899 VDPrivate->setInit(Result.getAs<Expr>()); 9900 // Remove temp variable declaration. 9901 Context.Deallocate(VDInitTemp); 9902 } else { 9903 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 9904 ".firstprivate.temp"); 9905 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 9906 RefExpr->getExprLoc()); 9907 AddInitializerToDecl(VDPrivate, 9908 DefaultLvalueConversion(VDInitRefExpr).get(), 9909 /*DirectInit=*/false); 9910 } 9911 if (VDPrivate->isInvalidDecl()) { 9912 if (IsImplicitClause) { 9913 Diag(RefExpr->getExprLoc(), 9914 diag::note_omp_task_predetermined_firstprivate_here); 9915 } 9916 continue; 9917 } 9918 CurContext->addDecl(VDPrivate); 9919 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 9920 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 9921 RefExpr->getExprLoc()); 9922 DeclRefExpr *Ref = nullptr; 9923 if (!VD && !CurContext->isDependentContext()) { 9924 if (TopDVar.CKind == OMPC_lastprivate) { 9925 Ref = TopDVar.PrivateCopy; 9926 } else { 9927 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9928 if (!isOpenMPCapturedDecl(D)) 9929 ExprCaptures.push_back(Ref->getDecl()); 9930 } 9931 } 9932 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 9933 Vars.push_back((VD || CurContext->isDependentContext()) 9934 ? RefExpr->IgnoreParens() 9935 : Ref); 9936 PrivateCopies.push_back(VDPrivateRefExpr); 9937 Inits.push_back(VDInitRefExpr); 9938 } 9939 9940 if (Vars.empty()) 9941 return nullptr; 9942 9943 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9944 Vars, PrivateCopies, Inits, 9945 buildPreInits(Context, ExprCaptures)); 9946 } 9947 9948 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 9949 SourceLocation StartLoc, 9950 SourceLocation LParenLoc, 9951 SourceLocation EndLoc) { 9952 SmallVector<Expr *, 8> Vars; 9953 SmallVector<Expr *, 8> SrcExprs; 9954 SmallVector<Expr *, 8> DstExprs; 9955 SmallVector<Expr *, 8> AssignmentOps; 9956 SmallVector<Decl *, 4> ExprCaptures; 9957 SmallVector<Expr *, 4> ExprPostUpdates; 9958 for (Expr *RefExpr : VarList) { 9959 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9960 SourceLocation ELoc; 9961 SourceRange ERange; 9962 Expr *SimpleRefExpr = RefExpr; 9963 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9964 if (Res.second) { 9965 // It will be analyzed later. 9966 Vars.push_back(RefExpr); 9967 SrcExprs.push_back(nullptr); 9968 DstExprs.push_back(nullptr); 9969 AssignmentOps.push_back(nullptr); 9970 } 9971 ValueDecl *D = Res.first; 9972 if (!D) 9973 continue; 9974 9975 QualType Type = D->getType(); 9976 auto *VD = dyn_cast<VarDecl>(D); 9977 9978 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 9979 // A variable that appears in a lastprivate clause must not have an 9980 // incomplete type or a reference type. 9981 if (RequireCompleteType(ELoc, Type, 9982 diag::err_omp_lastprivate_incomplete_type)) 9983 continue; 9984 Type = Type.getNonReferenceType(); 9985 9986 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9987 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 9988 // in a Construct] 9989 // Variables with the predetermined data-sharing attributes may not be 9990 // listed in data-sharing attributes clauses, except for the cases 9991 // listed below. 9992 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 9993 // A list item may appear in a firstprivate or lastprivate clause but not 9994 // both. 9995 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 9996 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 9997 (isOpenMPDistributeDirective(CurrDir) || 9998 DVar.CKind != OMPC_firstprivate) && 9999 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 10000 Diag(ELoc, diag::err_omp_wrong_dsa) 10001 << getOpenMPClauseName(DVar.CKind) 10002 << getOpenMPClauseName(OMPC_lastprivate); 10003 reportOriginalDsa(*this, DSAStack, D, DVar); 10004 continue; 10005 } 10006 10007 // OpenMP [2.14.3.5, Restrictions, p.2] 10008 // A list item that is private within a parallel region, or that appears in 10009 // the reduction clause of a parallel construct, must not appear in a 10010 // lastprivate clause on a worksharing construct if any of the corresponding 10011 // worksharing regions ever binds to any of the corresponding parallel 10012 // regions. 10013 DSAStackTy::DSAVarData TopDVar = DVar; 10014 if (isOpenMPWorksharingDirective(CurrDir) && 10015 !isOpenMPParallelDirective(CurrDir) && 10016 !isOpenMPTeamsDirective(CurrDir)) { 10017 DVar = DSAStack->getImplicitDSA(D, true); 10018 if (DVar.CKind != OMPC_shared) { 10019 Diag(ELoc, diag::err_omp_required_access) 10020 << getOpenMPClauseName(OMPC_lastprivate) 10021 << getOpenMPClauseName(OMPC_shared); 10022 reportOriginalDsa(*this, DSAStack, D, DVar); 10023 continue; 10024 } 10025 } 10026 10027 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 10028 // A variable of class type (or array thereof) that appears in a 10029 // lastprivate clause requires an accessible, unambiguous default 10030 // constructor for the class type, unless the list item is also specified 10031 // in a firstprivate clause. 10032 // A variable of class type (or array thereof) that appears in a 10033 // lastprivate clause requires an accessible, unambiguous copy assignment 10034 // operator for the class type. 10035 Type = Context.getBaseElementType(Type).getNonReferenceType(); 10036 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 10037 Type.getUnqualifiedType(), ".lastprivate.src", 10038 D->hasAttrs() ? &D->getAttrs() : nullptr); 10039 DeclRefExpr *PseudoSrcExpr = 10040 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 10041 VarDecl *DstVD = 10042 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 10043 D->hasAttrs() ? &D->getAttrs() : nullptr); 10044 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10045 // For arrays generate assignment operation for single element and replace 10046 // it by the original array element in CodeGen. 10047 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 10048 PseudoDstExpr, PseudoSrcExpr); 10049 if (AssignmentOp.isInvalid()) 10050 continue; 10051 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 10052 /*DiscardedValue=*/true); 10053 if (AssignmentOp.isInvalid()) 10054 continue; 10055 10056 DeclRefExpr *Ref = nullptr; 10057 if (!VD && !CurContext->isDependentContext()) { 10058 if (TopDVar.CKind == OMPC_firstprivate) { 10059 Ref = TopDVar.PrivateCopy; 10060 } else { 10061 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10062 if (!isOpenMPCapturedDecl(D)) 10063 ExprCaptures.push_back(Ref->getDecl()); 10064 } 10065 if (TopDVar.CKind == OMPC_firstprivate || 10066 (!isOpenMPCapturedDecl(D) && 10067 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 10068 ExprResult RefRes = DefaultLvalueConversion(Ref); 10069 if (!RefRes.isUsable()) 10070 continue; 10071 ExprResult PostUpdateRes = 10072 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10073 RefRes.get()); 10074 if (!PostUpdateRes.isUsable()) 10075 continue; 10076 ExprPostUpdates.push_back( 10077 IgnoredValueConversions(PostUpdateRes.get()).get()); 10078 } 10079 } 10080 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 10081 Vars.push_back((VD || CurContext->isDependentContext()) 10082 ? RefExpr->IgnoreParens() 10083 : Ref); 10084 SrcExprs.push_back(PseudoSrcExpr); 10085 DstExprs.push_back(PseudoDstExpr); 10086 AssignmentOps.push_back(AssignmentOp.get()); 10087 } 10088 10089 if (Vars.empty()) 10090 return nullptr; 10091 10092 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10093 Vars, SrcExprs, DstExprs, AssignmentOps, 10094 buildPreInits(Context, ExprCaptures), 10095 buildPostUpdate(*this, ExprPostUpdates)); 10096 } 10097 10098 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 10099 SourceLocation StartLoc, 10100 SourceLocation LParenLoc, 10101 SourceLocation EndLoc) { 10102 SmallVector<Expr *, 8> Vars; 10103 for (Expr *RefExpr : VarList) { 10104 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10105 SourceLocation ELoc; 10106 SourceRange ERange; 10107 Expr *SimpleRefExpr = RefExpr; 10108 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10109 if (Res.second) { 10110 // It will be analyzed later. 10111 Vars.push_back(RefExpr); 10112 } 10113 ValueDecl *D = Res.first; 10114 if (!D) 10115 continue; 10116 10117 auto *VD = dyn_cast<VarDecl>(D); 10118 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10119 // in a Construct] 10120 // Variables with the predetermined data-sharing attributes may not be 10121 // listed in data-sharing attributes clauses, except for the cases 10122 // listed below. For these exceptions only, listing a predetermined 10123 // variable in a data-sharing attribute clause is allowed and overrides 10124 // the variable's predetermined data-sharing attributes. 10125 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10126 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 10127 DVar.RefExpr) { 10128 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10129 << getOpenMPClauseName(OMPC_shared); 10130 reportOriginalDsa(*this, DSAStack, D, DVar); 10131 continue; 10132 } 10133 10134 DeclRefExpr *Ref = nullptr; 10135 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 10136 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10137 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 10138 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 10139 ? RefExpr->IgnoreParens() 10140 : Ref); 10141 } 10142 10143 if (Vars.empty()) 10144 return nullptr; 10145 10146 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 10147 } 10148 10149 namespace { 10150 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 10151 DSAStackTy *Stack; 10152 10153 public: 10154 bool VisitDeclRefExpr(DeclRefExpr *E) { 10155 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 10156 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 10157 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 10158 return false; 10159 if (DVar.CKind != OMPC_unknown) 10160 return true; 10161 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 10162 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 10163 /*FromParent=*/true); 10164 return DVarPrivate.CKind != OMPC_unknown; 10165 } 10166 return false; 10167 } 10168 bool VisitStmt(Stmt *S) { 10169 for (Stmt *Child : S->children()) { 10170 if (Child && Visit(Child)) 10171 return true; 10172 } 10173 return false; 10174 } 10175 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 10176 }; 10177 } // namespace 10178 10179 namespace { 10180 // Transform MemberExpression for specified FieldDecl of current class to 10181 // DeclRefExpr to specified OMPCapturedExprDecl. 10182 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 10183 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 10184 ValueDecl *Field = nullptr; 10185 DeclRefExpr *CapturedExpr = nullptr; 10186 10187 public: 10188 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 10189 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 10190 10191 ExprResult TransformMemberExpr(MemberExpr *E) { 10192 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 10193 E->getMemberDecl() == Field) { 10194 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 10195 return CapturedExpr; 10196 } 10197 return BaseTransform::TransformMemberExpr(E); 10198 } 10199 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 10200 }; 10201 } // namespace 10202 10203 template <typename T, typename U> 10204 static T filterLookupForUDR(SmallVectorImpl<U> &Lookups, 10205 const llvm::function_ref<T(ValueDecl *)> Gen) { 10206 for (U &Set : Lookups) { 10207 for (auto *D : Set) { 10208 if (T Res = Gen(cast<ValueDecl>(D))) 10209 return Res; 10210 } 10211 } 10212 return T(); 10213 } 10214 10215 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 10216 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 10217 10218 for (auto RD : D->redecls()) { 10219 // Don't bother with extra checks if we already know this one isn't visible. 10220 if (RD == D) 10221 continue; 10222 10223 auto ND = cast<NamedDecl>(RD); 10224 if (LookupResult::isVisible(SemaRef, ND)) 10225 return ND; 10226 } 10227 10228 return nullptr; 10229 } 10230 10231 static void 10232 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId, 10233 SourceLocation Loc, QualType Ty, 10234 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 10235 // Find all of the associated namespaces and classes based on the 10236 // arguments we have. 10237 Sema::AssociatedNamespaceSet AssociatedNamespaces; 10238 Sema::AssociatedClassSet AssociatedClasses; 10239 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 10240 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 10241 AssociatedClasses); 10242 10243 // C++ [basic.lookup.argdep]p3: 10244 // Let X be the lookup set produced by unqualified lookup (3.4.1) 10245 // and let Y be the lookup set produced by argument dependent 10246 // lookup (defined as follows). If X contains [...] then Y is 10247 // empty. Otherwise Y is the set of declarations found in the 10248 // namespaces associated with the argument types as described 10249 // below. The set of declarations found by the lookup of the name 10250 // is the union of X and Y. 10251 // 10252 // Here, we compute Y and add its members to the overloaded 10253 // candidate set. 10254 for (auto *NS : AssociatedNamespaces) { 10255 // When considering an associated namespace, the lookup is the 10256 // same as the lookup performed when the associated namespace is 10257 // used as a qualifier (3.4.3.2) except that: 10258 // 10259 // -- Any using-directives in the associated namespace are 10260 // ignored. 10261 // 10262 // -- Any namespace-scope friend functions declared in 10263 // associated classes are visible within their respective 10264 // namespaces even if they are not visible during an ordinary 10265 // lookup (11.4). 10266 DeclContext::lookup_result R = NS->lookup(ReductionId.getName()); 10267 for (auto *D : R) { 10268 auto *Underlying = D; 10269 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10270 Underlying = USD->getTargetDecl(); 10271 10272 if (!isa<OMPDeclareReductionDecl>(Underlying)) 10273 continue; 10274 10275 if (!SemaRef.isVisible(D)) { 10276 D = findAcceptableDecl(SemaRef, D); 10277 if (!D) 10278 continue; 10279 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10280 Underlying = USD->getTargetDecl(); 10281 } 10282 Lookups.emplace_back(); 10283 Lookups.back().addDecl(Underlying); 10284 } 10285 } 10286 } 10287 10288 static ExprResult 10289 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 10290 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 10291 const DeclarationNameInfo &ReductionId, QualType Ty, 10292 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 10293 if (ReductionIdScopeSpec.isInvalid()) 10294 return ExprError(); 10295 SmallVector<UnresolvedSet<8>, 4> Lookups; 10296 if (S) { 10297 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10298 Lookup.suppressDiagnostics(); 10299 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 10300 NamedDecl *D = Lookup.getRepresentativeDecl(); 10301 do { 10302 S = S->getParent(); 10303 } while (S && !S->isDeclScope(D)); 10304 if (S) 10305 S = S->getParent(); 10306 Lookups.emplace_back(); 10307 Lookups.back().append(Lookup.begin(), Lookup.end()); 10308 Lookup.clear(); 10309 } 10310 } else if (auto *ULE = 10311 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 10312 Lookups.push_back(UnresolvedSet<8>()); 10313 Decl *PrevD = nullptr; 10314 for (NamedDecl *D : ULE->decls()) { 10315 if (D == PrevD) 10316 Lookups.push_back(UnresolvedSet<8>()); 10317 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 10318 Lookups.back().addDecl(DRD); 10319 PrevD = D; 10320 } 10321 } 10322 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 10323 Ty->isInstantiationDependentType() || 10324 Ty->containsUnexpandedParameterPack() || 10325 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) { 10326 return !D->isInvalidDecl() && 10327 (D->getType()->isDependentType() || 10328 D->getType()->isInstantiationDependentType() || 10329 D->getType()->containsUnexpandedParameterPack()); 10330 })) { 10331 UnresolvedSet<8> ResSet; 10332 for (const UnresolvedSet<8> &Set : Lookups) { 10333 if (Set.empty()) 10334 continue; 10335 ResSet.append(Set.begin(), Set.end()); 10336 // The last item marks the end of all declarations at the specified scope. 10337 ResSet.addDecl(Set[Set.size() - 1]); 10338 } 10339 return UnresolvedLookupExpr::Create( 10340 SemaRef.Context, /*NamingClass=*/nullptr, 10341 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 10342 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 10343 } 10344 // Lookup inside the classes. 10345 // C++ [over.match.oper]p3: 10346 // For a unary operator @ with an operand of a type whose 10347 // cv-unqualified version is T1, and for a binary operator @ with 10348 // a left operand of a type whose cv-unqualified version is T1 and 10349 // a right operand of a type whose cv-unqualified version is T2, 10350 // three sets of candidate functions, designated member 10351 // candidates, non-member candidates and built-in candidates, are 10352 // constructed as follows: 10353 // -- If T1 is a complete class type or a class currently being 10354 // defined, the set of member candidates is the result of the 10355 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 10356 // the set of member candidates is empty. 10357 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10358 Lookup.suppressDiagnostics(); 10359 if (const auto *TyRec = Ty->getAs<RecordType>()) { 10360 // Complete the type if it can be completed. 10361 // If the type is neither complete nor being defined, bail out now. 10362 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 10363 TyRec->getDecl()->getDefinition()) { 10364 Lookup.clear(); 10365 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 10366 if (Lookup.empty()) { 10367 Lookups.emplace_back(); 10368 Lookups.back().append(Lookup.begin(), Lookup.end()); 10369 } 10370 } 10371 } 10372 // Perform ADL. 10373 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 10374 if (auto *VD = filterLookupForUDR<ValueDecl *>( 10375 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 10376 if (!D->isInvalidDecl() && 10377 SemaRef.Context.hasSameType(D->getType(), Ty)) 10378 return D; 10379 return nullptr; 10380 })) 10381 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 10382 if (auto *VD = filterLookupForUDR<ValueDecl *>( 10383 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 10384 if (!D->isInvalidDecl() && 10385 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 10386 !Ty.isMoreQualifiedThan(D->getType())) 10387 return D; 10388 return nullptr; 10389 })) { 10390 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 10391 /*DetectVirtual=*/false); 10392 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 10393 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 10394 VD->getType().getUnqualifiedType()))) { 10395 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 10396 /*DiagID=*/0) != 10397 Sema::AR_inaccessible) { 10398 SemaRef.BuildBasePathArray(Paths, BasePath); 10399 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 10400 } 10401 } 10402 } 10403 } 10404 if (ReductionIdScopeSpec.isSet()) { 10405 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 10406 return ExprError(); 10407 } 10408 return ExprEmpty(); 10409 } 10410 10411 namespace { 10412 /// Data for the reduction-based clauses. 10413 struct ReductionData { 10414 /// List of original reduction items. 10415 SmallVector<Expr *, 8> Vars; 10416 /// List of private copies of the reduction items. 10417 SmallVector<Expr *, 8> Privates; 10418 /// LHS expressions for the reduction_op expressions. 10419 SmallVector<Expr *, 8> LHSs; 10420 /// RHS expressions for the reduction_op expressions. 10421 SmallVector<Expr *, 8> RHSs; 10422 /// Reduction operation expression. 10423 SmallVector<Expr *, 8> ReductionOps; 10424 /// Taskgroup descriptors for the corresponding reduction items in 10425 /// in_reduction clauses. 10426 SmallVector<Expr *, 8> TaskgroupDescriptors; 10427 /// List of captures for clause. 10428 SmallVector<Decl *, 4> ExprCaptures; 10429 /// List of postupdate expressions. 10430 SmallVector<Expr *, 4> ExprPostUpdates; 10431 ReductionData() = delete; 10432 /// Reserves required memory for the reduction data. 10433 ReductionData(unsigned Size) { 10434 Vars.reserve(Size); 10435 Privates.reserve(Size); 10436 LHSs.reserve(Size); 10437 RHSs.reserve(Size); 10438 ReductionOps.reserve(Size); 10439 TaskgroupDescriptors.reserve(Size); 10440 ExprCaptures.reserve(Size); 10441 ExprPostUpdates.reserve(Size); 10442 } 10443 /// Stores reduction item and reduction operation only (required for dependent 10444 /// reduction item). 10445 void push(Expr *Item, Expr *ReductionOp) { 10446 Vars.emplace_back(Item); 10447 Privates.emplace_back(nullptr); 10448 LHSs.emplace_back(nullptr); 10449 RHSs.emplace_back(nullptr); 10450 ReductionOps.emplace_back(ReductionOp); 10451 TaskgroupDescriptors.emplace_back(nullptr); 10452 } 10453 /// Stores reduction data. 10454 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 10455 Expr *TaskgroupDescriptor) { 10456 Vars.emplace_back(Item); 10457 Privates.emplace_back(Private); 10458 LHSs.emplace_back(LHS); 10459 RHSs.emplace_back(RHS); 10460 ReductionOps.emplace_back(ReductionOp); 10461 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 10462 } 10463 }; 10464 } // namespace 10465 10466 static bool checkOMPArraySectionConstantForReduction( 10467 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 10468 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 10469 const Expr *Length = OASE->getLength(); 10470 if (Length == nullptr) { 10471 // For array sections of the form [1:] or [:], we would need to analyze 10472 // the lower bound... 10473 if (OASE->getColonLoc().isValid()) 10474 return false; 10475 10476 // This is an array subscript which has implicit length 1! 10477 SingleElement = true; 10478 ArraySizes.push_back(llvm::APSInt::get(1)); 10479 } else { 10480 llvm::APSInt ConstantLengthValue; 10481 if (!Length->EvaluateAsInt(ConstantLengthValue, Context)) 10482 return false; 10483 10484 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 10485 ArraySizes.push_back(ConstantLengthValue); 10486 } 10487 10488 // Get the base of this array section and walk up from there. 10489 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 10490 10491 // We require length = 1 for all array sections except the right-most to 10492 // guarantee that the memory region is contiguous and has no holes in it. 10493 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 10494 Length = TempOASE->getLength(); 10495 if (Length == nullptr) { 10496 // For array sections of the form [1:] or [:], we would need to analyze 10497 // the lower bound... 10498 if (OASE->getColonLoc().isValid()) 10499 return false; 10500 10501 // This is an array subscript which has implicit length 1! 10502 ArraySizes.push_back(llvm::APSInt::get(1)); 10503 } else { 10504 llvm::APSInt ConstantLengthValue; 10505 if (!Length->EvaluateAsInt(ConstantLengthValue, Context) || 10506 ConstantLengthValue.getSExtValue() != 1) 10507 return false; 10508 10509 ArraySizes.push_back(ConstantLengthValue); 10510 } 10511 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 10512 } 10513 10514 // If we have a single element, we don't need to add the implicit lengths. 10515 if (!SingleElement) { 10516 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 10517 // Has implicit length 1! 10518 ArraySizes.push_back(llvm::APSInt::get(1)); 10519 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10520 } 10521 } 10522 10523 // This array section can be privatized as a single value or as a constant 10524 // sized array. 10525 return true; 10526 } 10527 10528 static bool actOnOMPReductionKindClause( 10529 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 10530 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10531 SourceLocation ColonLoc, SourceLocation EndLoc, 10532 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10533 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 10534 DeclarationName DN = ReductionId.getName(); 10535 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 10536 BinaryOperatorKind BOK = BO_Comma; 10537 10538 ASTContext &Context = S.Context; 10539 // OpenMP [2.14.3.6, reduction clause] 10540 // C 10541 // reduction-identifier is either an identifier or one of the following 10542 // operators: +, -, *, &, |, ^, && and || 10543 // C++ 10544 // reduction-identifier is either an id-expression or one of the following 10545 // operators: +, -, *, &, |, ^, && and || 10546 switch (OOK) { 10547 case OO_Plus: 10548 case OO_Minus: 10549 BOK = BO_Add; 10550 break; 10551 case OO_Star: 10552 BOK = BO_Mul; 10553 break; 10554 case OO_Amp: 10555 BOK = BO_And; 10556 break; 10557 case OO_Pipe: 10558 BOK = BO_Or; 10559 break; 10560 case OO_Caret: 10561 BOK = BO_Xor; 10562 break; 10563 case OO_AmpAmp: 10564 BOK = BO_LAnd; 10565 break; 10566 case OO_PipePipe: 10567 BOK = BO_LOr; 10568 break; 10569 case OO_New: 10570 case OO_Delete: 10571 case OO_Array_New: 10572 case OO_Array_Delete: 10573 case OO_Slash: 10574 case OO_Percent: 10575 case OO_Tilde: 10576 case OO_Exclaim: 10577 case OO_Equal: 10578 case OO_Less: 10579 case OO_Greater: 10580 case OO_LessEqual: 10581 case OO_GreaterEqual: 10582 case OO_PlusEqual: 10583 case OO_MinusEqual: 10584 case OO_StarEqual: 10585 case OO_SlashEqual: 10586 case OO_PercentEqual: 10587 case OO_CaretEqual: 10588 case OO_AmpEqual: 10589 case OO_PipeEqual: 10590 case OO_LessLess: 10591 case OO_GreaterGreater: 10592 case OO_LessLessEqual: 10593 case OO_GreaterGreaterEqual: 10594 case OO_EqualEqual: 10595 case OO_ExclaimEqual: 10596 case OO_Spaceship: 10597 case OO_PlusPlus: 10598 case OO_MinusMinus: 10599 case OO_Comma: 10600 case OO_ArrowStar: 10601 case OO_Arrow: 10602 case OO_Call: 10603 case OO_Subscript: 10604 case OO_Conditional: 10605 case OO_Coawait: 10606 case NUM_OVERLOADED_OPERATORS: 10607 llvm_unreachable("Unexpected reduction identifier"); 10608 case OO_None: 10609 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 10610 if (II->isStr("max")) 10611 BOK = BO_GT; 10612 else if (II->isStr("min")) 10613 BOK = BO_LT; 10614 } 10615 break; 10616 } 10617 SourceRange ReductionIdRange; 10618 if (ReductionIdScopeSpec.isValid()) 10619 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 10620 else 10621 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 10622 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 10623 10624 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 10625 bool FirstIter = true; 10626 for (Expr *RefExpr : VarList) { 10627 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 10628 // OpenMP [2.1, C/C++] 10629 // A list item is a variable or array section, subject to the restrictions 10630 // specified in Section 2.4 on page 42 and in each of the sections 10631 // describing clauses and directives for which a list appears. 10632 // OpenMP [2.14.3.3, Restrictions, p.1] 10633 // A variable that is part of another variable (as an array or 10634 // structure element) cannot appear in a private clause. 10635 if (!FirstIter && IR != ER) 10636 ++IR; 10637 FirstIter = false; 10638 SourceLocation ELoc; 10639 SourceRange ERange; 10640 Expr *SimpleRefExpr = RefExpr; 10641 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 10642 /*AllowArraySection=*/true); 10643 if (Res.second) { 10644 // Try to find 'declare reduction' corresponding construct before using 10645 // builtin/overloaded operators. 10646 QualType Type = Context.DependentTy; 10647 CXXCastPath BasePath; 10648 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10649 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10650 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10651 Expr *ReductionOp = nullptr; 10652 if (S.CurContext->isDependentContext() && 10653 (DeclareReductionRef.isUnset() || 10654 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 10655 ReductionOp = DeclareReductionRef.get(); 10656 // It will be analyzed later. 10657 RD.push(RefExpr, ReductionOp); 10658 } 10659 ValueDecl *D = Res.first; 10660 if (!D) 10661 continue; 10662 10663 Expr *TaskgroupDescriptor = nullptr; 10664 QualType Type; 10665 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 10666 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 10667 if (ASE) { 10668 Type = ASE->getType().getNonReferenceType(); 10669 } else if (OASE) { 10670 QualType BaseType = 10671 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 10672 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 10673 Type = ATy->getElementType(); 10674 else 10675 Type = BaseType->getPointeeType(); 10676 Type = Type.getNonReferenceType(); 10677 } else { 10678 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 10679 } 10680 auto *VD = dyn_cast<VarDecl>(D); 10681 10682 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10683 // A variable that appears in a private clause must not have an incomplete 10684 // type or a reference type. 10685 if (S.RequireCompleteType(ELoc, D->getType(), 10686 diag::err_omp_reduction_incomplete_type)) 10687 continue; 10688 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10689 // A list item that appears in a reduction clause must not be 10690 // const-qualified. 10691 if (Type.getNonReferenceType().isConstant(Context)) { 10692 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange; 10693 if (!ASE && !OASE) { 10694 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10695 VarDecl::DeclarationOnly; 10696 S.Diag(D->getLocation(), 10697 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10698 << D; 10699 } 10700 continue; 10701 } 10702 10703 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 10704 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 10705 // If a list-item is a reference type then it must bind to the same object 10706 // for all threads of the team. 10707 if (!ASE && !OASE) { 10708 if (VD) { 10709 VarDecl *VDDef = VD->getDefinition(); 10710 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 10711 DSARefChecker Check(Stack); 10712 if (Check.Visit(VDDef->getInit())) { 10713 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 10714 << getOpenMPClauseName(ClauseKind) << ERange; 10715 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 10716 continue; 10717 } 10718 } 10719 } 10720 10721 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10722 // in a Construct] 10723 // Variables with the predetermined data-sharing attributes may not be 10724 // listed in data-sharing attributes clauses, except for the cases 10725 // listed below. For these exceptions only, listing a predetermined 10726 // variable in a data-sharing attribute clause is allowed and overrides 10727 // the variable's predetermined data-sharing attributes. 10728 // OpenMP [2.14.3.6, Restrictions, p.3] 10729 // Any number of reduction clauses can be specified on the directive, 10730 // but a list item can appear only once in the reduction clauses for that 10731 // directive. 10732 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 10733 if (DVar.CKind == OMPC_reduction) { 10734 S.Diag(ELoc, diag::err_omp_once_referenced) 10735 << getOpenMPClauseName(ClauseKind); 10736 if (DVar.RefExpr) 10737 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 10738 continue; 10739 } 10740 if (DVar.CKind != OMPC_unknown) { 10741 S.Diag(ELoc, diag::err_omp_wrong_dsa) 10742 << getOpenMPClauseName(DVar.CKind) 10743 << getOpenMPClauseName(OMPC_reduction); 10744 reportOriginalDsa(S, Stack, D, DVar); 10745 continue; 10746 } 10747 10748 // OpenMP [2.14.3.6, Restrictions, p.1] 10749 // A list item that appears in a reduction clause of a worksharing 10750 // construct must be shared in the parallel regions to which any of the 10751 // worksharing regions arising from the worksharing construct bind. 10752 if (isOpenMPWorksharingDirective(CurrDir) && 10753 !isOpenMPParallelDirective(CurrDir) && 10754 !isOpenMPTeamsDirective(CurrDir)) { 10755 DVar = Stack->getImplicitDSA(D, true); 10756 if (DVar.CKind != OMPC_shared) { 10757 S.Diag(ELoc, diag::err_omp_required_access) 10758 << getOpenMPClauseName(OMPC_reduction) 10759 << getOpenMPClauseName(OMPC_shared); 10760 reportOriginalDsa(S, Stack, D, DVar); 10761 continue; 10762 } 10763 } 10764 } 10765 10766 // Try to find 'declare reduction' corresponding construct before using 10767 // builtin/overloaded operators. 10768 CXXCastPath BasePath; 10769 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10770 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10771 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10772 if (DeclareReductionRef.isInvalid()) 10773 continue; 10774 if (S.CurContext->isDependentContext() && 10775 (DeclareReductionRef.isUnset() || 10776 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 10777 RD.push(RefExpr, DeclareReductionRef.get()); 10778 continue; 10779 } 10780 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 10781 // Not allowed reduction identifier is found. 10782 S.Diag(ReductionId.getBeginLoc(), 10783 diag::err_omp_unknown_reduction_identifier) 10784 << Type << ReductionIdRange; 10785 continue; 10786 } 10787 10788 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10789 // The type of a list item that appears in a reduction clause must be valid 10790 // for the reduction-identifier. For a max or min reduction in C, the type 10791 // of the list item must be an allowed arithmetic data type: char, int, 10792 // float, double, or _Bool, possibly modified with long, short, signed, or 10793 // unsigned. For a max or min reduction in C++, the type of the list item 10794 // must be an allowed arithmetic data type: char, wchar_t, int, float, 10795 // double, or bool, possibly modified with long, short, signed, or unsigned. 10796 if (DeclareReductionRef.isUnset()) { 10797 if ((BOK == BO_GT || BOK == BO_LT) && 10798 !(Type->isScalarType() || 10799 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 10800 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 10801 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 10802 if (!ASE && !OASE) { 10803 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10804 VarDecl::DeclarationOnly; 10805 S.Diag(D->getLocation(), 10806 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10807 << D; 10808 } 10809 continue; 10810 } 10811 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 10812 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 10813 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 10814 << getOpenMPClauseName(ClauseKind); 10815 if (!ASE && !OASE) { 10816 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10817 VarDecl::DeclarationOnly; 10818 S.Diag(D->getLocation(), 10819 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10820 << D; 10821 } 10822 continue; 10823 } 10824 } 10825 10826 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 10827 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 10828 D->hasAttrs() ? &D->getAttrs() : nullptr); 10829 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 10830 D->hasAttrs() ? &D->getAttrs() : nullptr); 10831 QualType PrivateTy = Type; 10832 10833 // Try if we can determine constant lengths for all array sections and avoid 10834 // the VLA. 10835 bool ConstantLengthOASE = false; 10836 if (OASE) { 10837 bool SingleElement; 10838 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 10839 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 10840 Context, OASE, SingleElement, ArraySizes); 10841 10842 // If we don't have a single element, we must emit a constant array type. 10843 if (ConstantLengthOASE && !SingleElement) { 10844 for (llvm::APSInt &Size : ArraySizes) 10845 PrivateTy = Context.getConstantArrayType( 10846 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 10847 } 10848 } 10849 10850 if ((OASE && !ConstantLengthOASE) || 10851 (!OASE && !ASE && 10852 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 10853 if (!Context.getTargetInfo().isVLASupported() && 10854 S.shouldDiagnoseTargetSupportFromOpenMP()) { 10855 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 10856 S.Diag(ELoc, diag::note_vla_unsupported); 10857 continue; 10858 } 10859 // For arrays/array sections only: 10860 // Create pseudo array type for private copy. The size for this array will 10861 // be generated during codegen. 10862 // For array subscripts or single variables Private Ty is the same as Type 10863 // (type of the variable or single array element). 10864 PrivateTy = Context.getVariableArrayType( 10865 Type, 10866 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 10867 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 10868 } else if (!ASE && !OASE && 10869 Context.getAsArrayType(D->getType().getNonReferenceType())) { 10870 PrivateTy = D->getType().getNonReferenceType(); 10871 } 10872 // Private copy. 10873 VarDecl *PrivateVD = 10874 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 10875 D->hasAttrs() ? &D->getAttrs() : nullptr, 10876 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10877 // Add initializer for private variable. 10878 Expr *Init = nullptr; 10879 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 10880 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 10881 if (DeclareReductionRef.isUsable()) { 10882 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 10883 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 10884 if (DRD->getInitializer()) { 10885 Init = DRDRef; 10886 RHSVD->setInit(DRDRef); 10887 RHSVD->setInitStyle(VarDecl::CallInit); 10888 } 10889 } else { 10890 switch (BOK) { 10891 case BO_Add: 10892 case BO_Xor: 10893 case BO_Or: 10894 case BO_LOr: 10895 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 10896 if (Type->isScalarType() || Type->isAnyComplexType()) 10897 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 10898 break; 10899 case BO_Mul: 10900 case BO_LAnd: 10901 if (Type->isScalarType() || Type->isAnyComplexType()) { 10902 // '*' and '&&' reduction ops - initializer is '1'. 10903 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 10904 } 10905 break; 10906 case BO_And: { 10907 // '&' reduction op - initializer is '~0'. 10908 QualType OrigType = Type; 10909 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 10910 Type = ComplexTy->getElementType(); 10911 if (Type->isRealFloatingType()) { 10912 llvm::APFloat InitValue = 10913 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 10914 /*isIEEE=*/true); 10915 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 10916 Type, ELoc); 10917 } else if (Type->isScalarType()) { 10918 uint64_t Size = Context.getTypeSize(Type); 10919 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 10920 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 10921 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 10922 } 10923 if (Init && OrigType->isAnyComplexType()) { 10924 // Init = 0xFFFF + 0xFFFFi; 10925 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 10926 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 10927 } 10928 Type = OrigType; 10929 break; 10930 } 10931 case BO_LT: 10932 case BO_GT: { 10933 // 'min' reduction op - initializer is 'Largest representable number in 10934 // the reduction list item type'. 10935 // 'max' reduction op - initializer is 'Least representable number in 10936 // the reduction list item type'. 10937 if (Type->isIntegerType() || Type->isPointerType()) { 10938 bool IsSigned = Type->hasSignedIntegerRepresentation(); 10939 uint64_t Size = Context.getTypeSize(Type); 10940 QualType IntTy = 10941 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 10942 llvm::APInt InitValue = 10943 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 10944 : llvm::APInt::getMinValue(Size) 10945 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 10946 : llvm::APInt::getMaxValue(Size); 10947 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 10948 if (Type->isPointerType()) { 10949 // Cast to pointer type. 10950 ExprResult CastExpr = S.BuildCStyleCastExpr( 10951 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 10952 if (CastExpr.isInvalid()) 10953 continue; 10954 Init = CastExpr.get(); 10955 } 10956 } else if (Type->isRealFloatingType()) { 10957 llvm::APFloat InitValue = llvm::APFloat::getLargest( 10958 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 10959 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 10960 Type, ELoc); 10961 } 10962 break; 10963 } 10964 case BO_PtrMemD: 10965 case BO_PtrMemI: 10966 case BO_MulAssign: 10967 case BO_Div: 10968 case BO_Rem: 10969 case BO_Sub: 10970 case BO_Shl: 10971 case BO_Shr: 10972 case BO_LE: 10973 case BO_GE: 10974 case BO_EQ: 10975 case BO_NE: 10976 case BO_Cmp: 10977 case BO_AndAssign: 10978 case BO_XorAssign: 10979 case BO_OrAssign: 10980 case BO_Assign: 10981 case BO_AddAssign: 10982 case BO_SubAssign: 10983 case BO_DivAssign: 10984 case BO_RemAssign: 10985 case BO_ShlAssign: 10986 case BO_ShrAssign: 10987 case BO_Comma: 10988 llvm_unreachable("Unexpected reduction operation"); 10989 } 10990 } 10991 if (Init && DeclareReductionRef.isUnset()) 10992 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 10993 else if (!Init) 10994 S.ActOnUninitializedDecl(RHSVD); 10995 if (RHSVD->isInvalidDecl()) 10996 continue; 10997 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 10998 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 10999 << Type << ReductionIdRange; 11000 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11001 VarDecl::DeclarationOnly; 11002 S.Diag(D->getLocation(), 11003 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11004 << D; 11005 continue; 11006 } 11007 // Store initializer for single element in private copy. Will be used during 11008 // codegen. 11009 PrivateVD->setInit(RHSVD->getInit()); 11010 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 11011 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 11012 ExprResult ReductionOp; 11013 if (DeclareReductionRef.isUsable()) { 11014 QualType RedTy = DeclareReductionRef.get()->getType(); 11015 QualType PtrRedTy = Context.getPointerType(RedTy); 11016 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 11017 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 11018 if (!BasePath.empty()) { 11019 LHS = S.DefaultLvalueConversion(LHS.get()); 11020 RHS = S.DefaultLvalueConversion(RHS.get()); 11021 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11022 CK_UncheckedDerivedToBase, LHS.get(), 11023 &BasePath, LHS.get()->getValueKind()); 11024 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11025 CK_UncheckedDerivedToBase, RHS.get(), 11026 &BasePath, RHS.get()->getValueKind()); 11027 } 11028 FunctionProtoType::ExtProtoInfo EPI; 11029 QualType Params[] = {PtrRedTy, PtrRedTy}; 11030 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 11031 auto *OVE = new (Context) OpaqueValueExpr( 11032 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 11033 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 11034 Expr *Args[] = {LHS.get(), RHS.get()}; 11035 ReductionOp = new (Context) 11036 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 11037 } else { 11038 ReductionOp = S.BuildBinOp( 11039 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 11040 if (ReductionOp.isUsable()) { 11041 if (BOK != BO_LT && BOK != BO_GT) { 11042 ReductionOp = 11043 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11044 BO_Assign, LHSDRE, ReductionOp.get()); 11045 } else { 11046 auto *ConditionalOp = new (Context) 11047 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 11048 Type, VK_LValue, OK_Ordinary); 11049 ReductionOp = 11050 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11051 BO_Assign, LHSDRE, ConditionalOp); 11052 } 11053 if (ReductionOp.isUsable()) 11054 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); 11055 } 11056 if (!ReductionOp.isUsable()) 11057 continue; 11058 } 11059 11060 // OpenMP [2.15.4.6, Restrictions, p.2] 11061 // A list item that appears in an in_reduction clause of a task construct 11062 // must appear in a task_reduction clause of a construct associated with a 11063 // taskgroup region that includes the participating task in its taskgroup 11064 // set. The construct associated with the innermost region that meets this 11065 // condition must specify the same reduction-identifier as the in_reduction 11066 // clause. 11067 if (ClauseKind == OMPC_in_reduction) { 11068 SourceRange ParentSR; 11069 BinaryOperatorKind ParentBOK; 11070 const Expr *ParentReductionOp; 11071 Expr *ParentBOKTD, *ParentReductionOpTD; 11072 DSAStackTy::DSAVarData ParentBOKDSA = 11073 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 11074 ParentBOKTD); 11075 DSAStackTy::DSAVarData ParentReductionOpDSA = 11076 Stack->getTopMostTaskgroupReductionData( 11077 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 11078 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 11079 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 11080 if (!IsParentBOK && !IsParentReductionOp) { 11081 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 11082 continue; 11083 } 11084 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 11085 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 11086 IsParentReductionOp) { 11087 bool EmitError = true; 11088 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 11089 llvm::FoldingSetNodeID RedId, ParentRedId; 11090 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 11091 DeclareReductionRef.get()->Profile(RedId, Context, 11092 /*Canonical=*/true); 11093 EmitError = RedId != ParentRedId; 11094 } 11095 if (EmitError) { 11096 S.Diag(ReductionId.getBeginLoc(), 11097 diag::err_omp_reduction_identifier_mismatch) 11098 << ReductionIdRange << RefExpr->getSourceRange(); 11099 S.Diag(ParentSR.getBegin(), 11100 diag::note_omp_previous_reduction_identifier) 11101 << ParentSR 11102 << (IsParentBOK ? ParentBOKDSA.RefExpr 11103 : ParentReductionOpDSA.RefExpr) 11104 ->getSourceRange(); 11105 continue; 11106 } 11107 } 11108 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 11109 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 11110 } 11111 11112 DeclRefExpr *Ref = nullptr; 11113 Expr *VarsExpr = RefExpr->IgnoreParens(); 11114 if (!VD && !S.CurContext->isDependentContext()) { 11115 if (ASE || OASE) { 11116 TransformExprToCaptures RebuildToCapture(S, D); 11117 VarsExpr = 11118 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 11119 Ref = RebuildToCapture.getCapturedExpr(); 11120 } else { 11121 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 11122 } 11123 if (!S.isOpenMPCapturedDecl(D)) { 11124 RD.ExprCaptures.emplace_back(Ref->getDecl()); 11125 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11126 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 11127 if (!RefRes.isUsable()) 11128 continue; 11129 ExprResult PostUpdateRes = 11130 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11131 RefRes.get()); 11132 if (!PostUpdateRes.isUsable()) 11133 continue; 11134 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 11135 Stack->getCurrentDirective() == OMPD_taskgroup) { 11136 S.Diag(RefExpr->getExprLoc(), 11137 diag::err_omp_reduction_non_addressable_expression) 11138 << RefExpr->getSourceRange(); 11139 continue; 11140 } 11141 RD.ExprPostUpdates.emplace_back( 11142 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 11143 } 11144 } 11145 } 11146 // All reduction items are still marked as reduction (to do not increase 11147 // code base size). 11148 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 11149 if (CurrDir == OMPD_taskgroup) { 11150 if (DeclareReductionRef.isUsable()) 11151 Stack->addTaskgroupReductionData(D, ReductionIdRange, 11152 DeclareReductionRef.get()); 11153 else 11154 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 11155 } 11156 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 11157 TaskgroupDescriptor); 11158 } 11159 return RD.Vars.empty(); 11160 } 11161 11162 OMPClause *Sema::ActOnOpenMPReductionClause( 11163 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11164 SourceLocation ColonLoc, SourceLocation EndLoc, 11165 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11166 ArrayRef<Expr *> UnresolvedReductions) { 11167 ReductionData RD(VarList.size()); 11168 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 11169 StartLoc, LParenLoc, ColonLoc, EndLoc, 11170 ReductionIdScopeSpec, ReductionId, 11171 UnresolvedReductions, RD)) 11172 return nullptr; 11173 11174 return OMPReductionClause::Create( 11175 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11176 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11177 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11178 buildPreInits(Context, RD.ExprCaptures), 11179 buildPostUpdate(*this, RD.ExprPostUpdates)); 11180 } 11181 11182 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 11183 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11184 SourceLocation ColonLoc, SourceLocation EndLoc, 11185 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11186 ArrayRef<Expr *> UnresolvedReductions) { 11187 ReductionData RD(VarList.size()); 11188 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 11189 StartLoc, LParenLoc, ColonLoc, EndLoc, 11190 ReductionIdScopeSpec, ReductionId, 11191 UnresolvedReductions, RD)) 11192 return nullptr; 11193 11194 return OMPTaskReductionClause::Create( 11195 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11196 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11197 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11198 buildPreInits(Context, RD.ExprCaptures), 11199 buildPostUpdate(*this, RD.ExprPostUpdates)); 11200 } 11201 11202 OMPClause *Sema::ActOnOpenMPInReductionClause( 11203 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11204 SourceLocation ColonLoc, SourceLocation EndLoc, 11205 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11206 ArrayRef<Expr *> UnresolvedReductions) { 11207 ReductionData RD(VarList.size()); 11208 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 11209 StartLoc, LParenLoc, ColonLoc, EndLoc, 11210 ReductionIdScopeSpec, ReductionId, 11211 UnresolvedReductions, RD)) 11212 return nullptr; 11213 11214 return OMPInReductionClause::Create( 11215 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11216 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11217 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 11218 buildPreInits(Context, RD.ExprCaptures), 11219 buildPostUpdate(*this, RD.ExprPostUpdates)); 11220 } 11221 11222 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 11223 SourceLocation LinLoc) { 11224 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 11225 LinKind == OMPC_LINEAR_unknown) { 11226 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 11227 return true; 11228 } 11229 return false; 11230 } 11231 11232 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 11233 OpenMPLinearClauseKind LinKind, 11234 QualType Type) { 11235 const auto *VD = dyn_cast_or_null<VarDecl>(D); 11236 // A variable must not have an incomplete type or a reference type. 11237 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 11238 return true; 11239 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 11240 !Type->isReferenceType()) { 11241 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 11242 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 11243 return true; 11244 } 11245 Type = Type.getNonReferenceType(); 11246 11247 // A list item must not be const-qualified. 11248 if (Type.isConstant(Context)) { 11249 Diag(ELoc, diag::err_omp_const_variable) 11250 << getOpenMPClauseName(OMPC_linear); 11251 if (D) { 11252 bool IsDecl = 11253 !VD || 11254 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11255 Diag(D->getLocation(), 11256 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11257 << D; 11258 } 11259 return true; 11260 } 11261 11262 // A list item must be of integral or pointer type. 11263 Type = Type.getUnqualifiedType().getCanonicalType(); 11264 const auto *Ty = Type.getTypePtrOrNull(); 11265 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 11266 !Ty->isPointerType())) { 11267 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 11268 if (D) { 11269 bool IsDecl = 11270 !VD || 11271 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11272 Diag(D->getLocation(), 11273 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11274 << D; 11275 } 11276 return true; 11277 } 11278 return false; 11279 } 11280 11281 OMPClause *Sema::ActOnOpenMPLinearClause( 11282 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 11283 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 11284 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11285 SmallVector<Expr *, 8> Vars; 11286 SmallVector<Expr *, 8> Privates; 11287 SmallVector<Expr *, 8> Inits; 11288 SmallVector<Decl *, 4> ExprCaptures; 11289 SmallVector<Expr *, 4> ExprPostUpdates; 11290 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 11291 LinKind = OMPC_LINEAR_val; 11292 for (Expr *RefExpr : VarList) { 11293 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11294 SourceLocation ELoc; 11295 SourceRange ERange; 11296 Expr *SimpleRefExpr = RefExpr; 11297 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11298 if (Res.second) { 11299 // It will be analyzed later. 11300 Vars.push_back(RefExpr); 11301 Privates.push_back(nullptr); 11302 Inits.push_back(nullptr); 11303 } 11304 ValueDecl *D = Res.first; 11305 if (!D) 11306 continue; 11307 11308 QualType Type = D->getType(); 11309 auto *VD = dyn_cast<VarDecl>(D); 11310 11311 // OpenMP [2.14.3.7, linear clause] 11312 // A list-item cannot appear in more than one linear clause. 11313 // A list-item that appears in a linear clause cannot appear in any 11314 // other data-sharing attribute clause. 11315 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11316 if (DVar.RefExpr) { 11317 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11318 << getOpenMPClauseName(OMPC_linear); 11319 reportOriginalDsa(*this, DSAStack, D, DVar); 11320 continue; 11321 } 11322 11323 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 11324 continue; 11325 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11326 11327 // Build private copy of original var. 11328 VarDecl *Private = 11329 buildVarDecl(*this, ELoc, Type, D->getName(), 11330 D->hasAttrs() ? &D->getAttrs() : nullptr, 11331 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11332 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 11333 // Build var to save initial value. 11334 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 11335 Expr *InitExpr; 11336 DeclRefExpr *Ref = nullptr; 11337 if (!VD && !CurContext->isDependentContext()) { 11338 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11339 if (!isOpenMPCapturedDecl(D)) { 11340 ExprCaptures.push_back(Ref->getDecl()); 11341 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11342 ExprResult RefRes = DefaultLvalueConversion(Ref); 11343 if (!RefRes.isUsable()) 11344 continue; 11345 ExprResult PostUpdateRes = 11346 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 11347 SimpleRefExpr, RefRes.get()); 11348 if (!PostUpdateRes.isUsable()) 11349 continue; 11350 ExprPostUpdates.push_back( 11351 IgnoredValueConversions(PostUpdateRes.get()).get()); 11352 } 11353 } 11354 } 11355 if (LinKind == OMPC_LINEAR_uval) 11356 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 11357 else 11358 InitExpr = VD ? SimpleRefExpr : Ref; 11359 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 11360 /*DirectInit=*/false); 11361 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 11362 11363 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 11364 Vars.push_back((VD || CurContext->isDependentContext()) 11365 ? RefExpr->IgnoreParens() 11366 : Ref); 11367 Privates.push_back(PrivateRef); 11368 Inits.push_back(InitRef); 11369 } 11370 11371 if (Vars.empty()) 11372 return nullptr; 11373 11374 Expr *StepExpr = Step; 11375 Expr *CalcStepExpr = nullptr; 11376 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 11377 !Step->isInstantiationDependent() && 11378 !Step->containsUnexpandedParameterPack()) { 11379 SourceLocation StepLoc = Step->getBeginLoc(); 11380 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 11381 if (Val.isInvalid()) 11382 return nullptr; 11383 StepExpr = Val.get(); 11384 11385 // Build var to save the step value. 11386 VarDecl *SaveVar = 11387 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 11388 ExprResult SaveRef = 11389 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 11390 ExprResult CalcStep = 11391 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 11392 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 11393 11394 // Warn about zero linear step (it would be probably better specified as 11395 // making corresponding variables 'const'). 11396 llvm::APSInt Result; 11397 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 11398 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 11399 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 11400 << (Vars.size() > 1); 11401 if (!IsConstant && CalcStep.isUsable()) { 11402 // Calculate the step beforehand instead of doing this on each iteration. 11403 // (This is not used if the number of iterations may be kfold-ed). 11404 CalcStepExpr = CalcStep.get(); 11405 } 11406 } 11407 11408 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 11409 ColonLoc, EndLoc, Vars, Privates, Inits, 11410 StepExpr, CalcStepExpr, 11411 buildPreInits(Context, ExprCaptures), 11412 buildPostUpdate(*this, ExprPostUpdates)); 11413 } 11414 11415 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 11416 Expr *NumIterations, Sema &SemaRef, 11417 Scope *S, DSAStackTy *Stack) { 11418 // Walk the vars and build update/final expressions for the CodeGen. 11419 SmallVector<Expr *, 8> Updates; 11420 SmallVector<Expr *, 8> Finals; 11421 Expr *Step = Clause.getStep(); 11422 Expr *CalcStep = Clause.getCalcStep(); 11423 // OpenMP [2.14.3.7, linear clause] 11424 // If linear-step is not specified it is assumed to be 1. 11425 if (!Step) 11426 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 11427 else if (CalcStep) 11428 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 11429 bool HasErrors = false; 11430 auto CurInit = Clause.inits().begin(); 11431 auto CurPrivate = Clause.privates().begin(); 11432 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 11433 for (Expr *RefExpr : Clause.varlists()) { 11434 SourceLocation ELoc; 11435 SourceRange ERange; 11436 Expr *SimpleRefExpr = RefExpr; 11437 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 11438 ValueDecl *D = Res.first; 11439 if (Res.second || !D) { 11440 Updates.push_back(nullptr); 11441 Finals.push_back(nullptr); 11442 HasErrors = true; 11443 continue; 11444 } 11445 auto &&Info = Stack->isLoopControlVariable(D); 11446 // OpenMP [2.15.11, distribute simd Construct] 11447 // A list item may not appear in a linear clause, unless it is the loop 11448 // iteration variable. 11449 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 11450 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 11451 SemaRef.Diag(ELoc, 11452 diag::err_omp_linear_distribute_var_non_loop_iteration); 11453 Updates.push_back(nullptr); 11454 Finals.push_back(nullptr); 11455 HasErrors = true; 11456 continue; 11457 } 11458 Expr *InitExpr = *CurInit; 11459 11460 // Build privatized reference to the current linear var. 11461 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 11462 Expr *CapturedRef; 11463 if (LinKind == OMPC_LINEAR_uval) 11464 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 11465 else 11466 CapturedRef = 11467 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 11468 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 11469 /*RefersToCapture=*/true); 11470 11471 // Build update: Var = InitExpr + IV * Step 11472 ExprResult Update; 11473 if (!Info.first) 11474 Update = 11475 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 11476 InitExpr, IV, Step, /* Subtract */ false); 11477 else 11478 Update = *CurPrivate; 11479 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 11480 /*DiscardedValue=*/true); 11481 11482 // Build final: Var = InitExpr + NumIterations * Step 11483 ExprResult Final; 11484 if (!Info.first) 11485 Final = 11486 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 11487 InitExpr, NumIterations, Step, /*Subtract=*/false); 11488 else 11489 Final = *CurPrivate; 11490 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 11491 /*DiscardedValue=*/true); 11492 11493 if (!Update.isUsable() || !Final.isUsable()) { 11494 Updates.push_back(nullptr); 11495 Finals.push_back(nullptr); 11496 HasErrors = true; 11497 } else { 11498 Updates.push_back(Update.get()); 11499 Finals.push_back(Final.get()); 11500 } 11501 ++CurInit; 11502 ++CurPrivate; 11503 } 11504 Clause.setUpdates(Updates); 11505 Clause.setFinals(Finals); 11506 return HasErrors; 11507 } 11508 11509 OMPClause *Sema::ActOnOpenMPAlignedClause( 11510 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 11511 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11512 SmallVector<Expr *, 8> Vars; 11513 for (Expr *RefExpr : VarList) { 11514 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11515 SourceLocation ELoc; 11516 SourceRange ERange; 11517 Expr *SimpleRefExpr = RefExpr; 11518 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11519 if (Res.second) { 11520 // It will be analyzed later. 11521 Vars.push_back(RefExpr); 11522 } 11523 ValueDecl *D = Res.first; 11524 if (!D) 11525 continue; 11526 11527 QualType QType = D->getType(); 11528 auto *VD = dyn_cast<VarDecl>(D); 11529 11530 // OpenMP [2.8.1, simd construct, Restrictions] 11531 // The type of list items appearing in the aligned clause must be 11532 // array, pointer, reference to array, or reference to pointer. 11533 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11534 const Type *Ty = QType.getTypePtrOrNull(); 11535 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 11536 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 11537 << QType << getLangOpts().CPlusPlus << ERange; 11538 bool IsDecl = 11539 !VD || 11540 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11541 Diag(D->getLocation(), 11542 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11543 << D; 11544 continue; 11545 } 11546 11547 // OpenMP [2.8.1, simd construct, Restrictions] 11548 // A list-item cannot appear in more than one aligned clause. 11549 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 11550 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 11551 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 11552 << getOpenMPClauseName(OMPC_aligned); 11553 continue; 11554 } 11555 11556 DeclRefExpr *Ref = nullptr; 11557 if (!VD && isOpenMPCapturedDecl(D)) 11558 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11559 Vars.push_back(DefaultFunctionArrayConversion( 11560 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 11561 .get()); 11562 } 11563 11564 // OpenMP [2.8.1, simd construct, Description] 11565 // The parameter of the aligned clause, alignment, must be a constant 11566 // positive integer expression. 11567 // If no optional parameter is specified, implementation-defined default 11568 // alignments for SIMD instructions on the target platforms are assumed. 11569 if (Alignment != nullptr) { 11570 ExprResult AlignResult = 11571 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 11572 if (AlignResult.isInvalid()) 11573 return nullptr; 11574 Alignment = AlignResult.get(); 11575 } 11576 if (Vars.empty()) 11577 return nullptr; 11578 11579 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 11580 EndLoc, Vars, Alignment); 11581 } 11582 11583 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 11584 SourceLocation StartLoc, 11585 SourceLocation LParenLoc, 11586 SourceLocation EndLoc) { 11587 SmallVector<Expr *, 8> Vars; 11588 SmallVector<Expr *, 8> SrcExprs; 11589 SmallVector<Expr *, 8> DstExprs; 11590 SmallVector<Expr *, 8> AssignmentOps; 11591 for (Expr *RefExpr : VarList) { 11592 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 11593 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 11594 // It will be analyzed later. 11595 Vars.push_back(RefExpr); 11596 SrcExprs.push_back(nullptr); 11597 DstExprs.push_back(nullptr); 11598 AssignmentOps.push_back(nullptr); 11599 continue; 11600 } 11601 11602 SourceLocation ELoc = RefExpr->getExprLoc(); 11603 // OpenMP [2.1, C/C++] 11604 // A list item is a variable name. 11605 // OpenMP [2.14.4.1, Restrictions, p.1] 11606 // A list item that appears in a copyin clause must be threadprivate. 11607 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 11608 if (!DE || !isa<VarDecl>(DE->getDecl())) { 11609 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 11610 << 0 << RefExpr->getSourceRange(); 11611 continue; 11612 } 11613 11614 Decl *D = DE->getDecl(); 11615 auto *VD = cast<VarDecl>(D); 11616 11617 QualType Type = VD->getType(); 11618 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 11619 // It will be analyzed later. 11620 Vars.push_back(DE); 11621 SrcExprs.push_back(nullptr); 11622 DstExprs.push_back(nullptr); 11623 AssignmentOps.push_back(nullptr); 11624 continue; 11625 } 11626 11627 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 11628 // A list item that appears in a copyin clause must be threadprivate. 11629 if (!DSAStack->isThreadPrivate(VD)) { 11630 Diag(ELoc, diag::err_omp_required_access) 11631 << getOpenMPClauseName(OMPC_copyin) 11632 << getOpenMPDirectiveName(OMPD_threadprivate); 11633 continue; 11634 } 11635 11636 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11637 // A variable of class type (or array thereof) that appears in a 11638 // copyin clause requires an accessible, unambiguous copy assignment 11639 // operator for the class type. 11640 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11641 VarDecl *SrcVD = 11642 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 11643 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11644 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 11645 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 11646 VarDecl *DstVD = 11647 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 11648 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11649 DeclRefExpr *PseudoDstExpr = 11650 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 11651 // For arrays generate assignment operation for single element and replace 11652 // it by the original array element in CodeGen. 11653 ExprResult AssignmentOp = 11654 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 11655 PseudoSrcExpr); 11656 if (AssignmentOp.isInvalid()) 11657 continue; 11658 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 11659 /*DiscardedValue=*/true); 11660 if (AssignmentOp.isInvalid()) 11661 continue; 11662 11663 DSAStack->addDSA(VD, DE, OMPC_copyin); 11664 Vars.push_back(DE); 11665 SrcExprs.push_back(PseudoSrcExpr); 11666 DstExprs.push_back(PseudoDstExpr); 11667 AssignmentOps.push_back(AssignmentOp.get()); 11668 } 11669 11670 if (Vars.empty()) 11671 return nullptr; 11672 11673 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11674 SrcExprs, DstExprs, AssignmentOps); 11675 } 11676 11677 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 11678 SourceLocation StartLoc, 11679 SourceLocation LParenLoc, 11680 SourceLocation EndLoc) { 11681 SmallVector<Expr *, 8> Vars; 11682 SmallVector<Expr *, 8> SrcExprs; 11683 SmallVector<Expr *, 8> DstExprs; 11684 SmallVector<Expr *, 8> AssignmentOps; 11685 for (Expr *RefExpr : VarList) { 11686 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11687 SourceLocation ELoc; 11688 SourceRange ERange; 11689 Expr *SimpleRefExpr = RefExpr; 11690 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11691 if (Res.second) { 11692 // It will be analyzed later. 11693 Vars.push_back(RefExpr); 11694 SrcExprs.push_back(nullptr); 11695 DstExprs.push_back(nullptr); 11696 AssignmentOps.push_back(nullptr); 11697 } 11698 ValueDecl *D = Res.first; 11699 if (!D) 11700 continue; 11701 11702 QualType Type = D->getType(); 11703 auto *VD = dyn_cast<VarDecl>(D); 11704 11705 // OpenMP [2.14.4.2, Restrictions, p.2] 11706 // A list item that appears in a copyprivate clause may not appear in a 11707 // private or firstprivate clause on the single construct. 11708 if (!VD || !DSAStack->isThreadPrivate(VD)) { 11709 DSAStackTy::DSAVarData DVar = 11710 DSAStack->getTopDSA(D, /*FromParent=*/false); 11711 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 11712 DVar.RefExpr) { 11713 Diag(ELoc, diag::err_omp_wrong_dsa) 11714 << getOpenMPClauseName(DVar.CKind) 11715 << getOpenMPClauseName(OMPC_copyprivate); 11716 reportOriginalDsa(*this, DSAStack, D, DVar); 11717 continue; 11718 } 11719 11720 // OpenMP [2.11.4.2, Restrictions, p.1] 11721 // All list items that appear in a copyprivate clause must be either 11722 // threadprivate or private in the enclosing context. 11723 if (DVar.CKind == OMPC_unknown) { 11724 DVar = DSAStack->getImplicitDSA(D, false); 11725 if (DVar.CKind == OMPC_shared) { 11726 Diag(ELoc, diag::err_omp_required_access) 11727 << getOpenMPClauseName(OMPC_copyprivate) 11728 << "threadprivate or private in the enclosing context"; 11729 reportOriginalDsa(*this, DSAStack, D, DVar); 11730 continue; 11731 } 11732 } 11733 } 11734 11735 // Variably modified types are not supported. 11736 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 11737 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11738 << getOpenMPClauseName(OMPC_copyprivate) << Type 11739 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11740 bool IsDecl = 11741 !VD || 11742 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11743 Diag(D->getLocation(), 11744 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11745 << D; 11746 continue; 11747 } 11748 11749 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11750 // A variable of class type (or array thereof) that appears in a 11751 // copyin clause requires an accessible, unambiguous copy assignment 11752 // operator for the class type. 11753 Type = Context.getBaseElementType(Type.getNonReferenceType()) 11754 .getUnqualifiedType(); 11755 VarDecl *SrcVD = 11756 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 11757 D->hasAttrs() ? &D->getAttrs() : nullptr); 11758 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 11759 VarDecl *DstVD = 11760 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 11761 D->hasAttrs() ? &D->getAttrs() : nullptr); 11762 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11763 ExprResult AssignmentOp = BuildBinOp( 11764 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 11765 if (AssignmentOp.isInvalid()) 11766 continue; 11767 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 11768 /*DiscardedValue=*/true); 11769 if (AssignmentOp.isInvalid()) 11770 continue; 11771 11772 // No need to mark vars as copyprivate, they are already threadprivate or 11773 // implicitly private. 11774 assert(VD || isOpenMPCapturedDecl(D)); 11775 Vars.push_back( 11776 VD ? RefExpr->IgnoreParens() 11777 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 11778 SrcExprs.push_back(PseudoSrcExpr); 11779 DstExprs.push_back(PseudoDstExpr); 11780 AssignmentOps.push_back(AssignmentOp.get()); 11781 } 11782 11783 if (Vars.empty()) 11784 return nullptr; 11785 11786 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11787 Vars, SrcExprs, DstExprs, AssignmentOps); 11788 } 11789 11790 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 11791 SourceLocation StartLoc, 11792 SourceLocation LParenLoc, 11793 SourceLocation EndLoc) { 11794 if (VarList.empty()) 11795 return nullptr; 11796 11797 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 11798 } 11799 11800 OMPClause * 11801 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 11802 SourceLocation DepLoc, SourceLocation ColonLoc, 11803 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 11804 SourceLocation LParenLoc, SourceLocation EndLoc) { 11805 if (DSAStack->getCurrentDirective() == OMPD_ordered && 11806 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 11807 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 11808 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 11809 return nullptr; 11810 } 11811 if (DSAStack->getCurrentDirective() != OMPD_ordered && 11812 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 11813 DepKind == OMPC_DEPEND_sink)) { 11814 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 11815 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 11816 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 11817 /*Last=*/OMPC_DEPEND_unknown, Except) 11818 << getOpenMPClauseName(OMPC_depend); 11819 return nullptr; 11820 } 11821 SmallVector<Expr *, 8> Vars; 11822 DSAStackTy::OperatorOffsetTy OpsOffs; 11823 llvm::APSInt DepCounter(/*BitWidth=*/32); 11824 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 11825 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 11826 if (const Expr *OrderedCountExpr = 11827 DSAStack->getParentOrderedRegionParam().first) { 11828 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 11829 TotalDepCount.setIsUnsigned(/*Val=*/true); 11830 } 11831 } 11832 for (Expr *RefExpr : VarList) { 11833 assert(RefExpr && "NULL expr in OpenMP shared clause."); 11834 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 11835 // It will be analyzed later. 11836 Vars.push_back(RefExpr); 11837 continue; 11838 } 11839 11840 SourceLocation ELoc = RefExpr->getExprLoc(); 11841 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 11842 if (DepKind == OMPC_DEPEND_sink) { 11843 if (DSAStack->getParentOrderedRegionParam().first && 11844 DepCounter >= TotalDepCount) { 11845 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 11846 continue; 11847 } 11848 ++DepCounter; 11849 // OpenMP [2.13.9, Summary] 11850 // depend(dependence-type : vec), where dependence-type is: 11851 // 'sink' and where vec is the iteration vector, which has the form: 11852 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 11853 // where n is the value specified by the ordered clause in the loop 11854 // directive, xi denotes the loop iteration variable of the i-th nested 11855 // loop associated with the loop directive, and di is a constant 11856 // non-negative integer. 11857 if (CurContext->isDependentContext()) { 11858 // It will be analyzed later. 11859 Vars.push_back(RefExpr); 11860 continue; 11861 } 11862 SimpleExpr = SimpleExpr->IgnoreImplicit(); 11863 OverloadedOperatorKind OOK = OO_None; 11864 SourceLocation OOLoc; 11865 Expr *LHS = SimpleExpr; 11866 Expr *RHS = nullptr; 11867 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 11868 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 11869 OOLoc = BO->getOperatorLoc(); 11870 LHS = BO->getLHS()->IgnoreParenImpCasts(); 11871 RHS = BO->getRHS()->IgnoreParenImpCasts(); 11872 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 11873 OOK = OCE->getOperator(); 11874 OOLoc = OCE->getOperatorLoc(); 11875 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 11876 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 11877 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 11878 OOK = MCE->getMethodDecl() 11879 ->getNameInfo() 11880 .getName() 11881 .getCXXOverloadedOperator(); 11882 OOLoc = MCE->getCallee()->getExprLoc(); 11883 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 11884 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 11885 } 11886 SourceLocation ELoc; 11887 SourceRange ERange; 11888 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 11889 if (Res.second) { 11890 // It will be analyzed later. 11891 Vars.push_back(RefExpr); 11892 } 11893 ValueDecl *D = Res.first; 11894 if (!D) 11895 continue; 11896 11897 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 11898 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 11899 continue; 11900 } 11901 if (RHS) { 11902 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 11903 RHS, OMPC_depend, /*StrictlyPositive=*/false); 11904 if (RHSRes.isInvalid()) 11905 continue; 11906 } 11907 if (!CurContext->isDependentContext() && 11908 DSAStack->getParentOrderedRegionParam().first && 11909 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 11910 const ValueDecl *VD = 11911 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 11912 if (VD) 11913 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 11914 << 1 << VD; 11915 else 11916 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 11917 continue; 11918 } 11919 OpsOffs.emplace_back(RHS, OOK); 11920 } else { 11921 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 11922 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 11923 (ASE && 11924 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 11925 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 11926 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 11927 << RefExpr->getSourceRange(); 11928 continue; 11929 } 11930 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 11931 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 11932 ExprResult Res = 11933 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 11934 getDiagnostics().setSuppressAllDiagnostics(Suppress); 11935 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 11936 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 11937 << RefExpr->getSourceRange(); 11938 continue; 11939 } 11940 } 11941 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 11942 } 11943 11944 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 11945 TotalDepCount > VarList.size() && 11946 DSAStack->getParentOrderedRegionParam().first && 11947 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 11948 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 11949 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 11950 } 11951 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 11952 Vars.empty()) 11953 return nullptr; 11954 11955 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11956 DepKind, DepLoc, ColonLoc, Vars, 11957 TotalDepCount.getZExtValue()); 11958 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 11959 DSAStack->isParentOrderedRegion()) 11960 DSAStack->addDoacrossDependClause(C, OpsOffs); 11961 return C; 11962 } 11963 11964 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 11965 SourceLocation LParenLoc, 11966 SourceLocation EndLoc) { 11967 Expr *ValExpr = Device; 11968 Stmt *HelperValStmt = nullptr; 11969 11970 // OpenMP [2.9.1, Restrictions] 11971 // The device expression must evaluate to a non-negative integer value. 11972 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 11973 /*StrictlyPositive=*/false)) 11974 return nullptr; 11975 11976 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11977 OpenMPDirectiveKind CaptureRegion = 11978 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 11979 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11980 ValExpr = MakeFullExpr(ValExpr).get(); 11981 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11982 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11983 HelperValStmt = buildPreInits(Context, Captures); 11984 } 11985 11986 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 11987 StartLoc, LParenLoc, EndLoc); 11988 } 11989 11990 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 11991 DSAStackTy *Stack, QualType QTy, 11992 bool FullCheck = true) { 11993 NamedDecl *ND; 11994 if (QTy->isIncompleteType(&ND)) { 11995 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 11996 return false; 11997 } 11998 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 11999 !QTy.isTrivialType(SemaRef.Context)) 12000 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 12001 return true; 12002 } 12003 12004 /// Return true if it can be proven that the provided array expression 12005 /// (array section or array subscript) does NOT specify the whole size of the 12006 /// array whose base type is \a BaseQTy. 12007 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 12008 const Expr *E, 12009 QualType BaseQTy) { 12010 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12011 12012 // If this is an array subscript, it refers to the whole size if the size of 12013 // the dimension is constant and equals 1. Also, an array section assumes the 12014 // format of an array subscript if no colon is used. 12015 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 12016 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12017 return ATy->getSize().getSExtValue() != 1; 12018 // Size can't be evaluated statically. 12019 return false; 12020 } 12021 12022 assert(OASE && "Expecting array section if not an array subscript."); 12023 const Expr *LowerBound = OASE->getLowerBound(); 12024 const Expr *Length = OASE->getLength(); 12025 12026 // If there is a lower bound that does not evaluates to zero, we are not 12027 // covering the whole dimension. 12028 if (LowerBound) { 12029 llvm::APSInt ConstLowerBound; 12030 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 12031 return false; // Can't get the integer value as a constant. 12032 if (ConstLowerBound.getSExtValue()) 12033 return true; 12034 } 12035 12036 // If we don't have a length we covering the whole dimension. 12037 if (!Length) 12038 return false; 12039 12040 // If the base is a pointer, we don't have a way to get the size of the 12041 // pointee. 12042 if (BaseQTy->isPointerType()) 12043 return false; 12044 12045 // We can only check if the length is the same as the size of the dimension 12046 // if we have a constant array. 12047 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 12048 if (!CATy) 12049 return false; 12050 12051 llvm::APSInt ConstLength; 12052 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 12053 return false; // Can't get the integer value as a constant. 12054 12055 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 12056 } 12057 12058 // Return true if it can be proven that the provided array expression (array 12059 // section or array subscript) does NOT specify a single element of the array 12060 // whose base type is \a BaseQTy. 12061 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 12062 const Expr *E, 12063 QualType BaseQTy) { 12064 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12065 12066 // An array subscript always refer to a single element. Also, an array section 12067 // assumes the format of an array subscript if no colon is used. 12068 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 12069 return false; 12070 12071 assert(OASE && "Expecting array section if not an array subscript."); 12072 const Expr *Length = OASE->getLength(); 12073 12074 // If we don't have a length we have to check if the array has unitary size 12075 // for this dimension. Also, we should always expect a length if the base type 12076 // is pointer. 12077 if (!Length) { 12078 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12079 return ATy->getSize().getSExtValue() != 1; 12080 // We cannot assume anything. 12081 return false; 12082 } 12083 12084 // Check if the length evaluates to 1. 12085 llvm::APSInt ConstLength; 12086 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 12087 return false; // Can't get the integer value as a constant. 12088 12089 return ConstLength.getSExtValue() != 1; 12090 } 12091 12092 // Return the expression of the base of the mappable expression or null if it 12093 // cannot be determined and do all the necessary checks to see if the expression 12094 // is valid as a standalone mappable expression. In the process, record all the 12095 // components of the expression. 12096 static const Expr *checkMapClauseExpressionBase( 12097 Sema &SemaRef, Expr *E, 12098 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 12099 OpenMPClauseKind CKind, bool NoDiagnose) { 12100 SourceLocation ELoc = E->getExprLoc(); 12101 SourceRange ERange = E->getSourceRange(); 12102 12103 // The base of elements of list in a map clause have to be either: 12104 // - a reference to variable or field. 12105 // - a member expression. 12106 // - an array expression. 12107 // 12108 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 12109 // reference to 'r'. 12110 // 12111 // If we have: 12112 // 12113 // struct SS { 12114 // Bla S; 12115 // foo() { 12116 // #pragma omp target map (S.Arr[:12]); 12117 // } 12118 // } 12119 // 12120 // We want to retrieve the member expression 'this->S'; 12121 12122 const Expr *RelevantExpr = nullptr; 12123 12124 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 12125 // If a list item is an array section, it must specify contiguous storage. 12126 // 12127 // For this restriction it is sufficient that we make sure only references 12128 // to variables or fields and array expressions, and that no array sections 12129 // exist except in the rightmost expression (unless they cover the whole 12130 // dimension of the array). E.g. these would be invalid: 12131 // 12132 // r.ArrS[3:5].Arr[6:7] 12133 // 12134 // r.ArrS[3:5].x 12135 // 12136 // but these would be valid: 12137 // r.ArrS[3].Arr[6:7] 12138 // 12139 // r.ArrS[3].x 12140 12141 bool AllowUnitySizeArraySection = true; 12142 bool AllowWholeSizeArraySection = true; 12143 12144 while (!RelevantExpr) { 12145 E = E->IgnoreParenImpCasts(); 12146 12147 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 12148 if (!isa<VarDecl>(CurE->getDecl())) 12149 return nullptr; 12150 12151 RelevantExpr = CurE; 12152 12153 // If we got a reference to a declaration, we should not expect any array 12154 // section before that. 12155 AllowUnitySizeArraySection = false; 12156 AllowWholeSizeArraySection = false; 12157 12158 // Record the component. 12159 CurComponents.emplace_back(CurE, CurE->getDecl()); 12160 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 12161 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 12162 12163 if (isa<CXXThisExpr>(BaseE)) 12164 // We found a base expression: this->Val. 12165 RelevantExpr = CurE; 12166 else 12167 E = BaseE; 12168 12169 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 12170 if (!NoDiagnose) { 12171 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 12172 << CurE->getSourceRange(); 12173 return nullptr; 12174 } 12175 if (RelevantExpr) 12176 return nullptr; 12177 continue; 12178 } 12179 12180 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 12181 12182 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 12183 // A bit-field cannot appear in a map clause. 12184 // 12185 if (FD->isBitField()) { 12186 if (!NoDiagnose) { 12187 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 12188 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 12189 return nullptr; 12190 } 12191 if (RelevantExpr) 12192 return nullptr; 12193 continue; 12194 } 12195 12196 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12197 // If the type of a list item is a reference to a type T then the type 12198 // will be considered to be T for all purposes of this clause. 12199 QualType CurType = BaseE->getType().getNonReferenceType(); 12200 12201 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 12202 // A list item cannot be a variable that is a member of a structure with 12203 // a union type. 12204 // 12205 if (CurType->isUnionType()) { 12206 if (!NoDiagnose) { 12207 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 12208 << CurE->getSourceRange(); 12209 return nullptr; 12210 } 12211 continue; 12212 } 12213 12214 // If we got a member expression, we should not expect any array section 12215 // before that: 12216 // 12217 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 12218 // If a list item is an element of a structure, only the rightmost symbol 12219 // of the variable reference can be an array section. 12220 // 12221 AllowUnitySizeArraySection = false; 12222 AllowWholeSizeArraySection = false; 12223 12224 // Record the component. 12225 CurComponents.emplace_back(CurE, FD); 12226 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 12227 E = CurE->getBase()->IgnoreParenImpCasts(); 12228 12229 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 12230 if (!NoDiagnose) { 12231 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12232 << 0 << CurE->getSourceRange(); 12233 return nullptr; 12234 } 12235 continue; 12236 } 12237 12238 // If we got an array subscript that express the whole dimension we 12239 // can have any array expressions before. If it only expressing part of 12240 // the dimension, we can only have unitary-size array expressions. 12241 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 12242 E->getType())) 12243 AllowWholeSizeArraySection = false; 12244 12245 // Record the component - we don't have any declaration associated. 12246 CurComponents.emplace_back(CurE, nullptr); 12247 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 12248 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 12249 E = CurE->getBase()->IgnoreParenImpCasts(); 12250 12251 QualType CurType = 12252 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12253 12254 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12255 // If the type of a list item is a reference to a type T then the type 12256 // will be considered to be T for all purposes of this clause. 12257 if (CurType->isReferenceType()) 12258 CurType = CurType->getPointeeType(); 12259 12260 bool IsPointer = CurType->isAnyPointerType(); 12261 12262 if (!IsPointer && !CurType->isArrayType()) { 12263 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12264 << 0 << CurE->getSourceRange(); 12265 return nullptr; 12266 } 12267 12268 bool NotWhole = 12269 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 12270 bool NotUnity = 12271 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 12272 12273 if (AllowWholeSizeArraySection) { 12274 // Any array section is currently allowed. Allowing a whole size array 12275 // section implies allowing a unity array section as well. 12276 // 12277 // If this array section refers to the whole dimension we can still 12278 // accept other array sections before this one, except if the base is a 12279 // pointer. Otherwise, only unitary sections are accepted. 12280 if (NotWhole || IsPointer) 12281 AllowWholeSizeArraySection = false; 12282 } else if (AllowUnitySizeArraySection && NotUnity) { 12283 // A unity or whole array section is not allowed and that is not 12284 // compatible with the properties of the current array section. 12285 SemaRef.Diag( 12286 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 12287 << CurE->getSourceRange(); 12288 return nullptr; 12289 } 12290 12291 // Record the component - we don't have any declaration associated. 12292 CurComponents.emplace_back(CurE, nullptr); 12293 } else { 12294 if (!NoDiagnose) { 12295 // If nothing else worked, this is not a valid map clause expression. 12296 SemaRef.Diag( 12297 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 12298 << ERange; 12299 } 12300 return nullptr; 12301 } 12302 } 12303 12304 return RelevantExpr; 12305 } 12306 12307 // Return true if expression E associated with value VD has conflicts with other 12308 // map information. 12309 static bool checkMapConflicts( 12310 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 12311 bool CurrentRegionOnly, 12312 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 12313 OpenMPClauseKind CKind) { 12314 assert(VD && E); 12315 SourceLocation ELoc = E->getExprLoc(); 12316 SourceRange ERange = E->getSourceRange(); 12317 12318 // In order to easily check the conflicts we need to match each component of 12319 // the expression under test with the components of the expressions that are 12320 // already in the stack. 12321 12322 assert(!CurComponents.empty() && "Map clause expression with no components!"); 12323 assert(CurComponents.back().getAssociatedDeclaration() == VD && 12324 "Map clause expression with unexpected base!"); 12325 12326 // Variables to help detecting enclosing problems in data environment nests. 12327 bool IsEnclosedByDataEnvironmentExpr = false; 12328 const Expr *EnclosingExpr = nullptr; 12329 12330 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 12331 VD, CurrentRegionOnly, 12332 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 12333 ERange, CKind, &EnclosingExpr, 12334 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 12335 StackComponents, 12336 OpenMPClauseKind) { 12337 assert(!StackComponents.empty() && 12338 "Map clause expression with no components!"); 12339 assert(StackComponents.back().getAssociatedDeclaration() == VD && 12340 "Map clause expression with unexpected base!"); 12341 (void)VD; 12342 12343 // The whole expression in the stack. 12344 const Expr *RE = StackComponents.front().getAssociatedExpression(); 12345 12346 // Expressions must start from the same base. Here we detect at which 12347 // point both expressions diverge from each other and see if we can 12348 // detect if the memory referred to both expressions is contiguous and 12349 // do not overlap. 12350 auto CI = CurComponents.rbegin(); 12351 auto CE = CurComponents.rend(); 12352 auto SI = StackComponents.rbegin(); 12353 auto SE = StackComponents.rend(); 12354 for (; CI != CE && SI != SE; ++CI, ++SI) { 12355 12356 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 12357 // At most one list item can be an array item derived from a given 12358 // variable in map clauses of the same construct. 12359 if (CurrentRegionOnly && 12360 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 12361 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 12362 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 12363 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 12364 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 12365 diag::err_omp_multiple_array_items_in_map_clause) 12366 << CI->getAssociatedExpression()->getSourceRange(); 12367 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 12368 diag::note_used_here) 12369 << SI->getAssociatedExpression()->getSourceRange(); 12370 return true; 12371 } 12372 12373 // Do both expressions have the same kind? 12374 if (CI->getAssociatedExpression()->getStmtClass() != 12375 SI->getAssociatedExpression()->getStmtClass()) 12376 break; 12377 12378 // Are we dealing with different variables/fields? 12379 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 12380 break; 12381 } 12382 // Check if the extra components of the expressions in the enclosing 12383 // data environment are redundant for the current base declaration. 12384 // If they are, the maps completely overlap, which is legal. 12385 for (; SI != SE; ++SI) { 12386 QualType Type; 12387 if (const auto *ASE = 12388 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 12389 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 12390 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 12391 SI->getAssociatedExpression())) { 12392 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 12393 Type = 12394 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12395 } 12396 if (Type.isNull() || Type->isAnyPointerType() || 12397 checkArrayExpressionDoesNotReferToWholeSize( 12398 SemaRef, SI->getAssociatedExpression(), Type)) 12399 break; 12400 } 12401 12402 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 12403 // List items of map clauses in the same construct must not share 12404 // original storage. 12405 // 12406 // If the expressions are exactly the same or one is a subset of the 12407 // other, it means they are sharing storage. 12408 if (CI == CE && SI == SE) { 12409 if (CurrentRegionOnly) { 12410 if (CKind == OMPC_map) { 12411 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 12412 } else { 12413 assert(CKind == OMPC_to || CKind == OMPC_from); 12414 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 12415 << ERange; 12416 } 12417 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12418 << RE->getSourceRange(); 12419 return true; 12420 } 12421 // If we find the same expression in the enclosing data environment, 12422 // that is legal. 12423 IsEnclosedByDataEnvironmentExpr = true; 12424 return false; 12425 } 12426 12427 QualType DerivedType = 12428 std::prev(CI)->getAssociatedDeclaration()->getType(); 12429 SourceLocation DerivedLoc = 12430 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 12431 12432 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12433 // If the type of a list item is a reference to a type T then the type 12434 // will be considered to be T for all purposes of this clause. 12435 DerivedType = DerivedType.getNonReferenceType(); 12436 12437 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 12438 // A variable for which the type is pointer and an array section 12439 // derived from that variable must not appear as list items of map 12440 // clauses of the same construct. 12441 // 12442 // Also, cover one of the cases in: 12443 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 12444 // If any part of the original storage of a list item has corresponding 12445 // storage in the device data environment, all of the original storage 12446 // must have corresponding storage in the device data environment. 12447 // 12448 if (DerivedType->isAnyPointerType()) { 12449 if (CI == CE || SI == SE) { 12450 SemaRef.Diag( 12451 DerivedLoc, 12452 diag::err_omp_pointer_mapped_along_with_derived_section) 12453 << DerivedLoc; 12454 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12455 << RE->getSourceRange(); 12456 return true; 12457 } 12458 if (CI->getAssociatedExpression()->getStmtClass() != 12459 SI->getAssociatedExpression()->getStmtClass() || 12460 CI->getAssociatedDeclaration()->getCanonicalDecl() == 12461 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 12462 assert(CI != CE && SI != SE); 12463 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 12464 << DerivedLoc; 12465 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12466 << RE->getSourceRange(); 12467 return true; 12468 } 12469 } 12470 12471 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 12472 // List items of map clauses in the same construct must not share 12473 // original storage. 12474 // 12475 // An expression is a subset of the other. 12476 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 12477 if (CKind == OMPC_map) { 12478 if (CI != CE || SI != SE) { 12479 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 12480 // a pointer. 12481 auto Begin = 12482 CI != CE ? CurComponents.begin() : StackComponents.begin(); 12483 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 12484 auto It = Begin; 12485 while (It != End && !It->getAssociatedDeclaration()) 12486 std::advance(It, 1); 12487 assert(It != End && 12488 "Expected at least one component with the declaration."); 12489 if (It != Begin && It->getAssociatedDeclaration() 12490 ->getType() 12491 .getCanonicalType() 12492 ->isAnyPointerType()) { 12493 IsEnclosedByDataEnvironmentExpr = false; 12494 EnclosingExpr = nullptr; 12495 return false; 12496 } 12497 } 12498 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 12499 } else { 12500 assert(CKind == OMPC_to || CKind == OMPC_from); 12501 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 12502 << ERange; 12503 } 12504 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12505 << RE->getSourceRange(); 12506 return true; 12507 } 12508 12509 // The current expression uses the same base as other expression in the 12510 // data environment but does not contain it completely. 12511 if (!CurrentRegionOnly && SI != SE) 12512 EnclosingExpr = RE; 12513 12514 // The current expression is a subset of the expression in the data 12515 // environment. 12516 IsEnclosedByDataEnvironmentExpr |= 12517 (!CurrentRegionOnly && CI != CE && SI == SE); 12518 12519 return false; 12520 }); 12521 12522 if (CurrentRegionOnly) 12523 return FoundError; 12524 12525 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 12526 // If any part of the original storage of a list item has corresponding 12527 // storage in the device data environment, all of the original storage must 12528 // have corresponding storage in the device data environment. 12529 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 12530 // If a list item is an element of a structure, and a different element of 12531 // the structure has a corresponding list item in the device data environment 12532 // prior to a task encountering the construct associated with the map clause, 12533 // then the list item must also have a corresponding list item in the device 12534 // data environment prior to the task encountering the construct. 12535 // 12536 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 12537 SemaRef.Diag(ELoc, 12538 diag::err_omp_original_storage_is_shared_and_does_not_contain) 12539 << ERange; 12540 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 12541 << EnclosingExpr->getSourceRange(); 12542 return true; 12543 } 12544 12545 return FoundError; 12546 } 12547 12548 namespace { 12549 // Utility struct that gathers all the related lists associated with a mappable 12550 // expression. 12551 struct MappableVarListInfo { 12552 // The list of expressions. 12553 ArrayRef<Expr *> VarList; 12554 // The list of processed expressions. 12555 SmallVector<Expr *, 16> ProcessedVarList; 12556 // The mappble components for each expression. 12557 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 12558 // The base declaration of the variable. 12559 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 12560 12561 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 12562 // We have a list of components and base declarations for each entry in the 12563 // variable list. 12564 VarComponents.reserve(VarList.size()); 12565 VarBaseDeclarations.reserve(VarList.size()); 12566 } 12567 }; 12568 } 12569 12570 // Check the validity of the provided variable list for the provided clause kind 12571 // \a CKind. In the check process the valid expressions, and mappable expression 12572 // components and variables are extracted and used to fill \a Vars, 12573 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 12574 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 12575 static void 12576 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 12577 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 12578 SourceLocation StartLoc, 12579 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 12580 bool IsMapTypeImplicit = false) { 12581 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 12582 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 12583 "Unexpected clause kind with mappable expressions!"); 12584 12585 // Keep track of the mappable components and base declarations in this clause. 12586 // Each entry in the list is going to have a list of components associated. We 12587 // record each set of the components so that we can build the clause later on. 12588 // In the end we should have the same amount of declarations and component 12589 // lists. 12590 12591 for (Expr *RE : MVLI.VarList) { 12592 assert(RE && "Null expr in omp to/from/map clause"); 12593 SourceLocation ELoc = RE->getExprLoc(); 12594 12595 const Expr *VE = RE->IgnoreParenLValueCasts(); 12596 12597 if (VE->isValueDependent() || VE->isTypeDependent() || 12598 VE->isInstantiationDependent() || 12599 VE->containsUnexpandedParameterPack()) { 12600 // We can only analyze this information once the missing information is 12601 // resolved. 12602 MVLI.ProcessedVarList.push_back(RE); 12603 continue; 12604 } 12605 12606 Expr *SimpleExpr = RE->IgnoreParenCasts(); 12607 12608 if (!RE->IgnoreParenImpCasts()->isLValue()) { 12609 SemaRef.Diag(ELoc, 12610 diag::err_omp_expected_named_var_member_or_array_expression) 12611 << RE->getSourceRange(); 12612 continue; 12613 } 12614 12615 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 12616 ValueDecl *CurDeclaration = nullptr; 12617 12618 // Obtain the array or member expression bases if required. Also, fill the 12619 // components array with all the components identified in the process. 12620 const Expr *BE = checkMapClauseExpressionBase( 12621 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 12622 if (!BE) 12623 continue; 12624 12625 assert(!CurComponents.empty() && 12626 "Invalid mappable expression information."); 12627 12628 // For the following checks, we rely on the base declaration which is 12629 // expected to be associated with the last component. The declaration is 12630 // expected to be a variable or a field (if 'this' is being mapped). 12631 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 12632 assert(CurDeclaration && "Null decl on map clause."); 12633 assert( 12634 CurDeclaration->isCanonicalDecl() && 12635 "Expecting components to have associated only canonical declarations."); 12636 12637 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 12638 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 12639 12640 assert((VD || FD) && "Only variables or fields are expected here!"); 12641 (void)FD; 12642 12643 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 12644 // threadprivate variables cannot appear in a map clause. 12645 // OpenMP 4.5 [2.10.5, target update Construct] 12646 // threadprivate variables cannot appear in a from clause. 12647 if (VD && DSAS->isThreadPrivate(VD)) { 12648 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 12649 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 12650 << getOpenMPClauseName(CKind); 12651 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 12652 continue; 12653 } 12654 12655 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12656 // A list item cannot appear in both a map clause and a data-sharing 12657 // attribute clause on the same construct. 12658 12659 // Check conflicts with other map clause expressions. We check the conflicts 12660 // with the current construct separately from the enclosing data 12661 // environment, because the restrictions are different. We only have to 12662 // check conflicts across regions for the map clauses. 12663 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12664 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 12665 break; 12666 if (CKind == OMPC_map && 12667 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12668 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 12669 break; 12670 12671 // OpenMP 4.5 [2.10.5, target update Construct] 12672 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12673 // If the type of a list item is a reference to a type T then the type will 12674 // be considered to be T for all purposes of this clause. 12675 auto I = llvm::find_if( 12676 CurComponents, 12677 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 12678 return MC.getAssociatedDeclaration(); 12679 }); 12680 assert(I != CurComponents.end() && "Null decl on map clause."); 12681 QualType Type = 12682 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 12683 12684 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 12685 // A list item in a to or from clause must have a mappable type. 12686 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12687 // A list item must have a mappable type. 12688 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 12689 DSAS, Type)) 12690 continue; 12691 12692 if (CKind == OMPC_map) { 12693 // target enter data 12694 // OpenMP [2.10.2, Restrictions, p. 99] 12695 // A map-type must be specified in all map clauses and must be either 12696 // to or alloc. 12697 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 12698 if (DKind == OMPD_target_enter_data && 12699 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 12700 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 12701 << (IsMapTypeImplicit ? 1 : 0) 12702 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 12703 << getOpenMPDirectiveName(DKind); 12704 continue; 12705 } 12706 12707 // target exit_data 12708 // OpenMP [2.10.3, Restrictions, p. 102] 12709 // A map-type must be specified in all map clauses and must be either 12710 // from, release, or delete. 12711 if (DKind == OMPD_target_exit_data && 12712 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 12713 MapType == OMPC_MAP_delete)) { 12714 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 12715 << (IsMapTypeImplicit ? 1 : 0) 12716 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 12717 << getOpenMPDirectiveName(DKind); 12718 continue; 12719 } 12720 12721 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12722 // A list item cannot appear in both a map clause and a data-sharing 12723 // attribute clause on the same construct 12724 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 12725 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 12726 if (isOpenMPPrivate(DVar.CKind)) { 12727 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12728 << getOpenMPClauseName(DVar.CKind) 12729 << getOpenMPClauseName(OMPC_map) 12730 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 12731 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 12732 continue; 12733 } 12734 } 12735 } 12736 12737 // Save the current expression. 12738 MVLI.ProcessedVarList.push_back(RE); 12739 12740 // Store the components in the stack so that they can be used to check 12741 // against other clauses later on. 12742 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 12743 /*WhereFoundClauseKind=*/OMPC_map); 12744 12745 // Save the components and declaration to create the clause. For purposes of 12746 // the clause creation, any component list that has has base 'this' uses 12747 // null as base declaration. 12748 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12749 MVLI.VarComponents.back().append(CurComponents.begin(), 12750 CurComponents.end()); 12751 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 12752 : CurDeclaration); 12753 } 12754 } 12755 12756 OMPClause * 12757 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 12758 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 12759 SourceLocation MapLoc, SourceLocation ColonLoc, 12760 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12761 SourceLocation LParenLoc, SourceLocation EndLoc) { 12762 MappableVarListInfo MVLI(VarList); 12763 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 12764 MapType, IsMapTypeImplicit); 12765 12766 // We need to produce a map clause even if we don't have variables so that 12767 // other diagnostics related with non-existing map clauses are accurate. 12768 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12769 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12770 MVLI.VarComponents, MapTypeModifier, MapType, 12771 IsMapTypeImplicit, MapLoc); 12772 } 12773 12774 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 12775 TypeResult ParsedType) { 12776 assert(ParsedType.isUsable()); 12777 12778 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 12779 if (ReductionType.isNull()) 12780 return QualType(); 12781 12782 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 12783 // A type name in a declare reduction directive cannot be a function type, an 12784 // array type, a reference type, or a type qualified with const, volatile or 12785 // restrict. 12786 if (ReductionType.hasQualifiers()) { 12787 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 12788 return QualType(); 12789 } 12790 12791 if (ReductionType->isFunctionType()) { 12792 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 12793 return QualType(); 12794 } 12795 if (ReductionType->isReferenceType()) { 12796 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 12797 return QualType(); 12798 } 12799 if (ReductionType->isArrayType()) { 12800 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 12801 return QualType(); 12802 } 12803 return ReductionType; 12804 } 12805 12806 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 12807 Scope *S, DeclContext *DC, DeclarationName Name, 12808 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 12809 AccessSpecifier AS, Decl *PrevDeclInScope) { 12810 SmallVector<Decl *, 8> Decls; 12811 Decls.reserve(ReductionTypes.size()); 12812 12813 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 12814 forRedeclarationInCurContext()); 12815 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 12816 // A reduction-identifier may not be re-declared in the current scope for the 12817 // same type or for a type that is compatible according to the base language 12818 // rules. 12819 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 12820 OMPDeclareReductionDecl *PrevDRD = nullptr; 12821 bool InCompoundScope = true; 12822 if (S != nullptr) { 12823 // Find previous declaration with the same name not referenced in other 12824 // declarations. 12825 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 12826 InCompoundScope = 12827 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 12828 LookupName(Lookup, S); 12829 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 12830 /*AllowInlineNamespace=*/false); 12831 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 12832 LookupResult::Filter Filter = Lookup.makeFilter(); 12833 while (Filter.hasNext()) { 12834 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 12835 if (InCompoundScope) { 12836 auto I = UsedAsPrevious.find(PrevDecl); 12837 if (I == UsedAsPrevious.end()) 12838 UsedAsPrevious[PrevDecl] = false; 12839 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 12840 UsedAsPrevious[D] = true; 12841 } 12842 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 12843 PrevDecl->getLocation(); 12844 } 12845 Filter.done(); 12846 if (InCompoundScope) { 12847 for (const auto &PrevData : UsedAsPrevious) { 12848 if (!PrevData.second) { 12849 PrevDRD = PrevData.first; 12850 break; 12851 } 12852 } 12853 } 12854 } else if (PrevDeclInScope != nullptr) { 12855 auto *PrevDRDInScope = PrevDRD = 12856 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 12857 do { 12858 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 12859 PrevDRDInScope->getLocation(); 12860 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 12861 } while (PrevDRDInScope != nullptr); 12862 } 12863 for (const auto &TyData : ReductionTypes) { 12864 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 12865 bool Invalid = false; 12866 if (I != PreviousRedeclTypes.end()) { 12867 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 12868 << TyData.first; 12869 Diag(I->second, diag::note_previous_definition); 12870 Invalid = true; 12871 } 12872 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 12873 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 12874 Name, TyData.first, PrevDRD); 12875 DC->addDecl(DRD); 12876 DRD->setAccess(AS); 12877 Decls.push_back(DRD); 12878 if (Invalid) 12879 DRD->setInvalidDecl(); 12880 else 12881 PrevDRD = DRD; 12882 } 12883 12884 return DeclGroupPtrTy::make( 12885 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 12886 } 12887 12888 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 12889 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12890 12891 // Enter new function scope. 12892 PushFunctionScope(); 12893 setFunctionHasBranchProtectedScope(); 12894 getCurFunction()->setHasOMPDeclareReductionCombiner(); 12895 12896 if (S != nullptr) 12897 PushDeclContext(S, DRD); 12898 else 12899 CurContext = DRD; 12900 12901 PushExpressionEvaluationContext( 12902 ExpressionEvaluationContext::PotentiallyEvaluated); 12903 12904 QualType ReductionType = DRD->getType(); 12905 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 12906 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 12907 // uses semantics of argument handles by value, but it should be passed by 12908 // reference. C lang does not support references, so pass all parameters as 12909 // pointers. 12910 // Create 'T omp_in;' variable. 12911 VarDecl *OmpInParm = 12912 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 12913 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 12914 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 12915 // uses semantics of argument handles by value, but it should be passed by 12916 // reference. C lang does not support references, so pass all parameters as 12917 // pointers. 12918 // Create 'T omp_out;' variable. 12919 VarDecl *OmpOutParm = 12920 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 12921 if (S != nullptr) { 12922 PushOnScopeChains(OmpInParm, S); 12923 PushOnScopeChains(OmpOutParm, S); 12924 } else { 12925 DRD->addDecl(OmpInParm); 12926 DRD->addDecl(OmpOutParm); 12927 } 12928 Expr *InE = 12929 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 12930 Expr *OutE = 12931 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 12932 DRD->setCombinerData(InE, OutE); 12933 } 12934 12935 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 12936 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12937 DiscardCleanupsInEvaluationContext(); 12938 PopExpressionEvaluationContext(); 12939 12940 PopDeclContext(); 12941 PopFunctionScopeInfo(); 12942 12943 if (Combiner != nullptr) 12944 DRD->setCombiner(Combiner); 12945 else 12946 DRD->setInvalidDecl(); 12947 } 12948 12949 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 12950 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12951 12952 // Enter new function scope. 12953 PushFunctionScope(); 12954 setFunctionHasBranchProtectedScope(); 12955 12956 if (S != nullptr) 12957 PushDeclContext(S, DRD); 12958 else 12959 CurContext = DRD; 12960 12961 PushExpressionEvaluationContext( 12962 ExpressionEvaluationContext::PotentiallyEvaluated); 12963 12964 QualType ReductionType = DRD->getType(); 12965 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 12966 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 12967 // uses semantics of argument handles by value, but it should be passed by 12968 // reference. C lang does not support references, so pass all parameters as 12969 // pointers. 12970 // Create 'T omp_priv;' variable. 12971 VarDecl *OmpPrivParm = 12972 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 12973 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 12974 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 12975 // uses semantics of argument handles by value, but it should be passed by 12976 // reference. C lang does not support references, so pass all parameters as 12977 // pointers. 12978 // Create 'T omp_orig;' variable. 12979 VarDecl *OmpOrigParm = 12980 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 12981 if (S != nullptr) { 12982 PushOnScopeChains(OmpPrivParm, S); 12983 PushOnScopeChains(OmpOrigParm, S); 12984 } else { 12985 DRD->addDecl(OmpPrivParm); 12986 DRD->addDecl(OmpOrigParm); 12987 } 12988 Expr *OrigE = 12989 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 12990 Expr *PrivE = 12991 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 12992 DRD->setInitializerData(OrigE, PrivE); 12993 return OmpPrivParm; 12994 } 12995 12996 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 12997 VarDecl *OmpPrivParm) { 12998 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12999 DiscardCleanupsInEvaluationContext(); 13000 PopExpressionEvaluationContext(); 13001 13002 PopDeclContext(); 13003 PopFunctionScopeInfo(); 13004 13005 if (Initializer != nullptr) { 13006 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 13007 } else if (OmpPrivParm->hasInit()) { 13008 DRD->setInitializer(OmpPrivParm->getInit(), 13009 OmpPrivParm->isDirectInit() 13010 ? OMPDeclareReductionDecl::DirectInit 13011 : OMPDeclareReductionDecl::CopyInit); 13012 } else { 13013 DRD->setInvalidDecl(); 13014 } 13015 } 13016 13017 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 13018 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 13019 for (Decl *D : DeclReductions.get()) { 13020 if (IsValid) { 13021 if (S) 13022 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 13023 /*AddToContext=*/false); 13024 } else { 13025 D->setInvalidDecl(); 13026 } 13027 } 13028 return DeclReductions; 13029 } 13030 13031 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 13032 SourceLocation StartLoc, 13033 SourceLocation LParenLoc, 13034 SourceLocation EndLoc) { 13035 Expr *ValExpr = NumTeams; 13036 Stmt *HelperValStmt = nullptr; 13037 13038 // OpenMP [teams Constrcut, Restrictions] 13039 // The num_teams expression must evaluate to a positive integer value. 13040 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 13041 /*StrictlyPositive=*/true)) 13042 return nullptr; 13043 13044 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13045 OpenMPDirectiveKind CaptureRegion = 13046 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 13047 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13048 ValExpr = MakeFullExpr(ValExpr).get(); 13049 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13050 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13051 HelperValStmt = buildPreInits(Context, Captures); 13052 } 13053 13054 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 13055 StartLoc, LParenLoc, EndLoc); 13056 } 13057 13058 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 13059 SourceLocation StartLoc, 13060 SourceLocation LParenLoc, 13061 SourceLocation EndLoc) { 13062 Expr *ValExpr = ThreadLimit; 13063 Stmt *HelperValStmt = nullptr; 13064 13065 // OpenMP [teams Constrcut, Restrictions] 13066 // The thread_limit expression must evaluate to a positive integer value. 13067 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 13068 /*StrictlyPositive=*/true)) 13069 return nullptr; 13070 13071 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13072 OpenMPDirectiveKind CaptureRegion = 13073 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 13074 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13075 ValExpr = MakeFullExpr(ValExpr).get(); 13076 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13077 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13078 HelperValStmt = buildPreInits(Context, Captures); 13079 } 13080 13081 return new (Context) OMPThreadLimitClause( 13082 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 13083 } 13084 13085 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 13086 SourceLocation StartLoc, 13087 SourceLocation LParenLoc, 13088 SourceLocation EndLoc) { 13089 Expr *ValExpr = Priority; 13090 13091 // OpenMP [2.9.1, task Constrcut] 13092 // The priority-value is a non-negative numerical scalar expression. 13093 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 13094 /*StrictlyPositive=*/false)) 13095 return nullptr; 13096 13097 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 13098 } 13099 13100 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 13101 SourceLocation StartLoc, 13102 SourceLocation LParenLoc, 13103 SourceLocation EndLoc) { 13104 Expr *ValExpr = Grainsize; 13105 13106 // OpenMP [2.9.2, taskloop Constrcut] 13107 // The parameter of the grainsize clause must be a positive integer 13108 // expression. 13109 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 13110 /*StrictlyPositive=*/true)) 13111 return nullptr; 13112 13113 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 13114 } 13115 13116 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 13117 SourceLocation StartLoc, 13118 SourceLocation LParenLoc, 13119 SourceLocation EndLoc) { 13120 Expr *ValExpr = NumTasks; 13121 13122 // OpenMP [2.9.2, taskloop Constrcut] 13123 // The parameter of the num_tasks clause must be a positive integer 13124 // expression. 13125 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 13126 /*StrictlyPositive=*/true)) 13127 return nullptr; 13128 13129 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 13130 } 13131 13132 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 13133 SourceLocation LParenLoc, 13134 SourceLocation EndLoc) { 13135 // OpenMP [2.13.2, critical construct, Description] 13136 // ... where hint-expression is an integer constant expression that evaluates 13137 // to a valid lock hint. 13138 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 13139 if (HintExpr.isInvalid()) 13140 return nullptr; 13141 return new (Context) 13142 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 13143 } 13144 13145 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 13146 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 13147 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 13148 SourceLocation EndLoc) { 13149 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 13150 std::string Values; 13151 Values += "'"; 13152 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 13153 Values += "'"; 13154 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 13155 << Values << getOpenMPClauseName(OMPC_dist_schedule); 13156 return nullptr; 13157 } 13158 Expr *ValExpr = ChunkSize; 13159 Stmt *HelperValStmt = nullptr; 13160 if (ChunkSize) { 13161 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13162 !ChunkSize->isInstantiationDependent() && 13163 !ChunkSize->containsUnexpandedParameterPack()) { 13164 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13165 ExprResult Val = 13166 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13167 if (Val.isInvalid()) 13168 return nullptr; 13169 13170 ValExpr = Val.get(); 13171 13172 // OpenMP [2.7.1, Restrictions] 13173 // chunk_size must be a loop invariant integer expression with a positive 13174 // value. 13175 llvm::APSInt Result; 13176 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 13177 if (Result.isSigned() && !Result.isStrictlyPositive()) { 13178 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13179 << "dist_schedule" << ChunkSize->getSourceRange(); 13180 return nullptr; 13181 } 13182 } else if (getOpenMPCaptureRegionForClause( 13183 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 13184 OMPD_unknown && 13185 !CurContext->isDependentContext()) { 13186 ValExpr = MakeFullExpr(ValExpr).get(); 13187 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13188 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13189 HelperValStmt = buildPreInits(Context, Captures); 13190 } 13191 } 13192 } 13193 13194 return new (Context) 13195 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 13196 Kind, ValExpr, HelperValStmt); 13197 } 13198 13199 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 13200 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 13201 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 13202 SourceLocation KindLoc, SourceLocation EndLoc) { 13203 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 13204 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 13205 std::string Value; 13206 SourceLocation Loc; 13207 Value += "'"; 13208 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 13209 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 13210 OMPC_DEFAULTMAP_MODIFIER_tofrom); 13211 Loc = MLoc; 13212 } else { 13213 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 13214 OMPC_DEFAULTMAP_scalar); 13215 Loc = KindLoc; 13216 } 13217 Value += "'"; 13218 Diag(Loc, diag::err_omp_unexpected_clause_value) 13219 << Value << getOpenMPClauseName(OMPC_defaultmap); 13220 return nullptr; 13221 } 13222 DSAStack->setDefaultDMAToFromScalar(StartLoc); 13223 13224 return new (Context) 13225 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 13226 } 13227 13228 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 13229 DeclContext *CurLexicalContext = getCurLexicalContext(); 13230 if (!CurLexicalContext->isFileContext() && 13231 !CurLexicalContext->isExternCContext() && 13232 !CurLexicalContext->isExternCXXContext() && 13233 !isa<CXXRecordDecl>(CurLexicalContext) && 13234 !isa<ClassTemplateDecl>(CurLexicalContext) && 13235 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 13236 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 13237 Diag(Loc, diag::err_omp_region_not_file_context); 13238 return false; 13239 } 13240 ++DeclareTargetNestingLevel; 13241 return true; 13242 } 13243 13244 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 13245 assert(DeclareTargetNestingLevel > 0 && 13246 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 13247 --DeclareTargetNestingLevel; 13248 } 13249 13250 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 13251 CXXScopeSpec &ScopeSpec, 13252 const DeclarationNameInfo &Id, 13253 OMPDeclareTargetDeclAttr::MapTypeTy MT, 13254 NamedDeclSetType &SameDirectiveDecls) { 13255 LookupResult Lookup(*this, Id, LookupOrdinaryName); 13256 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 13257 13258 if (Lookup.isAmbiguous()) 13259 return; 13260 Lookup.suppressDiagnostics(); 13261 13262 if (!Lookup.isSingleResult()) { 13263 if (TypoCorrection Corrected = 13264 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 13265 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 13266 CTK_ErrorRecovery)) { 13267 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 13268 << Id.getName()); 13269 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 13270 return; 13271 } 13272 13273 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 13274 return; 13275 } 13276 13277 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 13278 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 13279 isa<FunctionTemplateDecl>(ND)) { 13280 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 13281 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 13282 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 13283 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 13284 cast<ValueDecl>(ND)); 13285 if (!Res) { 13286 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 13287 ND->addAttr(A); 13288 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13289 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 13290 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 13291 } else if (*Res != MT) { 13292 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 13293 << Id.getName(); 13294 } 13295 } else { 13296 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 13297 } 13298 } 13299 13300 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 13301 Sema &SemaRef, Decl *D) { 13302 if (!D || !isa<VarDecl>(D)) 13303 return; 13304 auto *VD = cast<VarDecl>(D); 13305 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 13306 return; 13307 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 13308 SemaRef.Diag(SL, diag::note_used_here) << SR; 13309 } 13310 13311 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 13312 Sema &SemaRef, DSAStackTy *Stack, 13313 ValueDecl *VD) { 13314 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 13315 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 13316 /*FullCheck=*/false); 13317 } 13318 13319 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 13320 SourceLocation IdLoc) { 13321 if (!D || D->isInvalidDecl()) 13322 return; 13323 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 13324 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 13325 if (auto *VD = dyn_cast<VarDecl>(D)) { 13326 // Only global variables can be marked as declare target. 13327 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 13328 !VD->isStaticDataMember()) 13329 return; 13330 // 2.10.6: threadprivate variable cannot appear in a declare target 13331 // directive. 13332 if (DSAStack->isThreadPrivate(VD)) { 13333 Diag(SL, diag::err_omp_threadprivate_in_target); 13334 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 13335 return; 13336 } 13337 } 13338 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 13339 D = FTD->getTemplatedDecl(); 13340 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 13341 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 13342 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 13343 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 13344 assert(IdLoc.isValid() && "Source location is expected"); 13345 Diag(IdLoc, diag::err_omp_function_in_link_clause); 13346 Diag(FD->getLocation(), diag::note_defined_here) << FD; 13347 return; 13348 } 13349 } 13350 if (auto *VD = dyn_cast<ValueDecl>(D)) { 13351 // Problem if any with var declared with incomplete type will be reported 13352 // as normal, so no need to check it here. 13353 if ((E || !VD->getType()->isIncompleteType()) && 13354 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 13355 return; 13356 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 13357 // Checking declaration inside declare target region. 13358 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 13359 isa<FunctionTemplateDecl>(D)) { 13360 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 13361 Context, OMPDeclareTargetDeclAttr::MT_To); 13362 D->addAttr(A); 13363 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13364 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 13365 } 13366 return; 13367 } 13368 } 13369 if (!E) 13370 return; 13371 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 13372 } 13373 13374 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 13375 SourceLocation StartLoc, 13376 SourceLocation LParenLoc, 13377 SourceLocation EndLoc) { 13378 MappableVarListInfo MVLI(VarList); 13379 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 13380 if (MVLI.ProcessedVarList.empty()) 13381 return nullptr; 13382 13383 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13384 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13385 MVLI.VarComponents); 13386 } 13387 13388 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 13389 SourceLocation StartLoc, 13390 SourceLocation LParenLoc, 13391 SourceLocation EndLoc) { 13392 MappableVarListInfo MVLI(VarList); 13393 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 13394 if (MVLI.ProcessedVarList.empty()) 13395 return nullptr; 13396 13397 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13398 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13399 MVLI.VarComponents); 13400 } 13401 13402 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 13403 SourceLocation StartLoc, 13404 SourceLocation LParenLoc, 13405 SourceLocation EndLoc) { 13406 MappableVarListInfo MVLI(VarList); 13407 SmallVector<Expr *, 8> PrivateCopies; 13408 SmallVector<Expr *, 8> Inits; 13409 13410 for (Expr *RefExpr : VarList) { 13411 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 13412 SourceLocation ELoc; 13413 SourceRange ERange; 13414 Expr *SimpleRefExpr = RefExpr; 13415 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13416 if (Res.second) { 13417 // It will be analyzed later. 13418 MVLI.ProcessedVarList.push_back(RefExpr); 13419 PrivateCopies.push_back(nullptr); 13420 Inits.push_back(nullptr); 13421 } 13422 ValueDecl *D = Res.first; 13423 if (!D) 13424 continue; 13425 13426 QualType Type = D->getType(); 13427 Type = Type.getNonReferenceType().getUnqualifiedType(); 13428 13429 auto *VD = dyn_cast<VarDecl>(D); 13430 13431 // Item should be a pointer or reference to pointer. 13432 if (!Type->isPointerType()) { 13433 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 13434 << 0 << RefExpr->getSourceRange(); 13435 continue; 13436 } 13437 13438 // Build the private variable and the expression that refers to it. 13439 auto VDPrivate = 13440 buildVarDecl(*this, ELoc, Type, D->getName(), 13441 D->hasAttrs() ? &D->getAttrs() : nullptr, 13442 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13443 if (VDPrivate->isInvalidDecl()) 13444 continue; 13445 13446 CurContext->addDecl(VDPrivate); 13447 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13448 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13449 13450 // Add temporary variable to initialize the private copy of the pointer. 13451 VarDecl *VDInit = 13452 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 13453 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 13454 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 13455 AddInitializerToDecl(VDPrivate, 13456 DefaultLvalueConversion(VDInitRefExpr).get(), 13457 /*DirectInit=*/false); 13458 13459 // If required, build a capture to implement the privatization initialized 13460 // with the current list item value. 13461 DeclRefExpr *Ref = nullptr; 13462 if (!VD) 13463 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13464 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 13465 PrivateCopies.push_back(VDPrivateRefExpr); 13466 Inits.push_back(VDInitRefExpr); 13467 13468 // We need to add a data sharing attribute for this variable to make sure it 13469 // is correctly captured. A variable that shows up in a use_device_ptr has 13470 // similar properties of a first private variable. 13471 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13472 13473 // Create a mappable component for the list item. List items in this clause 13474 // only need a component. 13475 MVLI.VarBaseDeclarations.push_back(D); 13476 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13477 MVLI.VarComponents.back().push_back( 13478 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 13479 } 13480 13481 if (MVLI.ProcessedVarList.empty()) 13482 return nullptr; 13483 13484 return OMPUseDevicePtrClause::Create( 13485 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 13486 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 13487 } 13488 13489 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 13490 SourceLocation StartLoc, 13491 SourceLocation LParenLoc, 13492 SourceLocation EndLoc) { 13493 MappableVarListInfo MVLI(VarList); 13494 for (Expr *RefExpr : VarList) { 13495 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 13496 SourceLocation ELoc; 13497 SourceRange ERange; 13498 Expr *SimpleRefExpr = RefExpr; 13499 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13500 if (Res.second) { 13501 // It will be analyzed later. 13502 MVLI.ProcessedVarList.push_back(RefExpr); 13503 } 13504 ValueDecl *D = Res.first; 13505 if (!D) 13506 continue; 13507 13508 QualType Type = D->getType(); 13509 // item should be a pointer or array or reference to pointer or array 13510 if (!Type.getNonReferenceType()->isPointerType() && 13511 !Type.getNonReferenceType()->isArrayType()) { 13512 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 13513 << 0 << RefExpr->getSourceRange(); 13514 continue; 13515 } 13516 13517 // Check if the declaration in the clause does not show up in any data 13518 // sharing attribute. 13519 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13520 if (isOpenMPPrivate(DVar.CKind)) { 13521 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13522 << getOpenMPClauseName(DVar.CKind) 13523 << getOpenMPClauseName(OMPC_is_device_ptr) 13524 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13525 reportOriginalDsa(*this, DSAStack, D, DVar); 13526 continue; 13527 } 13528 13529 const Expr *ConflictExpr; 13530 if (DSAStack->checkMappableExprComponentListsForDecl( 13531 D, /*CurrentRegionOnly=*/true, 13532 [&ConflictExpr]( 13533 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 13534 OpenMPClauseKind) -> bool { 13535 ConflictExpr = R.front().getAssociatedExpression(); 13536 return true; 13537 })) { 13538 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 13539 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 13540 << ConflictExpr->getSourceRange(); 13541 continue; 13542 } 13543 13544 // Store the components in the stack so that they can be used to check 13545 // against other clauses later on. 13546 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 13547 DSAStack->addMappableExpressionComponents( 13548 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 13549 13550 // Record the expression we've just processed. 13551 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 13552 13553 // Create a mappable component for the list item. List items in this clause 13554 // only need a component. We use a null declaration to signal fields in 13555 // 'this'. 13556 assert((isa<DeclRefExpr>(SimpleRefExpr) || 13557 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 13558 "Unexpected device pointer expression!"); 13559 MVLI.VarBaseDeclarations.push_back( 13560 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 13561 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13562 MVLI.VarComponents.back().push_back(MC); 13563 } 13564 13565 if (MVLI.ProcessedVarList.empty()) 13566 return nullptr; 13567 13568 return OMPIsDevicePtrClause::Create( 13569 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 13570 MVLI.VarBaseDeclarations, MVLI.VarComponents); 13571 } 13572