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/AST/TypeOrdering.h" 26 #include "clang/Basic/OpenMPKinds.h" 27 #include "clang/Sema/Initialization.h" 28 #include "clang/Sema/Lookup.h" 29 #include "clang/Sema/Scope.h" 30 #include "clang/Sema/ScopeInfo.h" 31 #include "clang/Sema/SemaInternal.h" 32 #include "llvm/ADT/PointerEmbeddedInt.h" 33 using namespace clang; 34 35 //===----------------------------------------------------------------------===// 36 // Stack of data-sharing attributes for variables 37 //===----------------------------------------------------------------------===// 38 39 static const Expr *checkMapClauseExpressionBase( 40 Sema &SemaRef, Expr *E, 41 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 42 OpenMPClauseKind CKind, bool NoDiagnose); 43 44 namespace { 45 /// Default data sharing attributes, which can be applied to directive. 46 enum DefaultDataSharingAttributes { 47 DSA_unspecified = 0, /// Data sharing attribute not specified. 48 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 49 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 50 }; 51 52 /// Attributes of the defaultmap clause. 53 enum DefaultMapAttributes { 54 DMA_unspecified, /// Default mapping is not specified. 55 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 56 }; 57 58 /// Stack for tracking declarations used in OpenMP directives and 59 /// clauses and their data-sharing attributes. 60 class DSAStackTy { 61 public: 62 struct DSAVarData { 63 OpenMPDirectiveKind DKind = OMPD_unknown; 64 OpenMPClauseKind CKind = OMPC_unknown; 65 const Expr *RefExpr = nullptr; 66 DeclRefExpr *PrivateCopy = nullptr; 67 SourceLocation ImplicitDSALoc; 68 DSAVarData() = default; 69 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 70 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 71 SourceLocation ImplicitDSALoc) 72 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 73 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 74 }; 75 using OperatorOffsetTy = 76 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 77 using DoacrossDependMapTy = 78 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 79 80 private: 81 struct DSAInfo { 82 OpenMPClauseKind Attributes = OMPC_unknown; 83 /// Pointer to a reference expression and a flag which shows that the 84 /// variable is marked as lastprivate(true) or not (false). 85 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 86 DeclRefExpr *PrivateCopy = nullptr; 87 }; 88 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 89 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 90 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 91 using LoopControlVariablesMapTy = 92 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 93 /// Struct that associates a component with the clause kind where they are 94 /// found. 95 struct MappedExprComponentTy { 96 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 97 OpenMPClauseKind Kind = OMPC_unknown; 98 }; 99 using MappedExprComponentsTy = 100 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 101 using CriticalsWithHintsTy = 102 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 103 struct ReductionData { 104 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 105 SourceRange ReductionRange; 106 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 107 ReductionData() = default; 108 void set(BinaryOperatorKind BO, SourceRange RR) { 109 ReductionRange = RR; 110 ReductionOp = BO; 111 } 112 void set(const Expr *RefExpr, SourceRange RR) { 113 ReductionRange = RR; 114 ReductionOp = RefExpr; 115 } 116 }; 117 using DeclReductionMapTy = 118 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 119 120 struct SharingMapTy { 121 DeclSAMapTy SharingMap; 122 DeclReductionMapTy ReductionMap; 123 AlignedMapTy AlignedMap; 124 MappedExprComponentsTy MappedExprComponents; 125 LoopControlVariablesMapTy LCVMap; 126 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 127 SourceLocation DefaultAttrLoc; 128 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 129 SourceLocation DefaultMapAttrLoc; 130 OpenMPDirectiveKind Directive = OMPD_unknown; 131 DeclarationNameInfo DirectiveName; 132 Scope *CurScope = nullptr; 133 SourceLocation ConstructLoc; 134 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 135 /// get the data (loop counters etc.) about enclosing loop-based construct. 136 /// This data is required during codegen. 137 DoacrossDependMapTy DoacrossDepends; 138 /// first argument (Expr *) contains optional argument of the 139 /// 'ordered' clause, the second one is true if the regions has 'ordered' 140 /// clause, false otherwise. 141 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 142 unsigned AssociatedLoops = 1; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 SourceLocation InnerTeamsRegionLoc; 148 /// Reference to the taskgroup task_reduction reference expression. 149 Expr *TaskgroupReductionRef = nullptr; 150 llvm::DenseSet<QualType> MappedClassesQualTypes; 151 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 152 Scope *CurScope, SourceLocation Loc) 153 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 154 ConstructLoc(Loc) {} 155 SharingMapTy() = default; 156 }; 157 158 using StackTy = SmallVector<SharingMapTy, 4>; 159 160 /// Stack of used declaration and their data-sharing attributes. 161 DeclSAMapTy Threadprivates; 162 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 163 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 164 /// true, if check for DSA must be from parent directive, false, if 165 /// from current directive. 166 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 167 Sema &SemaRef; 168 bool ForceCapturing = false; 169 /// true if all the vaiables in the target executable directives must be 170 /// captured by reference. 171 bool ForceCaptureByReferenceInTargetExecutable = false; 172 CriticalsWithHintsTy Criticals; 173 174 using iterator = StackTy::const_reverse_iterator; 175 176 DSAVarData getDSA(iterator &Iter, ValueDecl *D) const; 177 178 /// Checks if the variable is a local for OpenMP region. 179 bool isOpenMPLocal(VarDecl *D, iterator Iter) const; 180 181 bool isStackEmpty() const { 182 return Stack.empty() || 183 Stack.back().second != CurrentNonCapturingFunctionScope || 184 Stack.back().first.empty(); 185 } 186 187 /// Vector of previously declared requires directives 188 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 189 190 public: 191 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 192 193 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 194 OpenMPClauseKind getClauseParsingMode() const { 195 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 196 return ClauseKindMode; 197 } 198 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 199 200 bool isForceVarCapturing() const { return ForceCapturing; } 201 void setForceVarCapturing(bool V) { ForceCapturing = V; } 202 203 void setForceCaptureByReferenceInTargetExecutable(bool V) { 204 ForceCaptureByReferenceInTargetExecutable = V; 205 } 206 bool isForceCaptureByReferenceInTargetExecutable() const { 207 return ForceCaptureByReferenceInTargetExecutable; 208 } 209 210 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 211 Scope *CurScope, SourceLocation Loc) { 212 if (Stack.empty() || 213 Stack.back().second != CurrentNonCapturingFunctionScope) 214 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 215 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 216 Stack.back().first.back().DefaultAttrLoc = Loc; 217 } 218 219 void pop() { 220 assert(!Stack.back().first.empty() && 221 "Data-sharing attributes stack is empty!"); 222 Stack.back().first.pop_back(); 223 } 224 225 /// Marks that we're started loop parsing. 226 void loopInit() { 227 assert(isOpenMPLoopDirective(getCurrentDirective()) && 228 "Expected loop-based directive."); 229 Stack.back().first.back().LoopStart = true; 230 } 231 /// Start capturing of the variables in the loop context. 232 void loopStart() { 233 assert(isOpenMPLoopDirective(getCurrentDirective()) && 234 "Expected loop-based directive."); 235 Stack.back().first.back().LoopStart = false; 236 } 237 /// true, if variables are captured, false otherwise. 238 bool isLoopStarted() const { 239 assert(isOpenMPLoopDirective(getCurrentDirective()) && 240 "Expected loop-based directive."); 241 return !Stack.back().first.back().LoopStart; 242 } 243 /// Marks (or clears) declaration as possibly loop counter. 244 void resetPossibleLoopCounter(const Decl *D = nullptr) { 245 Stack.back().first.back().PossiblyLoopCounter = 246 D ? D->getCanonicalDecl() : D; 247 } 248 /// Gets the possible loop counter decl. 249 const Decl *getPossiblyLoopCunter() const { 250 return Stack.back().first.back().PossiblyLoopCounter; 251 } 252 /// Start new OpenMP region stack in new non-capturing function. 253 void pushFunction() { 254 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 255 assert(!isa<CapturingScopeInfo>(CurFnScope)); 256 CurrentNonCapturingFunctionScope = CurFnScope; 257 } 258 /// Pop region stack for non-capturing function. 259 void popFunction(const FunctionScopeInfo *OldFSI) { 260 if (!Stack.empty() && Stack.back().second == OldFSI) { 261 assert(Stack.back().first.empty()); 262 Stack.pop_back(); 263 } 264 CurrentNonCapturingFunctionScope = nullptr; 265 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 266 if (!isa<CapturingScopeInfo>(FSI)) { 267 CurrentNonCapturingFunctionScope = FSI; 268 break; 269 } 270 } 271 } 272 273 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 274 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 275 } 276 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 277 getCriticalWithHint(const DeclarationNameInfo &Name) const { 278 auto I = Criticals.find(Name.getAsString()); 279 if (I != Criticals.end()) 280 return I->second; 281 return std::make_pair(nullptr, llvm::APSInt()); 282 } 283 /// If 'aligned' declaration for given variable \a D was not seen yet, 284 /// add it and return NULL; otherwise return previous occurrence's expression 285 /// for diagnostics. 286 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 287 288 /// Register specified variable as loop control variable. 289 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 290 /// Check if the specified variable is a loop control variable for 291 /// current region. 292 /// \return The index of the loop control variable in the list of associated 293 /// for-loops (from outer to inner). 294 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 295 /// Check if the specified variable is a loop control variable for 296 /// parent region. 297 /// \return The index of the loop control variable in the list of associated 298 /// for-loops (from outer to inner). 299 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 300 /// Get the loop control variable for the I-th loop (or nullptr) in 301 /// parent directive. 302 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 303 304 /// Adds explicit data sharing attribute to the specified declaration. 305 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 306 DeclRefExpr *PrivateCopy = nullptr); 307 308 /// Adds additional information for the reduction items with the reduction id 309 /// represented as an operator. 310 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 311 BinaryOperatorKind BOK); 312 /// Adds additional information for the reduction items with the reduction id 313 /// represented as reduction identifier. 314 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 315 const Expr *ReductionRef); 316 /// Returns the location and reduction operation from the innermost parent 317 /// region for the given \p D. 318 const DSAVarData 319 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 320 BinaryOperatorKind &BOK, 321 Expr *&TaskgroupDescriptor) const; 322 /// Returns the location and reduction operation from the innermost parent 323 /// region for the given \p D. 324 const DSAVarData 325 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 326 const Expr *&ReductionRef, 327 Expr *&TaskgroupDescriptor) const; 328 /// Return reduction reference expression for the current taskgroup. 329 Expr *getTaskgroupReductionRef() const { 330 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 331 "taskgroup reference expression requested for non taskgroup " 332 "directive."); 333 return Stack.back().first.back().TaskgroupReductionRef; 334 } 335 /// Checks if the given \p VD declaration is actually a taskgroup reduction 336 /// descriptor variable at the \p Level of OpenMP regions. 337 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 338 return Stack.back().first[Level].TaskgroupReductionRef && 339 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 340 ->getDecl() == VD; 341 } 342 343 /// Returns data sharing attributes from top of the stack for the 344 /// specified declaration. 345 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 346 /// Returns data-sharing attributes for the specified declaration. 347 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 348 /// Checks if the specified variables has data-sharing attributes which 349 /// match specified \a CPred predicate in any directive which matches \a DPred 350 /// predicate. 351 const DSAVarData 352 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 353 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 354 bool FromParent) const; 355 /// Checks if the specified variables has data-sharing attributes which 356 /// match specified \a CPred predicate in any innermost directive which 357 /// matches \a DPred predicate. 358 const DSAVarData 359 hasInnermostDSA(ValueDecl *D, 360 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 361 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 362 bool FromParent) const; 363 /// Checks if the specified variables has explicit data-sharing 364 /// attributes which match specified \a CPred predicate at the specified 365 /// OpenMP region. 366 bool hasExplicitDSA(const ValueDecl *D, 367 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 368 unsigned Level, bool NotLastprivate = false) const; 369 370 /// Returns true if the directive at level \Level matches in the 371 /// specified \a DPred predicate. 372 bool hasExplicitDirective( 373 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 374 unsigned Level) const; 375 376 /// Finds a directive which matches specified \a DPred predicate. 377 bool hasDirective( 378 const llvm::function_ref<bool( 379 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 380 DPred, 381 bool FromParent) const; 382 383 /// Returns currently analyzed directive. 384 OpenMPDirectiveKind getCurrentDirective() const { 385 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 386 } 387 /// Returns directive kind at specified level. 388 OpenMPDirectiveKind getDirective(unsigned Level) const { 389 assert(!isStackEmpty() && "No directive at specified level."); 390 return Stack.back().first[Level].Directive; 391 } 392 /// Returns parent directive. 393 OpenMPDirectiveKind getParentDirective() const { 394 if (isStackEmpty() || Stack.back().first.size() == 1) 395 return OMPD_unknown; 396 return std::next(Stack.back().first.rbegin())->Directive; 397 } 398 399 /// Add requires decl to internal vector 400 void addRequiresDecl(OMPRequiresDecl *RD) { 401 RequiresDecls.push_back(RD); 402 } 403 404 /// Checks for a duplicate clause amongst previously declared requires 405 /// directives 406 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 407 bool IsDuplicate = false; 408 for (OMPClause *CNew : ClauseList) { 409 for (const OMPRequiresDecl *D : RequiresDecls) { 410 for (const OMPClause *CPrev : D->clauselists()) { 411 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 412 SemaRef.Diag(CNew->getBeginLoc(), 413 diag::err_omp_requires_clause_redeclaration) 414 << getOpenMPClauseName(CNew->getClauseKind()); 415 SemaRef.Diag(CPrev->getBeginLoc(), 416 diag::note_omp_requires_previous_clause) 417 << getOpenMPClauseName(CPrev->getClauseKind()); 418 IsDuplicate = true; 419 } 420 } 421 } 422 } 423 return IsDuplicate; 424 } 425 426 /// Set default data sharing attribute to none. 427 void setDefaultDSANone(SourceLocation Loc) { 428 assert(!isStackEmpty()); 429 Stack.back().first.back().DefaultAttr = DSA_none; 430 Stack.back().first.back().DefaultAttrLoc = Loc; 431 } 432 /// Set default data sharing attribute to shared. 433 void setDefaultDSAShared(SourceLocation Loc) { 434 assert(!isStackEmpty()); 435 Stack.back().first.back().DefaultAttr = DSA_shared; 436 Stack.back().first.back().DefaultAttrLoc = Loc; 437 } 438 /// Set default data mapping attribute to 'tofrom:scalar'. 439 void setDefaultDMAToFromScalar(SourceLocation Loc) { 440 assert(!isStackEmpty()); 441 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 442 Stack.back().first.back().DefaultMapAttrLoc = Loc; 443 } 444 445 DefaultDataSharingAttributes getDefaultDSA() const { 446 return isStackEmpty() ? DSA_unspecified 447 : Stack.back().first.back().DefaultAttr; 448 } 449 SourceLocation getDefaultDSALocation() const { 450 return isStackEmpty() ? SourceLocation() 451 : Stack.back().first.back().DefaultAttrLoc; 452 } 453 DefaultMapAttributes getDefaultDMA() const { 454 return isStackEmpty() ? DMA_unspecified 455 : Stack.back().first.back().DefaultMapAttr; 456 } 457 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 458 return Stack.back().first[Level].DefaultMapAttr; 459 } 460 SourceLocation getDefaultDMALocation() const { 461 return isStackEmpty() ? SourceLocation() 462 : Stack.back().first.back().DefaultMapAttrLoc; 463 } 464 465 /// Checks if the specified variable is a threadprivate. 466 bool isThreadPrivate(VarDecl *D) { 467 const DSAVarData DVar = getTopDSA(D, false); 468 return isOpenMPThreadPrivate(DVar.CKind); 469 } 470 471 /// Marks current region as ordered (it has an 'ordered' clause). 472 void setOrderedRegion(bool IsOrdered, const Expr *Param, 473 OMPOrderedClause *Clause) { 474 assert(!isStackEmpty()); 475 if (IsOrdered) 476 Stack.back().first.back().OrderedRegion.emplace(Param, Clause); 477 else 478 Stack.back().first.back().OrderedRegion.reset(); 479 } 480 /// Returns true, if region is ordered (has associated 'ordered' clause), 481 /// false - otherwise. 482 bool isOrderedRegion() const { 483 if (isStackEmpty()) 484 return false; 485 return Stack.back().first.rbegin()->OrderedRegion.hasValue(); 486 } 487 /// Returns optional parameter for the ordered region. 488 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 489 if (isStackEmpty() || 490 !Stack.back().first.rbegin()->OrderedRegion.hasValue()) 491 return std::make_pair(nullptr, nullptr); 492 return Stack.back().first.rbegin()->OrderedRegion.getValue(); 493 } 494 /// Returns true, if parent region is ordered (has associated 495 /// 'ordered' clause), false - otherwise. 496 bool isParentOrderedRegion() const { 497 if (isStackEmpty() || Stack.back().first.size() == 1) 498 return false; 499 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); 500 } 501 /// Returns optional parameter for the ordered region. 502 std::pair<const Expr *, OMPOrderedClause *> 503 getParentOrderedRegionParam() const { 504 if (isStackEmpty() || Stack.back().first.size() == 1 || 505 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) 506 return std::make_pair(nullptr, nullptr); 507 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); 508 } 509 /// Marks current region as nowait (it has a 'nowait' clause). 510 void setNowaitRegion(bool IsNowait = true) { 511 assert(!isStackEmpty()); 512 Stack.back().first.back().NowaitRegion = IsNowait; 513 } 514 /// Returns true, if parent region is nowait (has associated 515 /// 'nowait' clause), false - otherwise. 516 bool isParentNowaitRegion() const { 517 if (isStackEmpty() || Stack.back().first.size() == 1) 518 return false; 519 return std::next(Stack.back().first.rbegin())->NowaitRegion; 520 } 521 /// Marks parent region as cancel region. 522 void setParentCancelRegion(bool Cancel = true) { 523 if (!isStackEmpty() && Stack.back().first.size() > 1) { 524 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 525 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 526 } 527 } 528 /// Return true if current region has inner cancel construct. 529 bool isCancelRegion() const { 530 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 531 } 532 533 /// Set collapse value for the region. 534 void setAssociatedLoops(unsigned Val) { 535 assert(!isStackEmpty()); 536 Stack.back().first.back().AssociatedLoops = Val; 537 } 538 /// Return collapse value for region. 539 unsigned getAssociatedLoops() const { 540 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 541 } 542 543 /// Marks current target region as one with closely nested teams 544 /// region. 545 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 546 if (!isStackEmpty() && Stack.back().first.size() > 1) { 547 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 548 TeamsRegionLoc; 549 } 550 } 551 /// Returns true, if current region has closely nested teams region. 552 bool hasInnerTeamsRegion() const { 553 return getInnerTeamsRegionLoc().isValid(); 554 } 555 /// Returns location of the nested teams region (if any). 556 SourceLocation getInnerTeamsRegionLoc() const { 557 return isStackEmpty() ? SourceLocation() 558 : Stack.back().first.back().InnerTeamsRegionLoc; 559 } 560 561 Scope *getCurScope() const { 562 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 563 } 564 SourceLocation getConstructLoc() const { 565 return isStackEmpty() ? SourceLocation() 566 : Stack.back().first.back().ConstructLoc; 567 } 568 569 /// Do the check specified in \a Check to all component lists and return true 570 /// if any issue is found. 571 bool checkMappableExprComponentListsForDecl( 572 const ValueDecl *VD, bool CurrentRegionOnly, 573 const llvm::function_ref< 574 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 575 OpenMPClauseKind)> 576 Check) const { 577 if (isStackEmpty()) 578 return false; 579 auto SI = Stack.back().first.rbegin(); 580 auto SE = Stack.back().first.rend(); 581 582 if (SI == SE) 583 return false; 584 585 if (CurrentRegionOnly) 586 SE = std::next(SI); 587 else 588 std::advance(SI, 1); 589 590 for (; SI != SE; ++SI) { 591 auto MI = SI->MappedExprComponents.find(VD); 592 if (MI != SI->MappedExprComponents.end()) 593 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 594 MI->second.Components) 595 if (Check(L, MI->second.Kind)) 596 return true; 597 } 598 return false; 599 } 600 601 /// Do the check specified in \a Check to all component lists at a given level 602 /// and return true if any issue is found. 603 bool checkMappableExprComponentListsForDeclAtLevel( 604 const ValueDecl *VD, unsigned Level, 605 const llvm::function_ref< 606 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 607 OpenMPClauseKind)> 608 Check) const { 609 if (isStackEmpty()) 610 return false; 611 612 auto StartI = Stack.back().first.begin(); 613 auto EndI = Stack.back().first.end(); 614 if (std::distance(StartI, EndI) <= (int)Level) 615 return false; 616 std::advance(StartI, Level); 617 618 auto MI = StartI->MappedExprComponents.find(VD); 619 if (MI != StartI->MappedExprComponents.end()) 620 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 621 MI->second.Components) 622 if (Check(L, MI->second.Kind)) 623 return true; 624 return false; 625 } 626 627 /// Create a new mappable expression component list associated with a given 628 /// declaration and initialize it with the provided list of components. 629 void addMappableExpressionComponents( 630 const ValueDecl *VD, 631 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 632 OpenMPClauseKind WhereFoundClauseKind) { 633 assert(!isStackEmpty() && 634 "Not expecting to retrieve components from a empty stack!"); 635 MappedExprComponentTy &MEC = 636 Stack.back().first.back().MappedExprComponents[VD]; 637 // Create new entry and append the new components there. 638 MEC.Components.resize(MEC.Components.size() + 1); 639 MEC.Components.back().append(Components.begin(), Components.end()); 640 MEC.Kind = WhereFoundClauseKind; 641 } 642 643 unsigned getNestingLevel() const { 644 assert(!isStackEmpty()); 645 return Stack.back().first.size() - 1; 646 } 647 void addDoacrossDependClause(OMPDependClause *C, 648 const OperatorOffsetTy &OpsOffs) { 649 assert(!isStackEmpty() && Stack.back().first.size() > 1); 650 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 651 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 652 StackElem.DoacrossDepends.try_emplace(C, OpsOffs); 653 } 654 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 655 getDoacrossDependClauses() const { 656 assert(!isStackEmpty()); 657 const SharingMapTy &StackElem = Stack.back().first.back(); 658 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 659 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 660 return llvm::make_range(Ref.begin(), Ref.end()); 661 } 662 return llvm::make_range(StackElem.DoacrossDepends.end(), 663 StackElem.DoacrossDepends.end()); 664 } 665 666 // Store types of classes which have been explicitly mapped 667 void addMappedClassesQualTypes(QualType QT) { 668 SharingMapTy &StackElem = Stack.back().first.back(); 669 StackElem.MappedClassesQualTypes.insert(QT); 670 } 671 672 // Return set of mapped classes types 673 bool isClassPreviouslyMapped(QualType QT) const { 674 const SharingMapTy &StackElem = Stack.back().first.back(); 675 return StackElem.MappedClassesQualTypes.count(QT) != 0; 676 } 677 678 }; 679 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 680 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 681 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 682 } 683 684 } // namespace 685 686 static const Expr *getExprAsWritten(const Expr *E) { 687 if (const auto *FE = dyn_cast<FullExpr>(E)) 688 E = FE->getSubExpr(); 689 690 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 691 E = MTE->GetTemporaryExpr(); 692 693 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 694 E = Binder->getSubExpr(); 695 696 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 697 E = ICE->getSubExprAsWritten(); 698 return E->IgnoreParens(); 699 } 700 701 static Expr *getExprAsWritten(Expr *E) { 702 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 703 } 704 705 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 706 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 707 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 708 D = ME->getMemberDecl(); 709 const auto *VD = dyn_cast<VarDecl>(D); 710 const auto *FD = dyn_cast<FieldDecl>(D); 711 if (VD != nullptr) { 712 VD = VD->getCanonicalDecl(); 713 D = VD; 714 } else { 715 assert(FD); 716 FD = FD->getCanonicalDecl(); 717 D = FD; 718 } 719 return D; 720 } 721 722 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 723 return const_cast<ValueDecl *>( 724 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 725 } 726 727 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 728 ValueDecl *D) const { 729 D = getCanonicalDecl(D); 730 auto *VD = dyn_cast<VarDecl>(D); 731 const auto *FD = dyn_cast<FieldDecl>(D); 732 DSAVarData DVar; 733 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 734 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 735 // in a region but not in construct] 736 // File-scope or namespace-scope variables referenced in called routines 737 // in the region are shared unless they appear in a threadprivate 738 // directive. 739 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 740 DVar.CKind = OMPC_shared; 741 742 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 743 // in a region but not in construct] 744 // Variables with static storage duration that are declared in called 745 // routines in the region are shared. 746 if (VD && VD->hasGlobalStorage()) 747 DVar.CKind = OMPC_shared; 748 749 // Non-static data members are shared by default. 750 if (FD) 751 DVar.CKind = OMPC_shared; 752 753 return DVar; 754 } 755 756 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 757 // in a Construct, C/C++, predetermined, p.1] 758 // Variables with automatic storage duration that are declared in a scope 759 // inside the construct are private. 760 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 761 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 762 DVar.CKind = OMPC_private; 763 return DVar; 764 } 765 766 DVar.DKind = Iter->Directive; 767 // Explicitly specified attributes and local variables with predetermined 768 // attributes. 769 if (Iter->SharingMap.count(D)) { 770 const DSAInfo &Data = Iter->SharingMap.lookup(D); 771 DVar.RefExpr = Data.RefExpr.getPointer(); 772 DVar.PrivateCopy = Data.PrivateCopy; 773 DVar.CKind = Data.Attributes; 774 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 775 return DVar; 776 } 777 778 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 779 // in a Construct, C/C++, implicitly determined, p.1] 780 // In a parallel or task construct, the data-sharing attributes of these 781 // variables are determined by the default clause, if present. 782 switch (Iter->DefaultAttr) { 783 case DSA_shared: 784 DVar.CKind = OMPC_shared; 785 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 786 return DVar; 787 case DSA_none: 788 return DVar; 789 case DSA_unspecified: 790 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 791 // in a Construct, implicitly determined, p.2] 792 // In a parallel construct, if no default clause is present, these 793 // variables are shared. 794 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 795 if (isOpenMPParallelDirective(DVar.DKind) || 796 isOpenMPTeamsDirective(DVar.DKind)) { 797 DVar.CKind = OMPC_shared; 798 return DVar; 799 } 800 801 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 802 // in a Construct, implicitly determined, p.4] 803 // In a task construct, if no default clause is present, a variable that in 804 // the enclosing context is determined to be shared by all implicit tasks 805 // bound to the current team is shared. 806 if (isOpenMPTaskingDirective(DVar.DKind)) { 807 DSAVarData DVarTemp; 808 iterator I = Iter, E = Stack.back().first.rend(); 809 do { 810 ++I; 811 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 812 // Referenced in a Construct, implicitly determined, p.6] 813 // In a task construct, if no default clause is present, a variable 814 // whose data-sharing attribute is not determined by the rules above is 815 // firstprivate. 816 DVarTemp = getDSA(I, D); 817 if (DVarTemp.CKind != OMPC_shared) { 818 DVar.RefExpr = nullptr; 819 DVar.CKind = OMPC_firstprivate; 820 return DVar; 821 } 822 } while (I != E && !isParallelOrTaskRegion(I->Directive)); 823 DVar.CKind = 824 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 825 return DVar; 826 } 827 } 828 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 829 // in a Construct, implicitly determined, p.3] 830 // For constructs other than task, if no default clause is present, these 831 // variables inherit their data-sharing attributes from the enclosing 832 // context. 833 return getDSA(++Iter, D); 834 } 835 836 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 837 const Expr *NewDE) { 838 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 839 D = getCanonicalDecl(D); 840 SharingMapTy &StackElem = Stack.back().first.back(); 841 auto It = StackElem.AlignedMap.find(D); 842 if (It == StackElem.AlignedMap.end()) { 843 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 844 StackElem.AlignedMap[D] = NewDE; 845 return nullptr; 846 } 847 assert(It->second && "Unexpected nullptr expr in the aligned map"); 848 return It->second; 849 } 850 851 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 852 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 853 D = getCanonicalDecl(D); 854 SharingMapTy &StackElem = Stack.back().first.back(); 855 StackElem.LCVMap.try_emplace( 856 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 857 } 858 859 const DSAStackTy::LCDeclInfo 860 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 861 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 862 D = getCanonicalDecl(D); 863 const SharingMapTy &StackElem = Stack.back().first.back(); 864 auto It = StackElem.LCVMap.find(D); 865 if (It != StackElem.LCVMap.end()) 866 return It->second; 867 return {0, nullptr}; 868 } 869 870 const DSAStackTy::LCDeclInfo 871 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 872 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 873 "Data-sharing attributes stack is empty"); 874 D = getCanonicalDecl(D); 875 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 876 auto It = StackElem.LCVMap.find(D); 877 if (It != StackElem.LCVMap.end()) 878 return It->second; 879 return {0, nullptr}; 880 } 881 882 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 883 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 884 "Data-sharing attributes stack is empty"); 885 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 886 if (StackElem.LCVMap.size() < I) 887 return nullptr; 888 for (const auto &Pair : StackElem.LCVMap) 889 if (Pair.second.first == I) 890 return Pair.first; 891 return nullptr; 892 } 893 894 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 895 DeclRefExpr *PrivateCopy) { 896 D = getCanonicalDecl(D); 897 if (A == OMPC_threadprivate) { 898 DSAInfo &Data = Threadprivates[D]; 899 Data.Attributes = A; 900 Data.RefExpr.setPointer(E); 901 Data.PrivateCopy = nullptr; 902 } else { 903 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 904 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 905 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 906 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 907 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 908 (isLoopControlVariable(D).first && A == OMPC_private)); 909 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 910 Data.RefExpr.setInt(/*IntVal=*/true); 911 return; 912 } 913 const bool IsLastprivate = 914 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 915 Data.Attributes = A; 916 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 917 Data.PrivateCopy = PrivateCopy; 918 if (PrivateCopy) { 919 DSAInfo &Data = 920 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 921 Data.Attributes = A; 922 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 923 Data.PrivateCopy = nullptr; 924 } 925 } 926 } 927 928 /// Build a variable declaration for OpenMP loop iteration variable. 929 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 930 StringRef Name, const AttrVec *Attrs = nullptr, 931 DeclRefExpr *OrigRef = nullptr) { 932 DeclContext *DC = SemaRef.CurContext; 933 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 934 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 935 auto *Decl = 936 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 937 if (Attrs) { 938 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 939 I != E; ++I) 940 Decl->addAttr(*I); 941 } 942 Decl->setImplicit(); 943 if (OrigRef) { 944 Decl->addAttr( 945 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 946 } 947 return Decl; 948 } 949 950 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 951 SourceLocation Loc, 952 bool RefersToCapture = false) { 953 D->setReferenced(); 954 D->markUsed(S.Context); 955 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 956 SourceLocation(), D, RefersToCapture, Loc, Ty, 957 VK_LValue); 958 } 959 960 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 961 BinaryOperatorKind BOK) { 962 D = getCanonicalDecl(D); 963 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 964 assert( 965 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 966 "Additional reduction info may be specified only for reduction items."); 967 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 968 assert(ReductionData.ReductionRange.isInvalid() && 969 Stack.back().first.back().Directive == OMPD_taskgroup && 970 "Additional reduction info may be specified only once for reduction " 971 "items."); 972 ReductionData.set(BOK, SR); 973 Expr *&TaskgroupReductionRef = 974 Stack.back().first.back().TaskgroupReductionRef; 975 if (!TaskgroupReductionRef) { 976 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 977 SemaRef.Context.VoidPtrTy, ".task_red."); 978 TaskgroupReductionRef = 979 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 980 } 981 } 982 983 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 984 const Expr *ReductionRef) { 985 D = getCanonicalDecl(D); 986 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 987 assert( 988 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 989 "Additional reduction info may be specified only for reduction items."); 990 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 991 assert(ReductionData.ReductionRange.isInvalid() && 992 Stack.back().first.back().Directive == OMPD_taskgroup && 993 "Additional reduction info may be specified only once for reduction " 994 "items."); 995 ReductionData.set(ReductionRef, SR); 996 Expr *&TaskgroupReductionRef = 997 Stack.back().first.back().TaskgroupReductionRef; 998 if (!TaskgroupReductionRef) { 999 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1000 SemaRef.Context.VoidPtrTy, ".task_red."); 1001 TaskgroupReductionRef = 1002 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1003 } 1004 } 1005 1006 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1007 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1008 Expr *&TaskgroupDescriptor) const { 1009 D = getCanonicalDecl(D); 1010 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1011 if (Stack.back().first.empty()) 1012 return DSAVarData(); 1013 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1014 E = Stack.back().first.rend(); 1015 I != E; std::advance(I, 1)) { 1016 const DSAInfo &Data = I->SharingMap.lookup(D); 1017 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1018 continue; 1019 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1020 if (!ReductionData.ReductionOp || 1021 ReductionData.ReductionOp.is<const Expr *>()) 1022 return DSAVarData(); 1023 SR = ReductionData.ReductionRange; 1024 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1025 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1026 "expression for the descriptor is not " 1027 "set."); 1028 TaskgroupDescriptor = I->TaskgroupReductionRef; 1029 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1030 Data.PrivateCopy, I->DefaultAttrLoc); 1031 } 1032 return DSAVarData(); 1033 } 1034 1035 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1036 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1037 Expr *&TaskgroupDescriptor) const { 1038 D = getCanonicalDecl(D); 1039 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1040 if (Stack.back().first.empty()) 1041 return DSAVarData(); 1042 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1043 E = Stack.back().first.rend(); 1044 I != E; std::advance(I, 1)) { 1045 const DSAInfo &Data = I->SharingMap.lookup(D); 1046 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1047 continue; 1048 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1049 if (!ReductionData.ReductionOp || 1050 !ReductionData.ReductionOp.is<const Expr *>()) 1051 return DSAVarData(); 1052 SR = ReductionData.ReductionRange; 1053 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1054 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1055 "expression for the descriptor is not " 1056 "set."); 1057 TaskgroupDescriptor = I->TaskgroupReductionRef; 1058 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1059 Data.PrivateCopy, I->DefaultAttrLoc); 1060 } 1061 return DSAVarData(); 1062 } 1063 1064 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 1065 D = D->getCanonicalDecl(); 1066 if (!isStackEmpty()) { 1067 iterator I = Iter, E = Stack.back().first.rend(); 1068 Scope *TopScope = nullptr; 1069 while (I != E && !isParallelOrTaskRegion(I->Directive) && 1070 !isOpenMPTargetExecutionDirective(I->Directive)) 1071 ++I; 1072 if (I == E) 1073 return false; 1074 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1075 Scope *CurScope = getCurScope(); 1076 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 1077 CurScope = CurScope->getParent(); 1078 return CurScope != TopScope; 1079 } 1080 return false; 1081 } 1082 1083 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1084 bool AcceptIfMutable = true, 1085 bool *IsClassType = nullptr) { 1086 ASTContext &Context = SemaRef.getASTContext(); 1087 Type = Type.getNonReferenceType().getCanonicalType(); 1088 bool IsConstant = Type.isConstant(Context); 1089 Type = Context.getBaseElementType(Type); 1090 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1091 ? Type->getAsCXXRecordDecl() 1092 : nullptr; 1093 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1094 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1095 RD = CTD->getTemplatedDecl(); 1096 if (IsClassType) 1097 *IsClassType = RD; 1098 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1099 RD->hasDefinition() && RD->hasMutableFields()); 1100 } 1101 1102 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1103 QualType Type, OpenMPClauseKind CKind, 1104 SourceLocation ELoc, 1105 bool AcceptIfMutable = true, 1106 bool ListItemNotVar = false) { 1107 ASTContext &Context = SemaRef.getASTContext(); 1108 bool IsClassType; 1109 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1110 unsigned Diag = ListItemNotVar 1111 ? diag::err_omp_const_list_item 1112 : IsClassType ? diag::err_omp_const_not_mutable_variable 1113 : diag::err_omp_const_variable; 1114 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1115 if (!ListItemNotVar && D) { 1116 const VarDecl *VD = dyn_cast<VarDecl>(D); 1117 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1118 VarDecl::DeclarationOnly; 1119 SemaRef.Diag(D->getLocation(), 1120 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1121 << D; 1122 } 1123 return true; 1124 } 1125 return false; 1126 } 1127 1128 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1129 bool FromParent) { 1130 D = getCanonicalDecl(D); 1131 DSAVarData DVar; 1132 1133 auto *VD = dyn_cast<VarDecl>(D); 1134 auto TI = Threadprivates.find(D); 1135 if (TI != Threadprivates.end()) { 1136 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1137 DVar.CKind = OMPC_threadprivate; 1138 return DVar; 1139 } 1140 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1141 DVar.RefExpr = buildDeclRefExpr( 1142 SemaRef, VD, D->getType().getNonReferenceType(), 1143 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1144 DVar.CKind = OMPC_threadprivate; 1145 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1146 return DVar; 1147 } 1148 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1149 // in a Construct, C/C++, predetermined, p.1] 1150 // Variables appearing in threadprivate directives are threadprivate. 1151 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1152 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1153 SemaRef.getLangOpts().OpenMPUseTLS && 1154 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1155 (VD && VD->getStorageClass() == SC_Register && 1156 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1157 DVar.RefExpr = buildDeclRefExpr( 1158 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1159 DVar.CKind = OMPC_threadprivate; 1160 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1161 return DVar; 1162 } 1163 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1164 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1165 !isLoopControlVariable(D).first) { 1166 iterator IterTarget = 1167 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1168 [](const SharingMapTy &Data) { 1169 return isOpenMPTargetExecutionDirective(Data.Directive); 1170 }); 1171 if (IterTarget != Stack.back().first.rend()) { 1172 iterator ParentIterTarget = std::next(IterTarget, 1); 1173 for (iterator Iter = Stack.back().first.rbegin(); 1174 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1175 if (isOpenMPLocal(VD, Iter)) { 1176 DVar.RefExpr = 1177 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1178 D->getLocation()); 1179 DVar.CKind = OMPC_threadprivate; 1180 return DVar; 1181 } 1182 } 1183 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1184 auto DSAIter = IterTarget->SharingMap.find(D); 1185 if (DSAIter != IterTarget->SharingMap.end() && 1186 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1187 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1188 DVar.CKind = OMPC_threadprivate; 1189 return DVar; 1190 } 1191 iterator End = Stack.back().first.rend(); 1192 if (!SemaRef.isOpenMPCapturedByRef( 1193 D, std::distance(ParentIterTarget, End))) { 1194 DVar.RefExpr = 1195 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1196 IterTarget->ConstructLoc); 1197 DVar.CKind = OMPC_threadprivate; 1198 return DVar; 1199 } 1200 } 1201 } 1202 } 1203 1204 if (isStackEmpty()) 1205 // Not in OpenMP execution region and top scope was already checked. 1206 return DVar; 1207 1208 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1209 // in a Construct, C/C++, predetermined, p.4] 1210 // Static data members are shared. 1211 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1212 // in a Construct, C/C++, predetermined, p.7] 1213 // Variables with static storage duration that are declared in a scope 1214 // inside the construct are shared. 1215 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1216 if (VD && VD->isStaticDataMember()) { 1217 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1218 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1219 return DVar; 1220 1221 DVar.CKind = OMPC_shared; 1222 return DVar; 1223 } 1224 1225 // The predetermined shared attribute for const-qualified types having no 1226 // mutable members was removed after OpenMP 3.1. 1227 if (SemaRef.LangOpts.OpenMP <= 31) { 1228 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1229 // in a Construct, C/C++, predetermined, p.6] 1230 // Variables with const qualified type having no mutable member are 1231 // shared. 1232 if (isConstNotMutableType(SemaRef, D->getType())) { 1233 // Variables with const-qualified type having no mutable member may be 1234 // listed in a firstprivate clause, even if they are static data members. 1235 DSAVarData DVarTemp = hasInnermostDSA( 1236 D, 1237 [](OpenMPClauseKind C) { 1238 return C == OMPC_firstprivate || C == OMPC_shared; 1239 }, 1240 MatchesAlways, FromParent); 1241 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1242 return DVarTemp; 1243 1244 DVar.CKind = OMPC_shared; 1245 return DVar; 1246 } 1247 } 1248 1249 // Explicitly specified attributes and local variables with predetermined 1250 // attributes. 1251 iterator I = Stack.back().first.rbegin(); 1252 iterator EndI = Stack.back().first.rend(); 1253 if (FromParent && I != EndI) 1254 std::advance(I, 1); 1255 auto It = I->SharingMap.find(D); 1256 if (It != I->SharingMap.end()) { 1257 const DSAInfo &Data = It->getSecond(); 1258 DVar.RefExpr = Data.RefExpr.getPointer(); 1259 DVar.PrivateCopy = Data.PrivateCopy; 1260 DVar.CKind = Data.Attributes; 1261 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1262 DVar.DKind = I->Directive; 1263 } 1264 1265 return DVar; 1266 } 1267 1268 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1269 bool FromParent) const { 1270 if (isStackEmpty()) { 1271 iterator I; 1272 return getDSA(I, D); 1273 } 1274 D = getCanonicalDecl(D); 1275 iterator StartI = Stack.back().first.rbegin(); 1276 iterator EndI = Stack.back().first.rend(); 1277 if (FromParent && StartI != EndI) 1278 std::advance(StartI, 1); 1279 return getDSA(StartI, D); 1280 } 1281 1282 const DSAStackTy::DSAVarData 1283 DSAStackTy::hasDSA(ValueDecl *D, 1284 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1285 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1286 bool FromParent) const { 1287 if (isStackEmpty()) 1288 return {}; 1289 D = getCanonicalDecl(D); 1290 iterator I = Stack.back().first.rbegin(); 1291 iterator EndI = Stack.back().first.rend(); 1292 if (FromParent && I != EndI) 1293 std::advance(I, 1); 1294 for (; I != EndI; std::advance(I, 1)) { 1295 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 1296 continue; 1297 iterator NewI = I; 1298 DSAVarData DVar = getDSA(NewI, D); 1299 if (I == NewI && CPred(DVar.CKind)) 1300 return DVar; 1301 } 1302 return {}; 1303 } 1304 1305 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1306 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1307 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1308 bool FromParent) const { 1309 if (isStackEmpty()) 1310 return {}; 1311 D = getCanonicalDecl(D); 1312 iterator StartI = Stack.back().first.rbegin(); 1313 iterator EndI = Stack.back().first.rend(); 1314 if (FromParent && StartI != EndI) 1315 std::advance(StartI, 1); 1316 if (StartI == EndI || !DPred(StartI->Directive)) 1317 return {}; 1318 iterator NewI = StartI; 1319 DSAVarData DVar = getDSA(NewI, D); 1320 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1321 } 1322 1323 bool DSAStackTy::hasExplicitDSA( 1324 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1325 unsigned Level, bool NotLastprivate) const { 1326 if (isStackEmpty()) 1327 return false; 1328 D = getCanonicalDecl(D); 1329 auto StartI = Stack.back().first.begin(); 1330 auto EndI = Stack.back().first.end(); 1331 if (std::distance(StartI, EndI) <= (int)Level) 1332 return false; 1333 std::advance(StartI, Level); 1334 auto I = StartI->SharingMap.find(D); 1335 if ((I != StartI->SharingMap.end()) && 1336 I->getSecond().RefExpr.getPointer() && 1337 CPred(I->getSecond().Attributes) && 1338 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1339 return true; 1340 // Check predetermined rules for the loop control variables. 1341 auto LI = StartI->LCVMap.find(D); 1342 if (LI != StartI->LCVMap.end()) 1343 return CPred(OMPC_private); 1344 return false; 1345 } 1346 1347 bool DSAStackTy::hasExplicitDirective( 1348 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1349 unsigned Level) const { 1350 if (isStackEmpty()) 1351 return false; 1352 auto StartI = Stack.back().first.begin(); 1353 auto EndI = Stack.back().first.end(); 1354 if (std::distance(StartI, EndI) <= (int)Level) 1355 return false; 1356 std::advance(StartI, Level); 1357 return DPred(StartI->Directive); 1358 } 1359 1360 bool DSAStackTy::hasDirective( 1361 const llvm::function_ref<bool(OpenMPDirectiveKind, 1362 const DeclarationNameInfo &, SourceLocation)> 1363 DPred, 1364 bool FromParent) const { 1365 // We look only in the enclosing region. 1366 if (isStackEmpty()) 1367 return false; 1368 auto StartI = std::next(Stack.back().first.rbegin()); 1369 auto EndI = Stack.back().first.rend(); 1370 if (FromParent && StartI != EndI) 1371 StartI = std::next(StartI); 1372 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1373 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1374 return true; 1375 } 1376 return false; 1377 } 1378 1379 void Sema::InitDataSharingAttributesStack() { 1380 VarDataSharingAttributesStack = new DSAStackTy(*this); 1381 } 1382 1383 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1384 1385 void Sema::pushOpenMPFunctionRegion() { 1386 DSAStack->pushFunction(); 1387 } 1388 1389 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1390 DSAStack->popFunction(OldFSI); 1391 } 1392 1393 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1394 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1395 1396 ASTContext &Ctx = getASTContext(); 1397 bool IsByRef = true; 1398 1399 // Find the directive that is associated with the provided scope. 1400 D = cast<ValueDecl>(D->getCanonicalDecl()); 1401 QualType Ty = D->getType(); 1402 1403 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1404 // This table summarizes how a given variable should be passed to the device 1405 // given its type and the clauses where it appears. This table is based on 1406 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1407 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1408 // 1409 // ========================================================================= 1410 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1411 // | |(tofrom:scalar)| | pvt | | | | 1412 // ========================================================================= 1413 // | scl | | | | - | | bycopy| 1414 // | scl | | - | x | - | - | bycopy| 1415 // | scl | | x | - | - | - | null | 1416 // | scl | x | | | - | | byref | 1417 // | scl | x | - | x | - | - | bycopy| 1418 // | scl | x | x | - | - | - | null | 1419 // | scl | | - | - | - | x | byref | 1420 // | scl | x | - | - | - | x | byref | 1421 // 1422 // | agg | n.a. | | | - | | byref | 1423 // | agg | n.a. | - | x | - | - | byref | 1424 // | agg | n.a. | x | - | - | - | null | 1425 // | agg | n.a. | - | - | - | x | byref | 1426 // | agg | n.a. | - | - | - | x[] | byref | 1427 // 1428 // | ptr | n.a. | | | - | | bycopy| 1429 // | ptr | n.a. | - | x | - | - | bycopy| 1430 // | ptr | n.a. | x | - | - | - | null | 1431 // | ptr | n.a. | - | - | - | x | byref | 1432 // | ptr | n.a. | - | - | - | x[] | bycopy| 1433 // | ptr | n.a. | - | - | x | | bycopy| 1434 // | ptr | n.a. | - | - | x | x | bycopy| 1435 // | ptr | n.a. | - | - | x | x[] | bycopy| 1436 // ========================================================================= 1437 // Legend: 1438 // scl - scalar 1439 // ptr - pointer 1440 // agg - aggregate 1441 // x - applies 1442 // - - invalid in this combination 1443 // [] - mapped with an array section 1444 // byref - should be mapped by reference 1445 // byval - should be mapped by value 1446 // null - initialize a local variable to null on the device 1447 // 1448 // Observations: 1449 // - All scalar declarations that show up in a map clause have to be passed 1450 // by reference, because they may have been mapped in the enclosing data 1451 // environment. 1452 // - If the scalar value does not fit the size of uintptr, it has to be 1453 // passed by reference, regardless the result in the table above. 1454 // - For pointers mapped by value that have either an implicit map or an 1455 // array section, the runtime library may pass the NULL value to the 1456 // device instead of the value passed to it by the compiler. 1457 1458 if (Ty->isReferenceType()) 1459 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1460 1461 // Locate map clauses and see if the variable being captured is referred to 1462 // in any of those clauses. Here we only care about variables, not fields, 1463 // because fields are part of aggregates. 1464 bool IsVariableUsedInMapClause = false; 1465 bool IsVariableAssociatedWithSection = false; 1466 1467 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1468 D, Level, 1469 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1470 OMPClauseMappableExprCommon::MappableExprComponentListRef 1471 MapExprComponents, 1472 OpenMPClauseKind WhereFoundClauseKind) { 1473 // Only the map clause information influences how a variable is 1474 // captured. E.g. is_device_ptr does not require changing the default 1475 // behavior. 1476 if (WhereFoundClauseKind != OMPC_map) 1477 return false; 1478 1479 auto EI = MapExprComponents.rbegin(); 1480 auto EE = MapExprComponents.rend(); 1481 1482 assert(EI != EE && "Invalid map expression!"); 1483 1484 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1485 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1486 1487 ++EI; 1488 if (EI == EE) 1489 return false; 1490 1491 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1492 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1493 isa<MemberExpr>(EI->getAssociatedExpression())) { 1494 IsVariableAssociatedWithSection = true; 1495 // There is nothing more we need to know about this variable. 1496 return true; 1497 } 1498 1499 // Keep looking for more map info. 1500 return false; 1501 }); 1502 1503 if (IsVariableUsedInMapClause) { 1504 // If variable is identified in a map clause it is always captured by 1505 // reference except if it is a pointer that is dereferenced somehow. 1506 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1507 } else { 1508 // By default, all the data that has a scalar type is mapped by copy 1509 // (except for reduction variables). 1510 IsByRef = 1511 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1512 !Ty->isAnyPointerType()) || 1513 !Ty->isScalarType() || 1514 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1515 DSAStack->hasExplicitDSA( 1516 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1517 } 1518 } 1519 1520 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1521 IsByRef = 1522 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1523 !Ty->isAnyPointerType()) || 1524 !DSAStack->hasExplicitDSA( 1525 D, 1526 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1527 Level, /*NotLastprivate=*/true)) && 1528 // If the variable is artificial and must be captured by value - try to 1529 // capture by value. 1530 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1531 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1532 } 1533 1534 // When passing data by copy, we need to make sure it fits the uintptr size 1535 // and alignment, because the runtime library only deals with uintptr types. 1536 // If it does not fit the uintptr size, we need to pass the data by reference 1537 // instead. 1538 if (!IsByRef && 1539 (Ctx.getTypeSizeInChars(Ty) > 1540 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1541 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1542 IsByRef = true; 1543 } 1544 1545 return IsByRef; 1546 } 1547 1548 unsigned Sema::getOpenMPNestingLevel() const { 1549 assert(getLangOpts().OpenMP); 1550 return DSAStack->getNestingLevel(); 1551 } 1552 1553 bool Sema::isInOpenMPTargetExecutionDirective() const { 1554 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1555 !DSAStack->isClauseParsingMode()) || 1556 DSAStack->hasDirective( 1557 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1558 SourceLocation) -> bool { 1559 return isOpenMPTargetExecutionDirective(K); 1560 }, 1561 false); 1562 } 1563 1564 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { 1565 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1566 D = getCanonicalDecl(D); 1567 1568 // If we are attempting to capture a global variable in a directive with 1569 // 'target' we return true so that this global is also mapped to the device. 1570 // 1571 auto *VD = dyn_cast<VarDecl>(D); 1572 if (VD && !VD->hasLocalStorage()) { 1573 if (isInOpenMPDeclareTargetContext() && 1574 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1575 // Try to mark variable as declare target if it is used in capturing 1576 // regions. 1577 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1578 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1579 return nullptr; 1580 } else if (isInOpenMPTargetExecutionDirective()) { 1581 // If the declaration is enclosed in a 'declare target' directive, 1582 // then it should not be captured. 1583 // 1584 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1585 return nullptr; 1586 return VD; 1587 } 1588 } 1589 // Capture variables captured by reference in lambdas for target-based 1590 // directives. 1591 if (VD && !DSAStack->isClauseParsingMode()) { 1592 if (const auto *RD = VD->getType() 1593 .getCanonicalType() 1594 .getNonReferenceType() 1595 ->getAsCXXRecordDecl()) { 1596 bool SavedForceCaptureByReferenceInTargetExecutable = 1597 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1598 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1599 if (RD->isLambda()) { 1600 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1601 FieldDecl *ThisCapture; 1602 RD->getCaptureFields(Captures, ThisCapture); 1603 for (const LambdaCapture &LC : RD->captures()) { 1604 if (LC.getCaptureKind() == LCK_ByRef) { 1605 VarDecl *VD = LC.getCapturedVar(); 1606 DeclContext *VDC = VD->getDeclContext(); 1607 if (!VDC->Encloses(CurContext)) 1608 continue; 1609 DSAStackTy::DSAVarData DVarPrivate = 1610 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1611 // Do not capture already captured variables. 1612 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1613 DVarPrivate.CKind == OMPC_unknown && 1614 !DSAStack->checkMappableExprComponentListsForDecl( 1615 D, /*CurrentRegionOnly=*/true, 1616 [](OMPClauseMappableExprCommon:: 1617 MappableExprComponentListRef, 1618 OpenMPClauseKind) { return true; })) 1619 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1620 } else if (LC.getCaptureKind() == LCK_This) { 1621 QualType ThisTy = getCurrentThisType(); 1622 if (!ThisTy.isNull() && 1623 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1624 CheckCXXThisCapture(LC.getLocation()); 1625 } 1626 } 1627 } 1628 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1629 SavedForceCaptureByReferenceInTargetExecutable); 1630 } 1631 } 1632 1633 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1634 (!DSAStack->isClauseParsingMode() || 1635 DSAStack->getParentDirective() != OMPD_unknown)) { 1636 auto &&Info = DSAStack->isLoopControlVariable(D); 1637 if (Info.first || 1638 (VD && VD->hasLocalStorage() && 1639 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1640 (VD && DSAStack->isForceVarCapturing())) 1641 return VD ? VD : Info.second; 1642 DSAStackTy::DSAVarData DVarPrivate = 1643 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1644 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1645 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1646 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1647 [](OpenMPDirectiveKind) { return true; }, 1648 DSAStack->isClauseParsingMode()); 1649 if (DVarPrivate.CKind != OMPC_unknown) 1650 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1651 } 1652 return nullptr; 1653 } 1654 1655 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1656 unsigned Level) const { 1657 SmallVector<OpenMPDirectiveKind, 4> Regions; 1658 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1659 FunctionScopesIndex -= Regions.size(); 1660 } 1661 1662 void Sema::startOpenMPLoop() { 1663 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1664 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1665 DSAStack->loopInit(); 1666 } 1667 1668 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1669 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1670 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1671 if (DSAStack->getAssociatedLoops() > 0 && 1672 !DSAStack->isLoopStarted()) { 1673 DSAStack->resetPossibleLoopCounter(D); 1674 DSAStack->loopStart(); 1675 return true; 1676 } 1677 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1678 DSAStack->isLoopControlVariable(D).first) && 1679 !DSAStack->hasExplicitDSA( 1680 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1681 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1682 return true; 1683 } 1684 return DSAStack->hasExplicitDSA( 1685 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1686 (DSAStack->isClauseParsingMode() && 1687 DSAStack->getClauseParsingMode() == OMPC_private) || 1688 // Consider taskgroup reduction descriptor variable a private to avoid 1689 // possible capture in the region. 1690 (DSAStack->hasExplicitDirective( 1691 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1692 Level) && 1693 DSAStack->isTaskgroupReductionRef(D, Level)); 1694 } 1695 1696 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1697 unsigned Level) { 1698 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1699 D = getCanonicalDecl(D); 1700 OpenMPClauseKind OMPC = OMPC_unknown; 1701 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1702 const unsigned NewLevel = I - 1; 1703 if (DSAStack->hasExplicitDSA(D, 1704 [&OMPC](const OpenMPClauseKind K) { 1705 if (isOpenMPPrivate(K)) { 1706 OMPC = K; 1707 return true; 1708 } 1709 return false; 1710 }, 1711 NewLevel)) 1712 break; 1713 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1714 D, NewLevel, 1715 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1716 OpenMPClauseKind) { return true; })) { 1717 OMPC = OMPC_map; 1718 break; 1719 } 1720 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1721 NewLevel)) { 1722 OMPC = OMPC_map; 1723 if (D->getType()->isScalarType() && 1724 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1725 DefaultMapAttributes::DMA_tofrom_scalar) 1726 OMPC = OMPC_firstprivate; 1727 break; 1728 } 1729 } 1730 if (OMPC != OMPC_unknown) 1731 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1732 } 1733 1734 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1735 unsigned Level) const { 1736 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1737 // Return true if the current level is no longer enclosed in a target region. 1738 1739 const auto *VD = dyn_cast<VarDecl>(D); 1740 return VD && !VD->hasLocalStorage() && 1741 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1742 Level); 1743 } 1744 1745 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1746 1747 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1748 const DeclarationNameInfo &DirName, 1749 Scope *CurScope, SourceLocation Loc) { 1750 DSAStack->push(DKind, DirName, CurScope, Loc); 1751 PushExpressionEvaluationContext( 1752 ExpressionEvaluationContext::PotentiallyEvaluated); 1753 } 1754 1755 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1756 DSAStack->setClauseParsingMode(K); 1757 } 1758 1759 void Sema::EndOpenMPClause() { 1760 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1761 } 1762 1763 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1764 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1765 // A variable of class type (or array thereof) that appears in a lastprivate 1766 // clause requires an accessible, unambiguous default constructor for the 1767 // class type, unless the list item is also specified in a firstprivate 1768 // clause. 1769 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1770 for (OMPClause *C : D->clauses()) { 1771 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1772 SmallVector<Expr *, 8> PrivateCopies; 1773 for (Expr *DE : Clause->varlists()) { 1774 if (DE->isValueDependent() || DE->isTypeDependent()) { 1775 PrivateCopies.push_back(nullptr); 1776 continue; 1777 } 1778 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1779 auto *VD = cast<VarDecl>(DRE->getDecl()); 1780 QualType Type = VD->getType().getNonReferenceType(); 1781 const DSAStackTy::DSAVarData DVar = 1782 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1783 if (DVar.CKind == OMPC_lastprivate) { 1784 // Generate helper private variable and initialize it with the 1785 // default value. The address of the original variable is replaced 1786 // by the address of the new private variable in CodeGen. This new 1787 // variable is not added to IdResolver, so the code in the OpenMP 1788 // region uses original variable for proper diagnostics. 1789 VarDecl *VDPrivate = buildVarDecl( 1790 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1791 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1792 ActOnUninitializedDecl(VDPrivate); 1793 if (VDPrivate->isInvalidDecl()) 1794 continue; 1795 PrivateCopies.push_back(buildDeclRefExpr( 1796 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1797 } else { 1798 // The variable is also a firstprivate, so initialization sequence 1799 // for private copy is generated already. 1800 PrivateCopies.push_back(nullptr); 1801 } 1802 } 1803 // Set initializers to private copies if no errors were found. 1804 if (PrivateCopies.size() == Clause->varlist_size()) 1805 Clause->setPrivateCopies(PrivateCopies); 1806 } 1807 } 1808 } 1809 1810 DSAStack->pop(); 1811 DiscardCleanupsInEvaluationContext(); 1812 PopExpressionEvaluationContext(); 1813 } 1814 1815 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1816 Expr *NumIterations, Sema &SemaRef, 1817 Scope *S, DSAStackTy *Stack); 1818 1819 namespace { 1820 1821 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1822 private: 1823 Sema &SemaRef; 1824 1825 public: 1826 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1827 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1828 NamedDecl *ND = Candidate.getCorrectionDecl(); 1829 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1830 return VD->hasGlobalStorage() && 1831 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1832 SemaRef.getCurScope()); 1833 } 1834 return false; 1835 } 1836 }; 1837 1838 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 1839 private: 1840 Sema &SemaRef; 1841 1842 public: 1843 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1844 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1845 NamedDecl *ND = Candidate.getCorrectionDecl(); 1846 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) { 1847 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1848 SemaRef.getCurScope()); 1849 } 1850 return false; 1851 } 1852 }; 1853 1854 } // namespace 1855 1856 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1857 CXXScopeSpec &ScopeSpec, 1858 const DeclarationNameInfo &Id) { 1859 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1860 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1861 1862 if (Lookup.isAmbiguous()) 1863 return ExprError(); 1864 1865 VarDecl *VD; 1866 if (!Lookup.isSingleResult()) { 1867 if (TypoCorrection Corrected = CorrectTypo( 1868 Id, LookupOrdinaryName, CurScope, nullptr, 1869 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1870 diagnoseTypo(Corrected, 1871 PDiag(Lookup.empty() 1872 ? diag::err_undeclared_var_use_suggest 1873 : diag::err_omp_expected_var_arg_suggest) 1874 << Id.getName()); 1875 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1876 } else { 1877 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1878 : diag::err_omp_expected_var_arg) 1879 << Id.getName(); 1880 return ExprError(); 1881 } 1882 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1883 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1884 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1885 return ExprError(); 1886 } 1887 Lookup.suppressDiagnostics(); 1888 1889 // OpenMP [2.9.2, Syntax, C/C++] 1890 // Variables must be file-scope, namespace-scope, or static block-scope. 1891 if (!VD->hasGlobalStorage()) { 1892 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1893 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1894 bool IsDecl = 1895 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1896 Diag(VD->getLocation(), 1897 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1898 << VD; 1899 return ExprError(); 1900 } 1901 1902 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1903 NamedDecl *ND = CanonicalVD; 1904 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1905 // A threadprivate directive for file-scope variables must appear outside 1906 // any definition or declaration. 1907 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1908 !getCurLexicalContext()->isTranslationUnit()) { 1909 Diag(Id.getLoc(), diag::err_omp_var_scope) 1910 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1911 bool IsDecl = 1912 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1913 Diag(VD->getLocation(), 1914 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1915 << VD; 1916 return ExprError(); 1917 } 1918 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1919 // A threadprivate directive for static class member variables must appear 1920 // in the class definition, in the same scope in which the member 1921 // variables are declared. 1922 if (CanonicalVD->isStaticDataMember() && 1923 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1924 Diag(Id.getLoc(), diag::err_omp_var_scope) 1925 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1926 bool IsDecl = 1927 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1928 Diag(VD->getLocation(), 1929 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1930 << VD; 1931 return ExprError(); 1932 } 1933 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1934 // A threadprivate directive for namespace-scope variables must appear 1935 // outside any definition or declaration other than the namespace 1936 // definition itself. 1937 if (CanonicalVD->getDeclContext()->isNamespace() && 1938 (!getCurLexicalContext()->isFileContext() || 1939 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1940 Diag(Id.getLoc(), diag::err_omp_var_scope) 1941 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1942 bool IsDecl = 1943 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1944 Diag(VD->getLocation(), 1945 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1946 << VD; 1947 return ExprError(); 1948 } 1949 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1950 // A threadprivate directive for static block-scope variables must appear 1951 // in the scope of the variable and not in a nested scope. 1952 if (CanonicalVD->isStaticLocal() && CurScope && 1953 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1954 Diag(Id.getLoc(), diag::err_omp_var_scope) 1955 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1956 bool IsDecl = 1957 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1958 Diag(VD->getLocation(), 1959 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1960 << VD; 1961 return ExprError(); 1962 } 1963 1964 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1965 // A threadprivate directive must lexically precede all references to any 1966 // of the variables in its list. 1967 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1968 Diag(Id.getLoc(), diag::err_omp_var_used) 1969 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1970 return ExprError(); 1971 } 1972 1973 QualType ExprType = VD->getType().getNonReferenceType(); 1974 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1975 SourceLocation(), VD, 1976 /*RefersToEnclosingVariableOrCapture=*/false, 1977 Id.getLoc(), ExprType, VK_LValue); 1978 } 1979 1980 Sema::DeclGroupPtrTy 1981 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1982 ArrayRef<Expr *> VarList) { 1983 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1984 CurContext->addDecl(D); 1985 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1986 } 1987 return nullptr; 1988 } 1989 1990 namespace { 1991 class LocalVarRefChecker final 1992 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1993 Sema &SemaRef; 1994 1995 public: 1996 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1997 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1998 if (VD->hasLocalStorage()) { 1999 SemaRef.Diag(E->getBeginLoc(), 2000 diag::err_omp_local_var_in_threadprivate_init) 2001 << E->getSourceRange(); 2002 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2003 << VD << VD->getSourceRange(); 2004 return true; 2005 } 2006 } 2007 return false; 2008 } 2009 bool VisitStmt(const Stmt *S) { 2010 for (const Stmt *Child : S->children()) { 2011 if (Child && Visit(Child)) 2012 return true; 2013 } 2014 return false; 2015 } 2016 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2017 }; 2018 } // namespace 2019 2020 OMPThreadPrivateDecl * 2021 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2022 SmallVector<Expr *, 8> Vars; 2023 for (Expr *RefExpr : VarList) { 2024 auto *DE = cast<DeclRefExpr>(RefExpr); 2025 auto *VD = cast<VarDecl>(DE->getDecl()); 2026 SourceLocation ILoc = DE->getExprLoc(); 2027 2028 // Mark variable as used. 2029 VD->setReferenced(); 2030 VD->markUsed(Context); 2031 2032 QualType QType = VD->getType(); 2033 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2034 // It will be analyzed later. 2035 Vars.push_back(DE); 2036 continue; 2037 } 2038 2039 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2040 // A threadprivate variable must not have an incomplete type. 2041 if (RequireCompleteType(ILoc, VD->getType(), 2042 diag::err_omp_threadprivate_incomplete_type)) { 2043 continue; 2044 } 2045 2046 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2047 // A threadprivate variable must not have a reference type. 2048 if (VD->getType()->isReferenceType()) { 2049 Diag(ILoc, diag::err_omp_ref_type_arg) 2050 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2051 bool IsDecl = 2052 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2053 Diag(VD->getLocation(), 2054 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2055 << VD; 2056 continue; 2057 } 2058 2059 // Check if this is a TLS variable. If TLS is not being supported, produce 2060 // the corresponding diagnostic. 2061 if ((VD->getTLSKind() != VarDecl::TLS_None && 2062 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2063 getLangOpts().OpenMPUseTLS && 2064 getASTContext().getTargetInfo().isTLSSupported())) || 2065 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2066 !VD->isLocalVarDecl())) { 2067 Diag(ILoc, diag::err_omp_var_thread_local) 2068 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2069 bool IsDecl = 2070 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2071 Diag(VD->getLocation(), 2072 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2073 << VD; 2074 continue; 2075 } 2076 2077 // Check if initial value of threadprivate variable reference variable with 2078 // local storage (it is not supported by runtime). 2079 if (const Expr *Init = VD->getAnyInitializer()) { 2080 LocalVarRefChecker Checker(*this); 2081 if (Checker.Visit(Init)) 2082 continue; 2083 } 2084 2085 Vars.push_back(RefExpr); 2086 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2087 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2088 Context, SourceRange(Loc, Loc))); 2089 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2090 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2091 } 2092 OMPThreadPrivateDecl *D = nullptr; 2093 if (!Vars.empty()) { 2094 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2095 Vars); 2096 D->setAccess(AS_public); 2097 } 2098 return D; 2099 } 2100 2101 Sema::DeclGroupPtrTy 2102 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2103 ArrayRef<OMPClause *> ClauseList) { 2104 OMPRequiresDecl *D = nullptr; 2105 if (!CurContext->isFileContext()) { 2106 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2107 } else { 2108 D = CheckOMPRequiresDecl(Loc, ClauseList); 2109 if (D) { 2110 CurContext->addDecl(D); 2111 DSAStack->addRequiresDecl(D); 2112 } 2113 } 2114 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2115 } 2116 2117 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2118 ArrayRef<OMPClause *> ClauseList) { 2119 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2120 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2121 ClauseList); 2122 return nullptr; 2123 } 2124 2125 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2126 const ValueDecl *D, 2127 const DSAStackTy::DSAVarData &DVar, 2128 bool IsLoopIterVar = false) { 2129 if (DVar.RefExpr) { 2130 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2131 << getOpenMPClauseName(DVar.CKind); 2132 return; 2133 } 2134 enum { 2135 PDSA_StaticMemberShared, 2136 PDSA_StaticLocalVarShared, 2137 PDSA_LoopIterVarPrivate, 2138 PDSA_LoopIterVarLinear, 2139 PDSA_LoopIterVarLastprivate, 2140 PDSA_ConstVarShared, 2141 PDSA_GlobalVarShared, 2142 PDSA_TaskVarFirstprivate, 2143 PDSA_LocalVarPrivate, 2144 PDSA_Implicit 2145 } Reason = PDSA_Implicit; 2146 bool ReportHint = false; 2147 auto ReportLoc = D->getLocation(); 2148 auto *VD = dyn_cast<VarDecl>(D); 2149 if (IsLoopIterVar) { 2150 if (DVar.CKind == OMPC_private) 2151 Reason = PDSA_LoopIterVarPrivate; 2152 else if (DVar.CKind == OMPC_lastprivate) 2153 Reason = PDSA_LoopIterVarLastprivate; 2154 else 2155 Reason = PDSA_LoopIterVarLinear; 2156 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2157 DVar.CKind == OMPC_firstprivate) { 2158 Reason = PDSA_TaskVarFirstprivate; 2159 ReportLoc = DVar.ImplicitDSALoc; 2160 } else if (VD && VD->isStaticLocal()) 2161 Reason = PDSA_StaticLocalVarShared; 2162 else if (VD && VD->isStaticDataMember()) 2163 Reason = PDSA_StaticMemberShared; 2164 else if (VD && VD->isFileVarDecl()) 2165 Reason = PDSA_GlobalVarShared; 2166 else if (D->getType().isConstant(SemaRef.getASTContext())) 2167 Reason = PDSA_ConstVarShared; 2168 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2169 ReportHint = true; 2170 Reason = PDSA_LocalVarPrivate; 2171 } 2172 if (Reason != PDSA_Implicit) { 2173 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2174 << Reason << ReportHint 2175 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2176 } else if (DVar.ImplicitDSALoc.isValid()) { 2177 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2178 << getOpenMPClauseName(DVar.CKind); 2179 } 2180 } 2181 2182 namespace { 2183 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2184 DSAStackTy *Stack; 2185 Sema &SemaRef; 2186 bool ErrorFound = false; 2187 CapturedStmt *CS = nullptr; 2188 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2189 llvm::SmallVector<Expr *, 4> ImplicitMap; 2190 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2191 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2192 2193 void VisitSubCaptures(OMPExecutableDirective *S) { 2194 // Check implicitly captured variables. 2195 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2196 return; 2197 for (const CapturedStmt::Capture &Cap : 2198 S->getInnermostCapturedStmt()->captures()) { 2199 if (!Cap.capturesVariable()) 2200 continue; 2201 VarDecl *VD = Cap.getCapturedVar(); 2202 // Do not try to map the variable if it or its sub-component was mapped 2203 // already. 2204 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2205 Stack->checkMappableExprComponentListsForDecl( 2206 VD, /*CurrentRegionOnly=*/true, 2207 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2208 OpenMPClauseKind) { return true; })) 2209 continue; 2210 DeclRefExpr *DRE = buildDeclRefExpr( 2211 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2212 Cap.getLocation(), /*RefersToCapture=*/true); 2213 Visit(DRE); 2214 } 2215 } 2216 2217 public: 2218 void VisitDeclRefExpr(DeclRefExpr *E) { 2219 if (E->isTypeDependent() || E->isValueDependent() || 2220 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2221 return; 2222 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2223 VD = VD->getCanonicalDecl(); 2224 // Skip internally declared variables. 2225 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 2226 return; 2227 2228 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2229 // Check if the variable has explicit DSA set and stop analysis if it so. 2230 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2231 return; 2232 2233 // Skip internally declared static variables. 2234 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2235 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2236 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && 2237 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2238 return; 2239 2240 SourceLocation ELoc = E->getExprLoc(); 2241 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2242 // The default(none) clause requires that each variable that is referenced 2243 // in the construct, and does not have a predetermined data-sharing 2244 // attribute, must have its data-sharing attribute explicitly determined 2245 // by being listed in a data-sharing attribute clause. 2246 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2247 isParallelOrTaskRegion(DKind) && 2248 VarsWithInheritedDSA.count(VD) == 0) { 2249 VarsWithInheritedDSA[VD] = E; 2250 return; 2251 } 2252 2253 if (isOpenMPTargetExecutionDirective(DKind) && 2254 !Stack->isLoopControlVariable(VD).first) { 2255 if (!Stack->checkMappableExprComponentListsForDecl( 2256 VD, /*CurrentRegionOnly=*/true, 2257 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2258 StackComponents, 2259 OpenMPClauseKind) { 2260 // Variable is used if it has been marked as an array, array 2261 // section or the variable iself. 2262 return StackComponents.size() == 1 || 2263 std::all_of( 2264 std::next(StackComponents.rbegin()), 2265 StackComponents.rend(), 2266 [](const OMPClauseMappableExprCommon:: 2267 MappableComponent &MC) { 2268 return MC.getAssociatedDeclaration() == 2269 nullptr && 2270 (isa<OMPArraySectionExpr>( 2271 MC.getAssociatedExpression()) || 2272 isa<ArraySubscriptExpr>( 2273 MC.getAssociatedExpression())); 2274 }); 2275 })) { 2276 bool IsFirstprivate = false; 2277 // By default lambdas are captured as firstprivates. 2278 if (const auto *RD = 2279 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2280 IsFirstprivate = RD->isLambda(); 2281 IsFirstprivate = 2282 IsFirstprivate || 2283 (VD->getType().getNonReferenceType()->isScalarType() && 2284 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2285 if (IsFirstprivate) 2286 ImplicitFirstprivate.emplace_back(E); 2287 else 2288 ImplicitMap.emplace_back(E); 2289 return; 2290 } 2291 } 2292 2293 // OpenMP [2.9.3.6, Restrictions, p.2] 2294 // A list item that appears in a reduction clause of the innermost 2295 // enclosing worksharing or parallel construct may not be accessed in an 2296 // explicit task. 2297 DVar = Stack->hasInnermostDSA( 2298 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2299 [](OpenMPDirectiveKind K) { 2300 return isOpenMPParallelDirective(K) || 2301 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2302 }, 2303 /*FromParent=*/true); 2304 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2305 ErrorFound = true; 2306 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2307 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2308 return; 2309 } 2310 2311 // Define implicit data-sharing attributes for task. 2312 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2313 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2314 !Stack->isLoopControlVariable(VD).first) 2315 ImplicitFirstprivate.push_back(E); 2316 } 2317 } 2318 void VisitMemberExpr(MemberExpr *E) { 2319 if (E->isTypeDependent() || E->isValueDependent() || 2320 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2321 return; 2322 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2323 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2324 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2325 if (!FD) 2326 return; 2327 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2328 // Check if the variable has explicit DSA set and stop analysis if it 2329 // so. 2330 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2331 return; 2332 2333 if (isOpenMPTargetExecutionDirective(DKind) && 2334 !Stack->isLoopControlVariable(FD).first && 2335 !Stack->checkMappableExprComponentListsForDecl( 2336 FD, /*CurrentRegionOnly=*/true, 2337 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2338 StackComponents, 2339 OpenMPClauseKind) { 2340 return isa<CXXThisExpr>( 2341 cast<MemberExpr>( 2342 StackComponents.back().getAssociatedExpression()) 2343 ->getBase() 2344 ->IgnoreParens()); 2345 })) { 2346 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2347 // A bit-field cannot appear in a map clause. 2348 // 2349 if (FD->isBitField()) 2350 return; 2351 2352 // Check to see if the member expression is referencing a class that 2353 // has already been explicitly mapped 2354 if (Stack->isClassPreviouslyMapped(TE->getType())) 2355 return; 2356 2357 ImplicitMap.emplace_back(E); 2358 return; 2359 } 2360 2361 SourceLocation ELoc = E->getExprLoc(); 2362 // OpenMP [2.9.3.6, Restrictions, p.2] 2363 // A list item that appears in a reduction clause of the innermost 2364 // enclosing worksharing or parallel construct may not be accessed in 2365 // an explicit task. 2366 DVar = Stack->hasInnermostDSA( 2367 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2368 [](OpenMPDirectiveKind K) { 2369 return isOpenMPParallelDirective(K) || 2370 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2371 }, 2372 /*FromParent=*/true); 2373 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2374 ErrorFound = true; 2375 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2376 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2377 return; 2378 } 2379 2380 // Define implicit data-sharing attributes for task. 2381 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2382 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2383 !Stack->isLoopControlVariable(FD).first) { 2384 // Check if there is a captured expression for the current field in the 2385 // region. Do not mark it as firstprivate unless there is no captured 2386 // expression. 2387 // TODO: try to make it firstprivate. 2388 if (DVar.CKind != OMPC_unknown) 2389 ImplicitFirstprivate.push_back(E); 2390 } 2391 return; 2392 } 2393 if (isOpenMPTargetExecutionDirective(DKind)) { 2394 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2395 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2396 /*NoDiagnose=*/true)) 2397 return; 2398 const auto *VD = cast<ValueDecl>( 2399 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2400 if (!Stack->checkMappableExprComponentListsForDecl( 2401 VD, /*CurrentRegionOnly=*/true, 2402 [&CurComponents]( 2403 OMPClauseMappableExprCommon::MappableExprComponentListRef 2404 StackComponents, 2405 OpenMPClauseKind) { 2406 auto CCI = CurComponents.rbegin(); 2407 auto CCE = CurComponents.rend(); 2408 for (const auto &SC : llvm::reverse(StackComponents)) { 2409 // Do both expressions have the same kind? 2410 if (CCI->getAssociatedExpression()->getStmtClass() != 2411 SC.getAssociatedExpression()->getStmtClass()) 2412 if (!(isa<OMPArraySectionExpr>( 2413 SC.getAssociatedExpression()) && 2414 isa<ArraySubscriptExpr>( 2415 CCI->getAssociatedExpression()))) 2416 return false; 2417 2418 const Decl *CCD = CCI->getAssociatedDeclaration(); 2419 const Decl *SCD = SC.getAssociatedDeclaration(); 2420 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2421 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2422 if (SCD != CCD) 2423 return false; 2424 std::advance(CCI, 1); 2425 if (CCI == CCE) 2426 break; 2427 } 2428 return true; 2429 })) { 2430 Visit(E->getBase()); 2431 } 2432 } else { 2433 Visit(E->getBase()); 2434 } 2435 } 2436 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2437 for (OMPClause *C : S->clauses()) { 2438 // Skip analysis of arguments of implicitly defined firstprivate clause 2439 // for task|target directives. 2440 // Skip analysis of arguments of implicitly defined map clause for target 2441 // directives. 2442 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2443 C->isImplicit())) { 2444 for (Stmt *CC : C->children()) { 2445 if (CC) 2446 Visit(CC); 2447 } 2448 } 2449 } 2450 // Check implicitly captured variables. 2451 VisitSubCaptures(S); 2452 } 2453 void VisitStmt(Stmt *S) { 2454 for (Stmt *C : S->children()) { 2455 if (C) { 2456 // Check implicitly captured variables in the task-based directives to 2457 // check if they must be firstprivatized. 2458 Visit(C); 2459 } 2460 } 2461 } 2462 2463 bool isErrorFound() const { return ErrorFound; } 2464 ArrayRef<Expr *> getImplicitFirstprivate() const { 2465 return ImplicitFirstprivate; 2466 } 2467 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2468 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2469 return VarsWithInheritedDSA; 2470 } 2471 2472 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2473 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 2474 }; 2475 } // namespace 2476 2477 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2478 switch (DKind) { 2479 case OMPD_parallel: 2480 case OMPD_parallel_for: 2481 case OMPD_parallel_for_simd: 2482 case OMPD_parallel_sections: 2483 case OMPD_teams: 2484 case OMPD_teams_distribute: 2485 case OMPD_teams_distribute_simd: { 2486 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2487 QualType KmpInt32PtrTy = 2488 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2489 Sema::CapturedParamNameType Params[] = { 2490 std::make_pair(".global_tid.", KmpInt32PtrTy), 2491 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2492 std::make_pair(StringRef(), QualType()) // __context with shared vars 2493 }; 2494 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2495 Params); 2496 break; 2497 } 2498 case OMPD_target_teams: 2499 case OMPD_target_parallel: 2500 case OMPD_target_parallel_for: 2501 case OMPD_target_parallel_for_simd: 2502 case OMPD_target_teams_distribute: 2503 case OMPD_target_teams_distribute_simd: { 2504 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2505 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2506 QualType KmpInt32PtrTy = 2507 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2508 QualType Args[] = {VoidPtrTy}; 2509 FunctionProtoType::ExtProtoInfo EPI; 2510 EPI.Variadic = true; 2511 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2512 Sema::CapturedParamNameType Params[] = { 2513 std::make_pair(".global_tid.", KmpInt32Ty), 2514 std::make_pair(".part_id.", KmpInt32PtrTy), 2515 std::make_pair(".privates.", VoidPtrTy), 2516 std::make_pair( 2517 ".copy_fn.", 2518 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2519 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2520 std::make_pair(StringRef(), QualType()) // __context with shared vars 2521 }; 2522 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2523 Params); 2524 // Mark this captured region as inlined, because we don't use outlined 2525 // function directly. 2526 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2527 AlwaysInlineAttr::CreateImplicit( 2528 Context, AlwaysInlineAttr::Keyword_forceinline)); 2529 Sema::CapturedParamNameType ParamsTarget[] = { 2530 std::make_pair(StringRef(), QualType()) // __context with shared vars 2531 }; 2532 // Start a captured region for 'target' with no implicit parameters. 2533 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2534 ParamsTarget); 2535 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2536 std::make_pair(".global_tid.", KmpInt32PtrTy), 2537 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2538 std::make_pair(StringRef(), QualType()) // __context with shared vars 2539 }; 2540 // Start a captured region for 'teams' or 'parallel'. Both regions have 2541 // the same implicit parameters. 2542 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2543 ParamsTeamsOrParallel); 2544 break; 2545 } 2546 case OMPD_target: 2547 case OMPD_target_simd: { 2548 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2549 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2550 QualType KmpInt32PtrTy = 2551 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2552 QualType Args[] = {VoidPtrTy}; 2553 FunctionProtoType::ExtProtoInfo EPI; 2554 EPI.Variadic = true; 2555 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2556 Sema::CapturedParamNameType Params[] = { 2557 std::make_pair(".global_tid.", KmpInt32Ty), 2558 std::make_pair(".part_id.", KmpInt32PtrTy), 2559 std::make_pair(".privates.", VoidPtrTy), 2560 std::make_pair( 2561 ".copy_fn.", 2562 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2563 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2564 std::make_pair(StringRef(), QualType()) // __context with shared vars 2565 }; 2566 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2567 Params); 2568 // Mark this captured region as inlined, because we don't use outlined 2569 // function directly. 2570 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2571 AlwaysInlineAttr::CreateImplicit( 2572 Context, AlwaysInlineAttr::Keyword_forceinline)); 2573 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2574 std::make_pair(StringRef(), QualType())); 2575 break; 2576 } 2577 case OMPD_simd: 2578 case OMPD_for: 2579 case OMPD_for_simd: 2580 case OMPD_sections: 2581 case OMPD_section: 2582 case OMPD_single: 2583 case OMPD_master: 2584 case OMPD_critical: 2585 case OMPD_taskgroup: 2586 case OMPD_distribute: 2587 case OMPD_distribute_simd: 2588 case OMPD_ordered: 2589 case OMPD_atomic: 2590 case OMPD_target_data: { 2591 Sema::CapturedParamNameType Params[] = { 2592 std::make_pair(StringRef(), QualType()) // __context with shared vars 2593 }; 2594 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2595 Params); 2596 break; 2597 } 2598 case OMPD_task: { 2599 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2600 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2601 QualType KmpInt32PtrTy = 2602 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2603 QualType Args[] = {VoidPtrTy}; 2604 FunctionProtoType::ExtProtoInfo EPI; 2605 EPI.Variadic = true; 2606 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2607 Sema::CapturedParamNameType Params[] = { 2608 std::make_pair(".global_tid.", KmpInt32Ty), 2609 std::make_pair(".part_id.", KmpInt32PtrTy), 2610 std::make_pair(".privates.", VoidPtrTy), 2611 std::make_pair( 2612 ".copy_fn.", 2613 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2614 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2615 std::make_pair(StringRef(), QualType()) // __context with shared vars 2616 }; 2617 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2618 Params); 2619 // Mark this captured region as inlined, because we don't use outlined 2620 // function directly. 2621 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2622 AlwaysInlineAttr::CreateImplicit( 2623 Context, AlwaysInlineAttr::Keyword_forceinline)); 2624 break; 2625 } 2626 case OMPD_taskloop: 2627 case OMPD_taskloop_simd: { 2628 QualType KmpInt32Ty = 2629 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 2630 .withConst(); 2631 QualType KmpUInt64Ty = 2632 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 2633 .withConst(); 2634 QualType KmpInt64Ty = 2635 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 2636 .withConst(); 2637 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2638 QualType KmpInt32PtrTy = 2639 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2640 QualType Args[] = {VoidPtrTy}; 2641 FunctionProtoType::ExtProtoInfo EPI; 2642 EPI.Variadic = true; 2643 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2644 Sema::CapturedParamNameType Params[] = { 2645 std::make_pair(".global_tid.", KmpInt32Ty), 2646 std::make_pair(".part_id.", KmpInt32PtrTy), 2647 std::make_pair(".privates.", VoidPtrTy), 2648 std::make_pair( 2649 ".copy_fn.", 2650 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2651 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2652 std::make_pair(".lb.", KmpUInt64Ty), 2653 std::make_pair(".ub.", KmpUInt64Ty), 2654 std::make_pair(".st.", KmpInt64Ty), 2655 std::make_pair(".liter.", KmpInt32Ty), 2656 std::make_pair(".reductions.", VoidPtrTy), 2657 std::make_pair(StringRef(), QualType()) // __context with shared vars 2658 }; 2659 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2660 Params); 2661 // Mark this captured region as inlined, because we don't use outlined 2662 // function directly. 2663 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2664 AlwaysInlineAttr::CreateImplicit( 2665 Context, AlwaysInlineAttr::Keyword_forceinline)); 2666 break; 2667 } 2668 case OMPD_distribute_parallel_for_simd: 2669 case OMPD_distribute_parallel_for: { 2670 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2671 QualType KmpInt32PtrTy = 2672 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2673 Sema::CapturedParamNameType Params[] = { 2674 std::make_pair(".global_tid.", KmpInt32PtrTy), 2675 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2676 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2677 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2678 std::make_pair(StringRef(), QualType()) // __context with shared vars 2679 }; 2680 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2681 Params); 2682 break; 2683 } 2684 case OMPD_target_teams_distribute_parallel_for: 2685 case OMPD_target_teams_distribute_parallel_for_simd: { 2686 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2687 QualType KmpInt32PtrTy = 2688 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2689 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2690 2691 QualType Args[] = {VoidPtrTy}; 2692 FunctionProtoType::ExtProtoInfo EPI; 2693 EPI.Variadic = true; 2694 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2695 Sema::CapturedParamNameType Params[] = { 2696 std::make_pair(".global_tid.", KmpInt32Ty), 2697 std::make_pair(".part_id.", KmpInt32PtrTy), 2698 std::make_pair(".privates.", VoidPtrTy), 2699 std::make_pair( 2700 ".copy_fn.", 2701 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2702 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2703 std::make_pair(StringRef(), QualType()) // __context with shared vars 2704 }; 2705 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2706 Params); 2707 // Mark this captured region as inlined, because we don't use outlined 2708 // function directly. 2709 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2710 AlwaysInlineAttr::CreateImplicit( 2711 Context, AlwaysInlineAttr::Keyword_forceinline)); 2712 Sema::CapturedParamNameType ParamsTarget[] = { 2713 std::make_pair(StringRef(), QualType()) // __context with shared vars 2714 }; 2715 // Start a captured region for 'target' with no implicit parameters. 2716 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2717 ParamsTarget); 2718 2719 Sema::CapturedParamNameType ParamsTeams[] = { 2720 std::make_pair(".global_tid.", KmpInt32PtrTy), 2721 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2722 std::make_pair(StringRef(), QualType()) // __context with shared vars 2723 }; 2724 // Start a captured region for 'target' with no implicit parameters. 2725 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2726 ParamsTeams); 2727 2728 Sema::CapturedParamNameType ParamsParallel[] = { 2729 std::make_pair(".global_tid.", KmpInt32PtrTy), 2730 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2731 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2732 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2733 std::make_pair(StringRef(), QualType()) // __context with shared vars 2734 }; 2735 // Start a captured region for 'teams' or 'parallel'. Both regions have 2736 // the same implicit parameters. 2737 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2738 ParamsParallel); 2739 break; 2740 } 2741 2742 case OMPD_teams_distribute_parallel_for: 2743 case OMPD_teams_distribute_parallel_for_simd: { 2744 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2745 QualType KmpInt32PtrTy = 2746 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2747 2748 Sema::CapturedParamNameType ParamsTeams[] = { 2749 std::make_pair(".global_tid.", KmpInt32PtrTy), 2750 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2751 std::make_pair(StringRef(), QualType()) // __context with shared vars 2752 }; 2753 // Start a captured region for 'target' with no implicit parameters. 2754 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2755 ParamsTeams); 2756 2757 Sema::CapturedParamNameType ParamsParallel[] = { 2758 std::make_pair(".global_tid.", KmpInt32PtrTy), 2759 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2760 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2761 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2762 std::make_pair(StringRef(), QualType()) // __context with shared vars 2763 }; 2764 // Start a captured region for 'teams' or 'parallel'. Both regions have 2765 // the same implicit parameters. 2766 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2767 ParamsParallel); 2768 break; 2769 } 2770 case OMPD_target_update: 2771 case OMPD_target_enter_data: 2772 case OMPD_target_exit_data: { 2773 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2774 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2775 QualType KmpInt32PtrTy = 2776 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2777 QualType Args[] = {VoidPtrTy}; 2778 FunctionProtoType::ExtProtoInfo EPI; 2779 EPI.Variadic = true; 2780 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2781 Sema::CapturedParamNameType Params[] = { 2782 std::make_pair(".global_tid.", KmpInt32Ty), 2783 std::make_pair(".part_id.", KmpInt32PtrTy), 2784 std::make_pair(".privates.", VoidPtrTy), 2785 std::make_pair( 2786 ".copy_fn.", 2787 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2788 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2789 std::make_pair(StringRef(), QualType()) // __context with shared vars 2790 }; 2791 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2792 Params); 2793 // Mark this captured region as inlined, because we don't use outlined 2794 // function directly. 2795 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2796 AlwaysInlineAttr::CreateImplicit( 2797 Context, AlwaysInlineAttr::Keyword_forceinline)); 2798 break; 2799 } 2800 case OMPD_threadprivate: 2801 case OMPD_taskyield: 2802 case OMPD_barrier: 2803 case OMPD_taskwait: 2804 case OMPD_cancellation_point: 2805 case OMPD_cancel: 2806 case OMPD_flush: 2807 case OMPD_declare_reduction: 2808 case OMPD_declare_simd: 2809 case OMPD_declare_target: 2810 case OMPD_end_declare_target: 2811 case OMPD_requires: 2812 llvm_unreachable("OpenMP Directive is not allowed"); 2813 case OMPD_unknown: 2814 llvm_unreachable("Unknown OpenMP directive"); 2815 } 2816 } 2817 2818 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 2819 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2820 getOpenMPCaptureRegions(CaptureRegions, DKind); 2821 return CaptureRegions.size(); 2822 } 2823 2824 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2825 Expr *CaptureExpr, bool WithInit, 2826 bool AsExpression) { 2827 assert(CaptureExpr); 2828 ASTContext &C = S.getASTContext(); 2829 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 2830 QualType Ty = Init->getType(); 2831 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 2832 if (S.getLangOpts().CPlusPlus) { 2833 Ty = C.getLValueReferenceType(Ty); 2834 } else { 2835 Ty = C.getPointerType(Ty); 2836 ExprResult Res = 2837 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 2838 if (!Res.isUsable()) 2839 return nullptr; 2840 Init = Res.get(); 2841 } 2842 WithInit = true; 2843 } 2844 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 2845 CaptureExpr->getBeginLoc()); 2846 if (!WithInit) 2847 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 2848 S.CurContext->addHiddenDecl(CED); 2849 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 2850 return CED; 2851 } 2852 2853 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2854 bool WithInit) { 2855 OMPCapturedExprDecl *CD; 2856 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 2857 CD = cast<OMPCapturedExprDecl>(VD); 2858 else 2859 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 2860 /*AsExpression=*/false); 2861 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2862 CaptureExpr->getExprLoc()); 2863 } 2864 2865 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 2866 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 2867 if (!Ref) { 2868 OMPCapturedExprDecl *CD = buildCaptureDecl( 2869 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 2870 /*WithInit=*/true, /*AsExpression=*/true); 2871 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2872 CaptureExpr->getExprLoc()); 2873 } 2874 ExprResult Res = Ref; 2875 if (!S.getLangOpts().CPlusPlus && 2876 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 2877 Ref->getType()->isPointerType()) { 2878 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 2879 if (!Res.isUsable()) 2880 return ExprError(); 2881 } 2882 return S.DefaultLvalueConversion(Res.get()); 2883 } 2884 2885 namespace { 2886 // OpenMP directives parsed in this section are represented as a 2887 // CapturedStatement with an associated statement. If a syntax error 2888 // is detected during the parsing of the associated statement, the 2889 // compiler must abort processing and close the CapturedStatement. 2890 // 2891 // Combined directives such as 'target parallel' have more than one 2892 // nested CapturedStatements. This RAII ensures that we unwind out 2893 // of all the nested CapturedStatements when an error is found. 2894 class CaptureRegionUnwinderRAII { 2895 private: 2896 Sema &S; 2897 bool &ErrorFound; 2898 OpenMPDirectiveKind DKind = OMPD_unknown; 2899 2900 public: 2901 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 2902 OpenMPDirectiveKind DKind) 2903 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 2904 ~CaptureRegionUnwinderRAII() { 2905 if (ErrorFound) { 2906 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 2907 while (--ThisCaptureLevel >= 0) 2908 S.ActOnCapturedRegionError(); 2909 } 2910 } 2911 }; 2912 } // namespace 2913 2914 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 2915 ArrayRef<OMPClause *> Clauses) { 2916 bool ErrorFound = false; 2917 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 2918 *this, ErrorFound, DSAStack->getCurrentDirective()); 2919 if (!S.isUsable()) { 2920 ErrorFound = true; 2921 return StmtError(); 2922 } 2923 2924 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2925 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 2926 OMPOrderedClause *OC = nullptr; 2927 OMPScheduleClause *SC = nullptr; 2928 SmallVector<const OMPLinearClause *, 4> LCs; 2929 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 2930 // This is required for proper codegen. 2931 for (OMPClause *Clause : Clauses) { 2932 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2933 Clause->getClauseKind() == OMPC_in_reduction) { 2934 // Capture taskgroup task_reduction descriptors inside the tasking regions 2935 // with the corresponding in_reduction items. 2936 auto *IRC = cast<OMPInReductionClause>(Clause); 2937 for (Expr *E : IRC->taskgroup_descriptors()) 2938 if (E) 2939 MarkDeclarationsReferencedInExpr(E); 2940 } 2941 if (isOpenMPPrivate(Clause->getClauseKind()) || 2942 Clause->getClauseKind() == OMPC_copyprivate || 2943 (getLangOpts().OpenMPUseTLS && 2944 getASTContext().getTargetInfo().isTLSSupported() && 2945 Clause->getClauseKind() == OMPC_copyin)) { 2946 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 2947 // Mark all variables in private list clauses as used in inner region. 2948 for (Stmt *VarRef : Clause->children()) { 2949 if (auto *E = cast_or_null<Expr>(VarRef)) { 2950 MarkDeclarationsReferencedInExpr(E); 2951 } 2952 } 2953 DSAStack->setForceVarCapturing(/*V=*/false); 2954 } else if (CaptureRegions.size() > 1 || 2955 CaptureRegions.back() != OMPD_unknown) { 2956 if (auto *C = OMPClauseWithPreInit::get(Clause)) 2957 PICs.push_back(C); 2958 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 2959 if (Expr *E = C->getPostUpdateExpr()) 2960 MarkDeclarationsReferencedInExpr(E); 2961 } 2962 } 2963 if (Clause->getClauseKind() == OMPC_schedule) 2964 SC = cast<OMPScheduleClause>(Clause); 2965 else if (Clause->getClauseKind() == OMPC_ordered) 2966 OC = cast<OMPOrderedClause>(Clause); 2967 else if (Clause->getClauseKind() == OMPC_linear) 2968 LCs.push_back(cast<OMPLinearClause>(Clause)); 2969 } 2970 // OpenMP, 2.7.1 Loop Construct, Restrictions 2971 // The nonmonotonic modifier cannot be specified if an ordered clause is 2972 // specified. 2973 if (SC && 2974 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 2975 SC->getSecondScheduleModifier() == 2976 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 2977 OC) { 2978 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 2979 ? SC->getFirstScheduleModifierLoc() 2980 : SC->getSecondScheduleModifierLoc(), 2981 diag::err_omp_schedule_nonmonotonic_ordered) 2982 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 2983 ErrorFound = true; 2984 } 2985 if (!LCs.empty() && OC && OC->getNumForLoops()) { 2986 for (const OMPLinearClause *C : LCs) { 2987 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 2988 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 2989 } 2990 ErrorFound = true; 2991 } 2992 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 2993 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 2994 OC->getNumForLoops()) { 2995 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 2996 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 2997 ErrorFound = true; 2998 } 2999 if (ErrorFound) { 3000 return StmtError(); 3001 } 3002 StmtResult SR = S; 3003 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3004 // Mark all variables in private list clauses as used in inner region. 3005 // Required for proper codegen of combined directives. 3006 // TODO: add processing for other clauses. 3007 if (ThisCaptureRegion != OMPD_unknown) { 3008 for (const clang::OMPClauseWithPreInit *C : PICs) { 3009 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3010 // Find the particular capture region for the clause if the 3011 // directive is a combined one with multiple capture regions. 3012 // If the directive is not a combined one, the capture region 3013 // associated with the clause is OMPD_unknown and is generated 3014 // only once. 3015 if (CaptureRegion == ThisCaptureRegion || 3016 CaptureRegion == OMPD_unknown) { 3017 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3018 for (Decl *D : DS->decls()) 3019 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3020 } 3021 } 3022 } 3023 } 3024 SR = ActOnCapturedRegionEnd(SR.get()); 3025 } 3026 return SR; 3027 } 3028 3029 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3030 OpenMPDirectiveKind CancelRegion, 3031 SourceLocation StartLoc) { 3032 // CancelRegion is only needed for cancel and cancellation_point. 3033 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3034 return false; 3035 3036 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3037 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3038 return false; 3039 3040 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3041 << getOpenMPDirectiveName(CancelRegion); 3042 return true; 3043 } 3044 3045 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3046 OpenMPDirectiveKind CurrentRegion, 3047 const DeclarationNameInfo &CurrentName, 3048 OpenMPDirectiveKind CancelRegion, 3049 SourceLocation StartLoc) { 3050 if (Stack->getCurScope()) { 3051 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3052 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3053 bool NestingProhibited = false; 3054 bool CloseNesting = true; 3055 bool OrphanSeen = false; 3056 enum { 3057 NoRecommend, 3058 ShouldBeInParallelRegion, 3059 ShouldBeInOrderedRegion, 3060 ShouldBeInTargetRegion, 3061 ShouldBeInTeamsRegion 3062 } Recommend = NoRecommend; 3063 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3064 // OpenMP [2.16, Nesting of Regions] 3065 // OpenMP constructs may not be nested inside a simd region. 3066 // OpenMP [2.8.1,simd Construct, Restrictions] 3067 // An ordered construct with the simd clause is the only OpenMP 3068 // construct that can appear in the simd region. 3069 // Allowing a SIMD construct nested in another SIMD construct is an 3070 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3071 // message. 3072 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3073 ? diag::err_omp_prohibited_region_simd 3074 : diag::warn_omp_nesting_simd); 3075 return CurrentRegion != OMPD_simd; 3076 } 3077 if (ParentRegion == OMPD_atomic) { 3078 // OpenMP [2.16, Nesting of Regions] 3079 // OpenMP constructs may not be nested inside an atomic region. 3080 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3081 return true; 3082 } 3083 if (CurrentRegion == OMPD_section) { 3084 // OpenMP [2.7.2, sections Construct, Restrictions] 3085 // Orphaned section directives are prohibited. That is, the section 3086 // directives must appear within the sections construct and must not be 3087 // encountered elsewhere in the sections region. 3088 if (ParentRegion != OMPD_sections && 3089 ParentRegion != OMPD_parallel_sections) { 3090 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3091 << (ParentRegion != OMPD_unknown) 3092 << getOpenMPDirectiveName(ParentRegion); 3093 return true; 3094 } 3095 return false; 3096 } 3097 // Allow some constructs (except teams and cancellation constructs) to be 3098 // orphaned (they could be used in functions, called from OpenMP regions 3099 // with the required preconditions). 3100 if (ParentRegion == OMPD_unknown && 3101 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3102 CurrentRegion != OMPD_cancellation_point && 3103 CurrentRegion != OMPD_cancel) 3104 return false; 3105 if (CurrentRegion == OMPD_cancellation_point || 3106 CurrentRegion == OMPD_cancel) { 3107 // OpenMP [2.16, Nesting of Regions] 3108 // A cancellation point construct for which construct-type-clause is 3109 // taskgroup must be nested inside a task construct. A cancellation 3110 // point construct for which construct-type-clause is not taskgroup must 3111 // be closely nested inside an OpenMP construct that matches the type 3112 // specified in construct-type-clause. 3113 // A cancel construct for which construct-type-clause is taskgroup must be 3114 // nested inside a task construct. A cancel construct for which 3115 // construct-type-clause is not taskgroup must be closely nested inside an 3116 // OpenMP construct that matches the type specified in 3117 // construct-type-clause. 3118 NestingProhibited = 3119 !((CancelRegion == OMPD_parallel && 3120 (ParentRegion == OMPD_parallel || 3121 ParentRegion == OMPD_target_parallel)) || 3122 (CancelRegion == OMPD_for && 3123 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3124 ParentRegion == OMPD_target_parallel_for || 3125 ParentRegion == OMPD_distribute_parallel_for || 3126 ParentRegion == OMPD_teams_distribute_parallel_for || 3127 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3128 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3129 (CancelRegion == OMPD_sections && 3130 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3131 ParentRegion == OMPD_parallel_sections))); 3132 OrphanSeen = ParentRegion == OMPD_unknown; 3133 } else if (CurrentRegion == OMPD_master) { 3134 // OpenMP [2.16, Nesting of Regions] 3135 // A master region may not be closely nested inside a worksharing, 3136 // atomic, or explicit task region. 3137 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3138 isOpenMPTaskingDirective(ParentRegion); 3139 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3140 // OpenMP [2.16, Nesting of Regions] 3141 // A critical region may not be nested (closely or otherwise) inside a 3142 // critical region with the same name. Note that this restriction is not 3143 // sufficient to prevent deadlock. 3144 SourceLocation PreviousCriticalLoc; 3145 bool DeadLock = Stack->hasDirective( 3146 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3147 const DeclarationNameInfo &DNI, 3148 SourceLocation Loc) { 3149 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3150 PreviousCriticalLoc = Loc; 3151 return true; 3152 } 3153 return false; 3154 }, 3155 false /* skip top directive */); 3156 if (DeadLock) { 3157 SemaRef.Diag(StartLoc, 3158 diag::err_omp_prohibited_region_critical_same_name) 3159 << CurrentName.getName(); 3160 if (PreviousCriticalLoc.isValid()) 3161 SemaRef.Diag(PreviousCriticalLoc, 3162 diag::note_omp_previous_critical_region); 3163 return true; 3164 } 3165 } else if (CurrentRegion == OMPD_barrier) { 3166 // OpenMP [2.16, Nesting of Regions] 3167 // A barrier region may not be closely nested inside a worksharing, 3168 // explicit task, critical, ordered, atomic, or master region. 3169 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3170 isOpenMPTaskingDirective(ParentRegion) || 3171 ParentRegion == OMPD_master || 3172 ParentRegion == OMPD_critical || 3173 ParentRegion == OMPD_ordered; 3174 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3175 !isOpenMPParallelDirective(CurrentRegion) && 3176 !isOpenMPTeamsDirective(CurrentRegion)) { 3177 // OpenMP [2.16, Nesting of Regions] 3178 // A worksharing region may not be closely nested inside a worksharing, 3179 // explicit task, critical, ordered, atomic, or master region. 3180 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3181 isOpenMPTaskingDirective(ParentRegion) || 3182 ParentRegion == OMPD_master || 3183 ParentRegion == OMPD_critical || 3184 ParentRegion == OMPD_ordered; 3185 Recommend = ShouldBeInParallelRegion; 3186 } else if (CurrentRegion == OMPD_ordered) { 3187 // OpenMP [2.16, Nesting of Regions] 3188 // An ordered region may not be closely nested inside a critical, 3189 // atomic, or explicit task region. 3190 // An ordered region must be closely nested inside a loop region (or 3191 // parallel loop region) with an ordered clause. 3192 // OpenMP [2.8.1,simd Construct, Restrictions] 3193 // An ordered construct with the simd clause is the only OpenMP construct 3194 // that can appear in the simd region. 3195 NestingProhibited = ParentRegion == OMPD_critical || 3196 isOpenMPTaskingDirective(ParentRegion) || 3197 !(isOpenMPSimdDirective(ParentRegion) || 3198 Stack->isParentOrderedRegion()); 3199 Recommend = ShouldBeInOrderedRegion; 3200 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3201 // OpenMP [2.16, Nesting of Regions] 3202 // If specified, a teams construct must be contained within a target 3203 // construct. 3204 NestingProhibited = ParentRegion != OMPD_target; 3205 OrphanSeen = ParentRegion == OMPD_unknown; 3206 Recommend = ShouldBeInTargetRegion; 3207 } 3208 if (!NestingProhibited && 3209 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3210 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3211 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3212 // OpenMP [2.16, Nesting of Regions] 3213 // distribute, parallel, parallel sections, parallel workshare, and the 3214 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3215 // constructs that can be closely nested in the teams region. 3216 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3217 !isOpenMPDistributeDirective(CurrentRegion); 3218 Recommend = ShouldBeInParallelRegion; 3219 } 3220 if (!NestingProhibited && 3221 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3222 // OpenMP 4.5 [2.17 Nesting of Regions] 3223 // The region associated with the distribute construct must be strictly 3224 // nested inside a teams region 3225 NestingProhibited = 3226 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3227 Recommend = ShouldBeInTeamsRegion; 3228 } 3229 if (!NestingProhibited && 3230 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3231 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3232 // OpenMP 4.5 [2.17 Nesting of Regions] 3233 // If a target, target update, target data, target enter data, or 3234 // target exit data construct is encountered during execution of a 3235 // target region, the behavior is unspecified. 3236 NestingProhibited = Stack->hasDirective( 3237 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3238 SourceLocation) { 3239 if (isOpenMPTargetExecutionDirective(K)) { 3240 OffendingRegion = K; 3241 return true; 3242 } 3243 return false; 3244 }, 3245 false /* don't skip top directive */); 3246 CloseNesting = false; 3247 } 3248 if (NestingProhibited) { 3249 if (OrphanSeen) { 3250 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3251 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3252 } else { 3253 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3254 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3255 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3256 } 3257 return true; 3258 } 3259 } 3260 return false; 3261 } 3262 3263 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3264 ArrayRef<OMPClause *> Clauses, 3265 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3266 bool ErrorFound = false; 3267 unsigned NamedModifiersNumber = 0; 3268 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3269 OMPD_unknown + 1); 3270 SmallVector<SourceLocation, 4> NameModifierLoc; 3271 for (const OMPClause *C : Clauses) { 3272 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3273 // At most one if clause without a directive-name-modifier can appear on 3274 // the directive. 3275 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3276 if (FoundNameModifiers[CurNM]) { 3277 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3278 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3279 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3280 ErrorFound = true; 3281 } else if (CurNM != OMPD_unknown) { 3282 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3283 ++NamedModifiersNumber; 3284 } 3285 FoundNameModifiers[CurNM] = IC; 3286 if (CurNM == OMPD_unknown) 3287 continue; 3288 // Check if the specified name modifier is allowed for the current 3289 // directive. 3290 // At most one if clause with the particular directive-name-modifier can 3291 // appear on the directive. 3292 bool MatchFound = false; 3293 for (auto NM : AllowedNameModifiers) { 3294 if (CurNM == NM) { 3295 MatchFound = true; 3296 break; 3297 } 3298 } 3299 if (!MatchFound) { 3300 S.Diag(IC->getNameModifierLoc(), 3301 diag::err_omp_wrong_if_directive_name_modifier) 3302 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3303 ErrorFound = true; 3304 } 3305 } 3306 } 3307 // If any if clause on the directive includes a directive-name-modifier then 3308 // all if clauses on the directive must include a directive-name-modifier. 3309 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3310 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3311 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3312 diag::err_omp_no_more_if_clause); 3313 } else { 3314 std::string Values; 3315 std::string Sep(", "); 3316 unsigned AllowedCnt = 0; 3317 unsigned TotalAllowedNum = 3318 AllowedNameModifiers.size() - NamedModifiersNumber; 3319 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3320 ++Cnt) { 3321 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3322 if (!FoundNameModifiers[NM]) { 3323 Values += "'"; 3324 Values += getOpenMPDirectiveName(NM); 3325 Values += "'"; 3326 if (AllowedCnt + 2 == TotalAllowedNum) 3327 Values += " or "; 3328 else if (AllowedCnt + 1 != TotalAllowedNum) 3329 Values += Sep; 3330 ++AllowedCnt; 3331 } 3332 } 3333 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3334 diag::err_omp_unnamed_if_clause) 3335 << (TotalAllowedNum > 1) << Values; 3336 } 3337 for (SourceLocation Loc : NameModifierLoc) { 3338 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3339 } 3340 ErrorFound = true; 3341 } 3342 return ErrorFound; 3343 } 3344 3345 StmtResult Sema::ActOnOpenMPExecutableDirective( 3346 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3347 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3348 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3349 StmtResult Res = StmtError(); 3350 // First check CancelRegion which is then used in checkNestingOfRegions. 3351 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3352 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3353 StartLoc)) 3354 return StmtError(); 3355 3356 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3357 VarsWithInheritedDSAType VarsWithInheritedDSA; 3358 bool ErrorFound = false; 3359 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3360 if (AStmt && !CurContext->isDependentContext()) { 3361 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3362 3363 // Check default data sharing attributes for referenced variables. 3364 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3365 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3366 Stmt *S = AStmt; 3367 while (--ThisCaptureLevel >= 0) 3368 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3369 DSAChecker.Visit(S); 3370 if (DSAChecker.isErrorFound()) 3371 return StmtError(); 3372 // Generate list of implicitly defined firstprivate variables. 3373 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3374 3375 SmallVector<Expr *, 4> ImplicitFirstprivates( 3376 DSAChecker.getImplicitFirstprivate().begin(), 3377 DSAChecker.getImplicitFirstprivate().end()); 3378 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3379 DSAChecker.getImplicitMap().end()); 3380 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3381 for (OMPClause *C : Clauses) { 3382 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3383 for (Expr *E : IRC->taskgroup_descriptors()) 3384 if (E) 3385 ImplicitFirstprivates.emplace_back(E); 3386 } 3387 } 3388 if (!ImplicitFirstprivates.empty()) { 3389 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3390 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3391 SourceLocation())) { 3392 ClausesWithImplicit.push_back(Implicit); 3393 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3394 ImplicitFirstprivates.size(); 3395 } else { 3396 ErrorFound = true; 3397 } 3398 } 3399 if (!ImplicitMaps.empty()) { 3400 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3401 llvm::None, llvm::None, OMPC_MAP_tofrom, 3402 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 3403 ImplicitMaps, SourceLocation(), SourceLocation(), 3404 SourceLocation())) { 3405 ClausesWithImplicit.emplace_back(Implicit); 3406 ErrorFound |= 3407 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3408 } else { 3409 ErrorFound = true; 3410 } 3411 } 3412 } 3413 3414 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3415 switch (Kind) { 3416 case OMPD_parallel: 3417 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3418 EndLoc); 3419 AllowedNameModifiers.push_back(OMPD_parallel); 3420 break; 3421 case OMPD_simd: 3422 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3423 VarsWithInheritedDSA); 3424 break; 3425 case OMPD_for: 3426 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3427 VarsWithInheritedDSA); 3428 break; 3429 case OMPD_for_simd: 3430 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3431 EndLoc, VarsWithInheritedDSA); 3432 break; 3433 case OMPD_sections: 3434 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3435 EndLoc); 3436 break; 3437 case OMPD_section: 3438 assert(ClausesWithImplicit.empty() && 3439 "No clauses are allowed for 'omp section' directive"); 3440 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3441 break; 3442 case OMPD_single: 3443 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3444 EndLoc); 3445 break; 3446 case OMPD_master: 3447 assert(ClausesWithImplicit.empty() && 3448 "No clauses are allowed for 'omp master' directive"); 3449 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3450 break; 3451 case OMPD_critical: 3452 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3453 StartLoc, EndLoc); 3454 break; 3455 case OMPD_parallel_for: 3456 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3457 EndLoc, VarsWithInheritedDSA); 3458 AllowedNameModifiers.push_back(OMPD_parallel); 3459 break; 3460 case OMPD_parallel_for_simd: 3461 Res = ActOnOpenMPParallelForSimdDirective( 3462 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3463 AllowedNameModifiers.push_back(OMPD_parallel); 3464 break; 3465 case OMPD_parallel_sections: 3466 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3467 StartLoc, EndLoc); 3468 AllowedNameModifiers.push_back(OMPD_parallel); 3469 break; 3470 case OMPD_task: 3471 Res = 3472 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3473 AllowedNameModifiers.push_back(OMPD_task); 3474 break; 3475 case OMPD_taskyield: 3476 assert(ClausesWithImplicit.empty() && 3477 "No clauses are allowed for 'omp taskyield' directive"); 3478 assert(AStmt == nullptr && 3479 "No associated statement allowed for 'omp taskyield' directive"); 3480 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3481 break; 3482 case OMPD_barrier: 3483 assert(ClausesWithImplicit.empty() && 3484 "No clauses are allowed for 'omp barrier' directive"); 3485 assert(AStmt == nullptr && 3486 "No associated statement allowed for 'omp barrier' directive"); 3487 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3488 break; 3489 case OMPD_taskwait: 3490 assert(ClausesWithImplicit.empty() && 3491 "No clauses are allowed for 'omp taskwait' directive"); 3492 assert(AStmt == nullptr && 3493 "No associated statement allowed for 'omp taskwait' directive"); 3494 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3495 break; 3496 case OMPD_taskgroup: 3497 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 3498 EndLoc); 3499 break; 3500 case OMPD_flush: 3501 assert(AStmt == nullptr && 3502 "No associated statement allowed for 'omp flush' directive"); 3503 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3504 break; 3505 case OMPD_ordered: 3506 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3507 EndLoc); 3508 break; 3509 case OMPD_atomic: 3510 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3511 EndLoc); 3512 break; 3513 case OMPD_teams: 3514 Res = 3515 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3516 break; 3517 case OMPD_target: 3518 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3519 EndLoc); 3520 AllowedNameModifiers.push_back(OMPD_target); 3521 break; 3522 case OMPD_target_parallel: 3523 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3524 StartLoc, EndLoc); 3525 AllowedNameModifiers.push_back(OMPD_target); 3526 AllowedNameModifiers.push_back(OMPD_parallel); 3527 break; 3528 case OMPD_target_parallel_for: 3529 Res = ActOnOpenMPTargetParallelForDirective( 3530 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3531 AllowedNameModifiers.push_back(OMPD_target); 3532 AllowedNameModifiers.push_back(OMPD_parallel); 3533 break; 3534 case OMPD_cancellation_point: 3535 assert(ClausesWithImplicit.empty() && 3536 "No clauses are allowed for 'omp cancellation point' directive"); 3537 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3538 "cancellation point' directive"); 3539 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3540 break; 3541 case OMPD_cancel: 3542 assert(AStmt == nullptr && 3543 "No associated statement allowed for 'omp cancel' directive"); 3544 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3545 CancelRegion); 3546 AllowedNameModifiers.push_back(OMPD_cancel); 3547 break; 3548 case OMPD_target_data: 3549 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3550 EndLoc); 3551 AllowedNameModifiers.push_back(OMPD_target_data); 3552 break; 3553 case OMPD_target_enter_data: 3554 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3555 EndLoc, AStmt); 3556 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3557 break; 3558 case OMPD_target_exit_data: 3559 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3560 EndLoc, AStmt); 3561 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3562 break; 3563 case OMPD_taskloop: 3564 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3565 EndLoc, VarsWithInheritedDSA); 3566 AllowedNameModifiers.push_back(OMPD_taskloop); 3567 break; 3568 case OMPD_taskloop_simd: 3569 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3570 EndLoc, VarsWithInheritedDSA); 3571 AllowedNameModifiers.push_back(OMPD_taskloop); 3572 break; 3573 case OMPD_distribute: 3574 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3575 EndLoc, VarsWithInheritedDSA); 3576 break; 3577 case OMPD_target_update: 3578 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 3579 EndLoc, AStmt); 3580 AllowedNameModifiers.push_back(OMPD_target_update); 3581 break; 3582 case OMPD_distribute_parallel_for: 3583 Res = ActOnOpenMPDistributeParallelForDirective( 3584 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3585 AllowedNameModifiers.push_back(OMPD_parallel); 3586 break; 3587 case OMPD_distribute_parallel_for_simd: 3588 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3589 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3590 AllowedNameModifiers.push_back(OMPD_parallel); 3591 break; 3592 case OMPD_distribute_simd: 3593 Res = ActOnOpenMPDistributeSimdDirective( 3594 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3595 break; 3596 case OMPD_target_parallel_for_simd: 3597 Res = ActOnOpenMPTargetParallelForSimdDirective( 3598 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3599 AllowedNameModifiers.push_back(OMPD_target); 3600 AllowedNameModifiers.push_back(OMPD_parallel); 3601 break; 3602 case OMPD_target_simd: 3603 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3604 EndLoc, VarsWithInheritedDSA); 3605 AllowedNameModifiers.push_back(OMPD_target); 3606 break; 3607 case OMPD_teams_distribute: 3608 Res = ActOnOpenMPTeamsDistributeDirective( 3609 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3610 break; 3611 case OMPD_teams_distribute_simd: 3612 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3613 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3614 break; 3615 case OMPD_teams_distribute_parallel_for_simd: 3616 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3617 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3618 AllowedNameModifiers.push_back(OMPD_parallel); 3619 break; 3620 case OMPD_teams_distribute_parallel_for: 3621 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3622 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3623 AllowedNameModifiers.push_back(OMPD_parallel); 3624 break; 3625 case OMPD_target_teams: 3626 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3627 EndLoc); 3628 AllowedNameModifiers.push_back(OMPD_target); 3629 break; 3630 case OMPD_target_teams_distribute: 3631 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3632 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3633 AllowedNameModifiers.push_back(OMPD_target); 3634 break; 3635 case OMPD_target_teams_distribute_parallel_for: 3636 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3637 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3638 AllowedNameModifiers.push_back(OMPD_target); 3639 AllowedNameModifiers.push_back(OMPD_parallel); 3640 break; 3641 case OMPD_target_teams_distribute_parallel_for_simd: 3642 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3643 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3644 AllowedNameModifiers.push_back(OMPD_target); 3645 AllowedNameModifiers.push_back(OMPD_parallel); 3646 break; 3647 case OMPD_target_teams_distribute_simd: 3648 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3649 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3650 AllowedNameModifiers.push_back(OMPD_target); 3651 break; 3652 case OMPD_declare_target: 3653 case OMPD_end_declare_target: 3654 case OMPD_threadprivate: 3655 case OMPD_declare_reduction: 3656 case OMPD_declare_simd: 3657 case OMPD_requires: 3658 llvm_unreachable("OpenMP Directive is not allowed"); 3659 case OMPD_unknown: 3660 llvm_unreachable("Unknown OpenMP directive"); 3661 } 3662 3663 for (const auto &P : VarsWithInheritedDSA) { 3664 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3665 << P.first << P.second->getSourceRange(); 3666 } 3667 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3668 3669 if (!AllowedNameModifiers.empty()) 3670 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3671 ErrorFound; 3672 3673 if (ErrorFound) 3674 return StmtError(); 3675 return Res; 3676 } 3677 3678 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3679 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3680 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3681 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3682 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3683 assert(Aligneds.size() == Alignments.size()); 3684 assert(Linears.size() == LinModifiers.size()); 3685 assert(Linears.size() == Steps.size()); 3686 if (!DG || DG.get().isNull()) 3687 return DeclGroupPtrTy(); 3688 3689 if (!DG.get().isSingleDecl()) { 3690 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3691 return DG; 3692 } 3693 Decl *ADecl = DG.get().getSingleDecl(); 3694 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3695 ADecl = FTD->getTemplatedDecl(); 3696 3697 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3698 if (!FD) { 3699 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3700 return DeclGroupPtrTy(); 3701 } 3702 3703 // OpenMP [2.8.2, declare simd construct, Description] 3704 // The parameter of the simdlen clause must be a constant positive integer 3705 // expression. 3706 ExprResult SL; 3707 if (Simdlen) 3708 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3709 // OpenMP [2.8.2, declare simd construct, Description] 3710 // The special this pointer can be used as if was one of the arguments to the 3711 // function in any of the linear, aligned, or uniform clauses. 3712 // The uniform clause declares one or more arguments to have an invariant 3713 // value for all concurrent invocations of the function in the execution of a 3714 // single SIMD loop. 3715 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 3716 const Expr *UniformedLinearThis = nullptr; 3717 for (const Expr *E : Uniforms) { 3718 E = E->IgnoreParenImpCasts(); 3719 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3720 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3721 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3722 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3723 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3724 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 3725 continue; 3726 } 3727 if (isa<CXXThisExpr>(E)) { 3728 UniformedLinearThis = E; 3729 continue; 3730 } 3731 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3732 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3733 } 3734 // OpenMP [2.8.2, declare simd construct, Description] 3735 // The aligned clause declares that the object to which each list item points 3736 // is aligned to the number of bytes expressed in the optional parameter of 3737 // the aligned clause. 3738 // The special this pointer can be used as if was one of the arguments to the 3739 // function in any of the linear, aligned, or uniform clauses. 3740 // The type of list items appearing in the aligned clause must be array, 3741 // pointer, reference to array, or reference to pointer. 3742 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 3743 const Expr *AlignedThis = nullptr; 3744 for (const Expr *E : Aligneds) { 3745 E = E->IgnoreParenImpCasts(); 3746 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3747 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3748 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3749 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3750 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3751 ->getCanonicalDecl() == CanonPVD) { 3752 // OpenMP [2.8.1, simd construct, Restrictions] 3753 // A list-item cannot appear in more than one aligned clause. 3754 if (AlignedArgs.count(CanonPVD) > 0) { 3755 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3756 << 1 << E->getSourceRange(); 3757 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3758 diag::note_omp_explicit_dsa) 3759 << getOpenMPClauseName(OMPC_aligned); 3760 continue; 3761 } 3762 AlignedArgs[CanonPVD] = E; 3763 QualType QTy = PVD->getType() 3764 .getNonReferenceType() 3765 .getUnqualifiedType() 3766 .getCanonicalType(); 3767 const Type *Ty = QTy.getTypePtrOrNull(); 3768 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3769 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3770 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3771 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3772 } 3773 continue; 3774 } 3775 } 3776 if (isa<CXXThisExpr>(E)) { 3777 if (AlignedThis) { 3778 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3779 << 2 << E->getSourceRange(); 3780 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3781 << getOpenMPClauseName(OMPC_aligned); 3782 } 3783 AlignedThis = E; 3784 continue; 3785 } 3786 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3787 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3788 } 3789 // The optional parameter of the aligned clause, alignment, must be a constant 3790 // positive integer expression. If no optional parameter is specified, 3791 // implementation-defined default alignments for SIMD instructions on the 3792 // target platforms are assumed. 3793 SmallVector<const Expr *, 4> NewAligns; 3794 for (Expr *E : Alignments) { 3795 ExprResult Align; 3796 if (E) 3797 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3798 NewAligns.push_back(Align.get()); 3799 } 3800 // OpenMP [2.8.2, declare simd construct, Description] 3801 // The linear clause declares one or more list items to be private to a SIMD 3802 // lane and to have a linear relationship with respect to the iteration space 3803 // of a loop. 3804 // The special this pointer can be used as if was one of the arguments to the 3805 // function in any of the linear, aligned, or uniform clauses. 3806 // When a linear-step expression is specified in a linear clause it must be 3807 // either a constant integer expression or an integer-typed parameter that is 3808 // specified in a uniform clause on the directive. 3809 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 3810 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3811 auto MI = LinModifiers.begin(); 3812 for (const Expr *E : Linears) { 3813 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3814 ++MI; 3815 E = E->IgnoreParenImpCasts(); 3816 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3817 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3818 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3819 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3820 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3821 ->getCanonicalDecl() == CanonPVD) { 3822 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3823 // A list-item cannot appear in more than one linear clause. 3824 if (LinearArgs.count(CanonPVD) > 0) { 3825 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3826 << getOpenMPClauseName(OMPC_linear) 3827 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3828 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3829 diag::note_omp_explicit_dsa) 3830 << getOpenMPClauseName(OMPC_linear); 3831 continue; 3832 } 3833 // Each argument can appear in at most one uniform or linear clause. 3834 if (UniformedArgs.count(CanonPVD) > 0) { 3835 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3836 << getOpenMPClauseName(OMPC_linear) 3837 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3838 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3839 diag::note_omp_explicit_dsa) 3840 << getOpenMPClauseName(OMPC_uniform); 3841 continue; 3842 } 3843 LinearArgs[CanonPVD] = E; 3844 if (E->isValueDependent() || E->isTypeDependent() || 3845 E->isInstantiationDependent() || 3846 E->containsUnexpandedParameterPack()) 3847 continue; 3848 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 3849 PVD->getOriginalType()); 3850 continue; 3851 } 3852 } 3853 if (isa<CXXThisExpr>(E)) { 3854 if (UniformedLinearThis) { 3855 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3856 << getOpenMPClauseName(OMPC_linear) 3857 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 3858 << E->getSourceRange(); 3859 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 3860 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 3861 : OMPC_linear); 3862 continue; 3863 } 3864 UniformedLinearThis = E; 3865 if (E->isValueDependent() || E->isTypeDependent() || 3866 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 3867 continue; 3868 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 3869 E->getType()); 3870 continue; 3871 } 3872 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3873 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3874 } 3875 Expr *Step = nullptr; 3876 Expr *NewStep = nullptr; 3877 SmallVector<Expr *, 4> NewSteps; 3878 for (Expr *E : Steps) { 3879 // Skip the same step expression, it was checked already. 3880 if (Step == E || !E) { 3881 NewSteps.push_back(E ? NewStep : nullptr); 3882 continue; 3883 } 3884 Step = E; 3885 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 3886 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3887 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 3888 if (UniformedArgs.count(CanonPVD) == 0) { 3889 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 3890 << Step->getSourceRange(); 3891 } else if (E->isValueDependent() || E->isTypeDependent() || 3892 E->isInstantiationDependent() || 3893 E->containsUnexpandedParameterPack() || 3894 CanonPVD->getType()->hasIntegerRepresentation()) { 3895 NewSteps.push_back(Step); 3896 } else { 3897 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 3898 << Step->getSourceRange(); 3899 } 3900 continue; 3901 } 3902 NewStep = Step; 3903 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 3904 !Step->isInstantiationDependent() && 3905 !Step->containsUnexpandedParameterPack()) { 3906 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 3907 .get(); 3908 if (NewStep) 3909 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 3910 } 3911 NewSteps.push_back(NewStep); 3912 } 3913 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3914 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 3915 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 3916 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 3917 const_cast<Expr **>(Linears.data()), Linears.size(), 3918 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 3919 NewSteps.data(), NewSteps.size(), SR); 3920 ADecl->addAttr(NewAttr); 3921 return ConvertDeclToDeclGroup(ADecl); 3922 } 3923 3924 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3925 Stmt *AStmt, 3926 SourceLocation StartLoc, 3927 SourceLocation EndLoc) { 3928 if (!AStmt) 3929 return StmtError(); 3930 3931 auto *CS = cast<CapturedStmt>(AStmt); 3932 // 1.2.2 OpenMP Language Terminology 3933 // Structured block - An executable statement with a single entry at the 3934 // top and a single exit at the bottom. 3935 // The point of exit cannot be a branch out of the structured block. 3936 // longjmp() and throw() must not violate the entry/exit criteria. 3937 CS->getCapturedDecl()->setNothrow(); 3938 3939 setFunctionHasBranchProtectedScope(); 3940 3941 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3942 DSAStack->isCancelRegion()); 3943 } 3944 3945 namespace { 3946 /// Helper class for checking canonical form of the OpenMP loops and 3947 /// extracting iteration space of each loop in the loop nest, that will be used 3948 /// for IR generation. 3949 class OpenMPIterationSpaceChecker { 3950 /// Reference to Sema. 3951 Sema &SemaRef; 3952 /// A location for diagnostics (when there is no some better location). 3953 SourceLocation DefaultLoc; 3954 /// A location for diagnostics (when increment is not compatible). 3955 SourceLocation ConditionLoc; 3956 /// A source location for referring to loop init later. 3957 SourceRange InitSrcRange; 3958 /// A source location for referring to condition later. 3959 SourceRange ConditionSrcRange; 3960 /// A source location for referring to increment later. 3961 SourceRange IncrementSrcRange; 3962 /// Loop variable. 3963 ValueDecl *LCDecl = nullptr; 3964 /// Reference to loop variable. 3965 Expr *LCRef = nullptr; 3966 /// Lower bound (initializer for the var). 3967 Expr *LB = nullptr; 3968 /// Upper bound. 3969 Expr *UB = nullptr; 3970 /// Loop step (increment). 3971 Expr *Step = nullptr; 3972 /// This flag is true when condition is one of: 3973 /// Var < UB 3974 /// Var <= UB 3975 /// UB > Var 3976 /// UB >= Var 3977 /// This will have no value when the condition is != 3978 llvm::Optional<bool> TestIsLessOp; 3979 /// This flag is true when condition is strict ( < or > ). 3980 bool TestIsStrictOp = false; 3981 /// This flag is true when step is subtracted on each iteration. 3982 bool SubtractStep = false; 3983 3984 public: 3985 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3986 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3987 /// Check init-expr for canonical loop form and save loop counter 3988 /// variable - #Var and its initialization value - #LB. 3989 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 3990 /// Check test-expr for canonical form, save upper-bound (#UB), flags 3991 /// for less/greater and for strict/non-strict comparison. 3992 bool checkAndSetCond(Expr *S); 3993 /// Check incr-expr for canonical loop form and return true if it 3994 /// does not conform, otherwise save loop step (#Step). 3995 bool checkAndSetInc(Expr *S); 3996 /// Return the loop counter variable. 3997 ValueDecl *getLoopDecl() const { return LCDecl; } 3998 /// Return the reference expression to loop counter variable. 3999 Expr *getLoopDeclRefExpr() const { return LCRef; } 4000 /// Source range of the loop init. 4001 SourceRange getInitSrcRange() const { return InitSrcRange; } 4002 /// Source range of the loop condition. 4003 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4004 /// Source range of the loop increment. 4005 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4006 /// True if the step should be subtracted. 4007 bool shouldSubtractStep() const { return SubtractStep; } 4008 /// Build the expression to calculate the number of iterations. 4009 Expr *buildNumIterations( 4010 Scope *S, const bool LimitedType, 4011 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4012 /// Build the precondition expression for the loops. 4013 Expr * 4014 buildPreCond(Scope *S, Expr *Cond, 4015 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4016 /// Build reference expression to the counter be used for codegen. 4017 DeclRefExpr * 4018 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4019 DSAStackTy &DSA) const; 4020 /// Build reference expression to the private counter be used for 4021 /// codegen. 4022 Expr *buildPrivateCounterVar() const; 4023 /// Build initialization of the counter be used for codegen. 4024 Expr *buildCounterInit() const; 4025 /// Build step of the counter be used for codegen. 4026 Expr *buildCounterStep() const; 4027 /// Build loop data with counter value for depend clauses in ordered 4028 /// directives. 4029 Expr * 4030 buildOrderedLoopData(Scope *S, Expr *Counter, 4031 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4032 SourceLocation Loc, Expr *Inc = nullptr, 4033 OverloadedOperatorKind OOK = OO_Amp); 4034 /// Return true if any expression is dependent. 4035 bool dependent() const; 4036 4037 private: 4038 /// Check the right-hand side of an assignment in the increment 4039 /// expression. 4040 bool checkAndSetIncRHS(Expr *RHS); 4041 /// Helper to set loop counter variable and its initializer. 4042 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 4043 /// Helper to set upper bound. 4044 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4045 SourceRange SR, SourceLocation SL); 4046 /// Helper to set loop increment. 4047 bool setStep(Expr *NewStep, bool Subtract); 4048 }; 4049 4050 bool OpenMPIterationSpaceChecker::dependent() const { 4051 if (!LCDecl) { 4052 assert(!LB && !UB && !Step); 4053 return false; 4054 } 4055 return LCDecl->getType()->isDependentType() || 4056 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4057 (Step && Step->isValueDependent()); 4058 } 4059 4060 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4061 Expr *NewLCRefExpr, 4062 Expr *NewLB) { 4063 // State consistency checking to ensure correct usage. 4064 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4065 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4066 if (!NewLCDecl || !NewLB) 4067 return true; 4068 LCDecl = getCanonicalDecl(NewLCDecl); 4069 LCRef = NewLCRefExpr; 4070 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4071 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4072 if ((Ctor->isCopyOrMoveConstructor() || 4073 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4074 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4075 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4076 LB = NewLB; 4077 return false; 4078 } 4079 4080 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, llvm::Optional<bool> LessOp, 4081 bool StrictOp, SourceRange SR, 4082 SourceLocation SL) { 4083 // State consistency checking to ensure correct usage. 4084 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4085 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4086 if (!NewUB) 4087 return true; 4088 UB = NewUB; 4089 if (LessOp) 4090 TestIsLessOp = LessOp; 4091 TestIsStrictOp = StrictOp; 4092 ConditionSrcRange = SR; 4093 ConditionLoc = SL; 4094 return false; 4095 } 4096 4097 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4098 // State consistency checking to ensure correct usage. 4099 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4100 if (!NewStep) 4101 return true; 4102 if (!NewStep->isValueDependent()) { 4103 // Check that the step is integer expression. 4104 SourceLocation StepLoc = NewStep->getBeginLoc(); 4105 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4106 StepLoc, getExprAsWritten(NewStep)); 4107 if (Val.isInvalid()) 4108 return true; 4109 NewStep = Val.get(); 4110 4111 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4112 // If test-expr is of form var relational-op b and relational-op is < or 4113 // <= then incr-expr must cause var to increase on each iteration of the 4114 // loop. If test-expr is of form var relational-op b and relational-op is 4115 // > or >= then incr-expr must cause var to decrease on each iteration of 4116 // the loop. 4117 // If test-expr is of form b relational-op var and relational-op is < or 4118 // <= then incr-expr must cause var to decrease on each iteration of the 4119 // loop. If test-expr is of form b relational-op var and relational-op is 4120 // > or >= then incr-expr must cause var to increase on each iteration of 4121 // the loop. 4122 llvm::APSInt Result; 4123 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4124 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4125 bool IsConstNeg = 4126 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4127 bool IsConstPos = 4128 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4129 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4130 4131 // != with increment is treated as <; != with decrement is treated as > 4132 if (!TestIsLessOp.hasValue()) 4133 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4134 if (UB && (IsConstZero || 4135 (TestIsLessOp.getValue() ? 4136 (IsConstNeg || (IsUnsigned && Subtract)) : 4137 (IsConstPos || (IsUnsigned && !Subtract))))) { 4138 SemaRef.Diag(NewStep->getExprLoc(), 4139 diag::err_omp_loop_incr_not_compatible) 4140 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4141 SemaRef.Diag(ConditionLoc, 4142 diag::note_omp_loop_cond_requres_compatible_incr) 4143 << TestIsLessOp.getValue() << ConditionSrcRange; 4144 return true; 4145 } 4146 if (TestIsLessOp.getValue() == Subtract) { 4147 NewStep = 4148 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4149 .get(); 4150 Subtract = !Subtract; 4151 } 4152 } 4153 4154 Step = NewStep; 4155 SubtractStep = Subtract; 4156 return false; 4157 } 4158 4159 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 4160 // Check init-expr for canonical loop form and save loop counter 4161 // variable - #Var and its initialization value - #LB. 4162 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 4163 // var = lb 4164 // integer-type var = lb 4165 // random-access-iterator-type var = lb 4166 // pointer-type var = lb 4167 // 4168 if (!S) { 4169 if (EmitDiags) { 4170 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 4171 } 4172 return true; 4173 } 4174 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4175 if (!ExprTemp->cleanupsHaveSideEffects()) 4176 S = ExprTemp->getSubExpr(); 4177 4178 InitSrcRange = S->getSourceRange(); 4179 if (Expr *E = dyn_cast<Expr>(S)) 4180 S = E->IgnoreParens(); 4181 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4182 if (BO->getOpcode() == BO_Assign) { 4183 Expr *LHS = BO->getLHS()->IgnoreParens(); 4184 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4185 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4186 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4187 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4188 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 4189 } 4190 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4191 if (ME->isArrow() && 4192 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4193 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4194 } 4195 } 4196 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4197 if (DS->isSingleDecl()) { 4198 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4199 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4200 // Accept non-canonical init form here but emit ext. warning. 4201 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4202 SemaRef.Diag(S->getBeginLoc(), 4203 diag::ext_omp_loop_not_canonical_init) 4204 << S->getSourceRange(); 4205 return setLCDeclAndLB( 4206 Var, 4207 buildDeclRefExpr(SemaRef, Var, 4208 Var->getType().getNonReferenceType(), 4209 DS->getBeginLoc()), 4210 Var->getInit()); 4211 } 4212 } 4213 } 4214 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4215 if (CE->getOperator() == OO_Equal) { 4216 Expr *LHS = CE->getArg(0); 4217 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4218 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4219 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4220 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4221 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 4222 } 4223 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4224 if (ME->isArrow() && 4225 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4226 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4227 } 4228 } 4229 } 4230 4231 if (dependent() || SemaRef.CurContext->isDependentContext()) 4232 return false; 4233 if (EmitDiags) { 4234 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 4235 << S->getSourceRange(); 4236 } 4237 return true; 4238 } 4239 4240 /// Ignore parenthesizes, implicit casts, copy constructor and return the 4241 /// variable (which may be the loop variable) if possible. 4242 static const ValueDecl *getInitLCDecl(const Expr *E) { 4243 if (!E) 4244 return nullptr; 4245 E = getExprAsWritten(E); 4246 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 4247 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4248 if ((Ctor->isCopyOrMoveConstructor() || 4249 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4250 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4251 E = CE->getArg(0)->IgnoreParenImpCasts(); 4252 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 4253 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 4254 return getCanonicalDecl(VD); 4255 } 4256 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 4257 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4258 return getCanonicalDecl(ME->getMemberDecl()); 4259 return nullptr; 4260 } 4261 4262 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 4263 // Check test-expr for canonical form, save upper-bound UB, flags for 4264 // less/greater and for strict/non-strict comparison. 4265 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4266 // var relational-op b 4267 // b relational-op var 4268 // 4269 if (!S) { 4270 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 4271 return true; 4272 } 4273 S = getExprAsWritten(S); 4274 SourceLocation CondLoc = S->getBeginLoc(); 4275 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4276 if (BO->isRelationalOp()) { 4277 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4278 return setUB(BO->getRHS(), 4279 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4280 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4281 BO->getSourceRange(), BO->getOperatorLoc()); 4282 if (getInitLCDecl(BO->getRHS()) == LCDecl) 4283 return setUB(BO->getLHS(), 4284 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4285 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4286 BO->getSourceRange(), BO->getOperatorLoc()); 4287 } else if (BO->getOpcode() == BO_NE) 4288 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 4289 BO->getRHS() : BO->getLHS(), 4290 /*LessOp=*/llvm::None, 4291 /*StrictOp=*/true, 4292 BO->getSourceRange(), BO->getOperatorLoc()); 4293 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4294 if (CE->getNumArgs() == 2) { 4295 auto Op = CE->getOperator(); 4296 switch (Op) { 4297 case OO_Greater: 4298 case OO_GreaterEqual: 4299 case OO_Less: 4300 case OO_LessEqual: 4301 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4302 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4303 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4304 CE->getOperatorLoc()); 4305 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 4306 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4307 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4308 CE->getOperatorLoc()); 4309 break; 4310 case OO_ExclaimEqual: 4311 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 4312 CE->getArg(1) : CE->getArg(0), 4313 /*LessOp=*/llvm::None, 4314 /*StrictOp=*/true, 4315 CE->getSourceRange(), 4316 CE->getOperatorLoc()); 4317 break; 4318 default: 4319 break; 4320 } 4321 } 4322 } 4323 if (dependent() || SemaRef.CurContext->isDependentContext()) 4324 return false; 4325 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4326 << S->getSourceRange() << LCDecl; 4327 return true; 4328 } 4329 4330 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 4331 // RHS of canonical loop form increment can be: 4332 // var + incr 4333 // incr + var 4334 // var - incr 4335 // 4336 RHS = RHS->IgnoreParenImpCasts(); 4337 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 4338 if (BO->isAdditiveOp()) { 4339 bool IsAdd = BO->getOpcode() == BO_Add; 4340 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4341 return setStep(BO->getRHS(), !IsAdd); 4342 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 4343 return setStep(BO->getLHS(), /*Subtract=*/false); 4344 } 4345 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 4346 bool IsAdd = CE->getOperator() == OO_Plus; 4347 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 4348 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4349 return setStep(CE->getArg(1), !IsAdd); 4350 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 4351 return setStep(CE->getArg(0), /*Subtract=*/false); 4352 } 4353 } 4354 if (dependent() || SemaRef.CurContext->isDependentContext()) 4355 return false; 4356 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4357 << RHS->getSourceRange() << LCDecl; 4358 return true; 4359 } 4360 4361 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 4362 // Check incr-expr for canonical loop form and return true if it 4363 // does not conform. 4364 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4365 // ++var 4366 // var++ 4367 // --var 4368 // var-- 4369 // var += incr 4370 // var -= incr 4371 // var = var + incr 4372 // var = incr + var 4373 // var = var - incr 4374 // 4375 if (!S) { 4376 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 4377 return true; 4378 } 4379 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4380 if (!ExprTemp->cleanupsHaveSideEffects()) 4381 S = ExprTemp->getSubExpr(); 4382 4383 IncrementSrcRange = S->getSourceRange(); 4384 S = S->IgnoreParens(); 4385 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 4386 if (UO->isIncrementDecrementOp() && 4387 getInitLCDecl(UO->getSubExpr()) == LCDecl) 4388 return setStep(SemaRef 4389 .ActOnIntegerConstant(UO->getBeginLoc(), 4390 (UO->isDecrementOp() ? -1 : 1)) 4391 .get(), 4392 /*Subtract=*/false); 4393 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4394 switch (BO->getOpcode()) { 4395 case BO_AddAssign: 4396 case BO_SubAssign: 4397 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4398 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4399 break; 4400 case BO_Assign: 4401 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4402 return checkAndSetIncRHS(BO->getRHS()); 4403 break; 4404 default: 4405 break; 4406 } 4407 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4408 switch (CE->getOperator()) { 4409 case OO_PlusPlus: 4410 case OO_MinusMinus: 4411 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4412 return setStep(SemaRef 4413 .ActOnIntegerConstant( 4414 CE->getBeginLoc(), 4415 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 4416 .get(), 4417 /*Subtract=*/false); 4418 break; 4419 case OO_PlusEqual: 4420 case OO_MinusEqual: 4421 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4422 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4423 break; 4424 case OO_Equal: 4425 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4426 return checkAndSetIncRHS(CE->getArg(1)); 4427 break; 4428 default: 4429 break; 4430 } 4431 } 4432 if (dependent() || SemaRef.CurContext->isDependentContext()) 4433 return false; 4434 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4435 << S->getSourceRange() << LCDecl; 4436 return true; 4437 } 4438 4439 static ExprResult 4440 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4441 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4442 if (SemaRef.CurContext->isDependentContext()) 4443 return ExprResult(Capture); 4444 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4445 return SemaRef.PerformImplicitConversion( 4446 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4447 /*AllowExplicit=*/true); 4448 auto I = Captures.find(Capture); 4449 if (I != Captures.end()) 4450 return buildCapture(SemaRef, Capture, I->second); 4451 DeclRefExpr *Ref = nullptr; 4452 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4453 Captures[Capture] = Ref; 4454 return Res; 4455 } 4456 4457 /// Build the expression to calculate the number of iterations. 4458 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 4459 Scope *S, const bool LimitedType, 4460 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4461 ExprResult Diff; 4462 QualType VarType = LCDecl->getType().getNonReferenceType(); 4463 if (VarType->isIntegerType() || VarType->isPointerType() || 4464 SemaRef.getLangOpts().CPlusPlus) { 4465 // Upper - Lower 4466 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 4467 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 4468 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4469 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4470 if (!Upper || !Lower) 4471 return nullptr; 4472 4473 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4474 4475 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4476 // BuildBinOp already emitted error, this one is to point user to upper 4477 // and lower bound, and to tell what is passed to 'operator-'. 4478 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4479 << Upper->getSourceRange() << Lower->getSourceRange(); 4480 return nullptr; 4481 } 4482 } 4483 4484 if (!Diff.isUsable()) 4485 return nullptr; 4486 4487 // Upper - Lower [- 1] 4488 if (TestIsStrictOp) 4489 Diff = SemaRef.BuildBinOp( 4490 S, DefaultLoc, BO_Sub, Diff.get(), 4491 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4492 if (!Diff.isUsable()) 4493 return nullptr; 4494 4495 // Upper - Lower [- 1] + Step 4496 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4497 if (!NewStep.isUsable()) 4498 return nullptr; 4499 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4500 if (!Diff.isUsable()) 4501 return nullptr; 4502 4503 // Parentheses (for dumping/debugging purposes only). 4504 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4505 if (!Diff.isUsable()) 4506 return nullptr; 4507 4508 // (Upper - Lower [- 1] + Step) / Step 4509 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4510 if (!Diff.isUsable()) 4511 return nullptr; 4512 4513 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4514 QualType Type = Diff.get()->getType(); 4515 ASTContext &C = SemaRef.Context; 4516 bool UseVarType = VarType->hasIntegerRepresentation() && 4517 C.getTypeSize(Type) > C.getTypeSize(VarType); 4518 if (!Type->isIntegerType() || UseVarType) { 4519 unsigned NewSize = 4520 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4521 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4522 : Type->hasSignedIntegerRepresentation(); 4523 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4524 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4525 Diff = SemaRef.PerformImplicitConversion( 4526 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4527 if (!Diff.isUsable()) 4528 return nullptr; 4529 } 4530 } 4531 if (LimitedType) { 4532 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4533 if (NewSize != C.getTypeSize(Type)) { 4534 if (NewSize < C.getTypeSize(Type)) { 4535 assert(NewSize == 64 && "incorrect loop var size"); 4536 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4537 << InitSrcRange << ConditionSrcRange; 4538 } 4539 QualType NewType = C.getIntTypeForBitwidth( 4540 NewSize, Type->hasSignedIntegerRepresentation() || 4541 C.getTypeSize(Type) < NewSize); 4542 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4543 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4544 Sema::AA_Converting, true); 4545 if (!Diff.isUsable()) 4546 return nullptr; 4547 } 4548 } 4549 } 4550 4551 return Diff.get(); 4552 } 4553 4554 Expr *OpenMPIterationSpaceChecker::buildPreCond( 4555 Scope *S, Expr *Cond, 4556 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4557 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4558 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4559 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4560 4561 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 4562 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 4563 if (!NewLB.isUsable() || !NewUB.isUsable()) 4564 return nullptr; 4565 4566 ExprResult CondExpr = 4567 SemaRef.BuildBinOp(S, DefaultLoc, 4568 TestIsLessOp.getValue() ? 4569 (TestIsStrictOp ? BO_LT : BO_LE) : 4570 (TestIsStrictOp ? BO_GT : BO_GE), 4571 NewLB.get(), NewUB.get()); 4572 if (CondExpr.isUsable()) { 4573 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4574 SemaRef.Context.BoolTy)) 4575 CondExpr = SemaRef.PerformImplicitConversion( 4576 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4577 /*AllowExplicit=*/true); 4578 } 4579 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4580 // Otherwise use original loop conditon and evaluate it in runtime. 4581 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4582 } 4583 4584 /// Build reference expression to the counter be used for codegen. 4585 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 4586 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4587 DSAStackTy &DSA) const { 4588 auto *VD = dyn_cast<VarDecl>(LCDecl); 4589 if (!VD) { 4590 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 4591 DeclRefExpr *Ref = buildDeclRefExpr( 4592 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4593 const DSAStackTy::DSAVarData Data = 4594 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4595 // If the loop control decl is explicitly marked as private, do not mark it 4596 // as captured again. 4597 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4598 Captures.insert(std::make_pair(LCRef, Ref)); 4599 return Ref; 4600 } 4601 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 4602 DefaultLoc); 4603 } 4604 4605 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 4606 if (LCDecl && !LCDecl->isInvalidDecl()) { 4607 QualType Type = LCDecl->getType().getNonReferenceType(); 4608 VarDecl *PrivateVar = buildVarDecl( 4609 SemaRef, DefaultLoc, Type, LCDecl->getName(), 4610 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 4611 isa<VarDecl>(LCDecl) 4612 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 4613 : nullptr); 4614 if (PrivateVar->isInvalidDecl()) 4615 return nullptr; 4616 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4617 } 4618 return nullptr; 4619 } 4620 4621 /// Build initialization of the counter to be used for codegen. 4622 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 4623 4624 /// Build step of the counter be used for codegen. 4625 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 4626 4627 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 4628 Scope *S, Expr *Counter, 4629 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 4630 Expr *Inc, OverloadedOperatorKind OOK) { 4631 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 4632 if (!Cnt) 4633 return nullptr; 4634 if (Inc) { 4635 assert((OOK == OO_Plus || OOK == OO_Minus) && 4636 "Expected only + or - operations for depend clauses."); 4637 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 4638 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 4639 if (!Cnt) 4640 return nullptr; 4641 } 4642 ExprResult Diff; 4643 QualType VarType = LCDecl->getType().getNonReferenceType(); 4644 if (VarType->isIntegerType() || VarType->isPointerType() || 4645 SemaRef.getLangOpts().CPlusPlus) { 4646 // Upper - Lower 4647 Expr *Upper = 4648 TestIsLessOp.getValue() ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get(); 4649 Expr *Lower = 4650 TestIsLessOp.getValue() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; 4651 if (!Upper || !Lower) 4652 return nullptr; 4653 4654 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4655 4656 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4657 // BuildBinOp already emitted error, this one is to point user to upper 4658 // and lower bound, and to tell what is passed to 'operator-'. 4659 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4660 << Upper->getSourceRange() << Lower->getSourceRange(); 4661 return nullptr; 4662 } 4663 } 4664 4665 if (!Diff.isUsable()) 4666 return nullptr; 4667 4668 // Parentheses (for dumping/debugging purposes only). 4669 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4670 if (!Diff.isUsable()) 4671 return nullptr; 4672 4673 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4674 if (!NewStep.isUsable()) 4675 return nullptr; 4676 // (Upper - Lower) / Step 4677 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4678 if (!Diff.isUsable()) 4679 return nullptr; 4680 4681 return Diff.get(); 4682 } 4683 4684 /// Iteration space of a single for loop. 4685 struct LoopIterationSpace final { 4686 /// Condition of the loop. 4687 Expr *PreCond = nullptr; 4688 /// This expression calculates the number of iterations in the loop. 4689 /// It is always possible to calculate it before starting the loop. 4690 Expr *NumIterations = nullptr; 4691 /// The loop counter variable. 4692 Expr *CounterVar = nullptr; 4693 /// Private loop counter variable. 4694 Expr *PrivateCounterVar = nullptr; 4695 /// This is initializer for the initial value of #CounterVar. 4696 Expr *CounterInit = nullptr; 4697 /// This is step for the #CounterVar used to generate its update: 4698 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4699 Expr *CounterStep = nullptr; 4700 /// Should step be subtracted? 4701 bool Subtract = false; 4702 /// Source range of the loop init. 4703 SourceRange InitSrcRange; 4704 /// Source range of the loop condition. 4705 SourceRange CondSrcRange; 4706 /// Source range of the loop increment. 4707 SourceRange IncSrcRange; 4708 }; 4709 4710 } // namespace 4711 4712 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4713 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4714 assert(Init && "Expected loop in canonical form."); 4715 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4716 if (AssociatedLoops > 0 && 4717 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4718 DSAStack->loopStart(); 4719 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4720 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 4721 if (ValueDecl *D = ISC.getLoopDecl()) { 4722 auto *VD = dyn_cast<VarDecl>(D); 4723 if (!VD) { 4724 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 4725 VD = Private; 4726 } else { 4727 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 4728 /*WithInit=*/false); 4729 VD = cast<VarDecl>(Ref->getDecl()); 4730 } 4731 } 4732 DSAStack->addLoopControlVariable(D, VD); 4733 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 4734 if (LD != D->getCanonicalDecl()) { 4735 DSAStack->resetPossibleLoopCounter(); 4736 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 4737 MarkDeclarationsReferencedInExpr( 4738 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 4739 Var->getType().getNonLValueExprType(Context), 4740 ForLoc, /*RefersToCapture=*/true)); 4741 } 4742 } 4743 } 4744 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4745 } 4746 } 4747 4748 /// Called on a for stmt to check and extract its iteration space 4749 /// for further processing (such as collapsing). 4750 static bool checkOpenMPIterationSpace( 4751 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4752 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4753 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 4754 Expr *OrderedLoopCountExpr, 4755 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 4756 LoopIterationSpace &ResultIterSpace, 4757 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4758 // OpenMP [2.6, Canonical Loop Form] 4759 // for (init-expr; test-expr; incr-expr) structured-block 4760 auto *For = dyn_cast_or_null<ForStmt>(S); 4761 if (!For) { 4762 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 4763 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4764 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 4765 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4766 if (TotalNestedLoopCount > 1) { 4767 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4768 SemaRef.Diag(DSA.getConstructLoc(), 4769 diag::note_omp_collapse_ordered_expr) 4770 << 2 << CollapseLoopCountExpr->getSourceRange() 4771 << OrderedLoopCountExpr->getSourceRange(); 4772 else if (CollapseLoopCountExpr) 4773 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4774 diag::note_omp_collapse_ordered_expr) 4775 << 0 << CollapseLoopCountExpr->getSourceRange(); 4776 else 4777 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4778 diag::note_omp_collapse_ordered_expr) 4779 << 1 << OrderedLoopCountExpr->getSourceRange(); 4780 } 4781 return true; 4782 } 4783 assert(For->getBody()); 4784 4785 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4786 4787 // Check init. 4788 Stmt *Init = For->getInit(); 4789 if (ISC.checkAndSetInit(Init)) 4790 return true; 4791 4792 bool HasErrors = false; 4793 4794 // Check loop variable's type. 4795 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 4796 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 4797 4798 // OpenMP [2.6, Canonical Loop Form] 4799 // Var is one of the following: 4800 // A variable of signed or unsigned integer type. 4801 // For C++, a variable of a random access iterator type. 4802 // For C, a variable of a pointer type. 4803 QualType VarType = LCDecl->getType().getNonReferenceType(); 4804 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4805 !VarType->isPointerType() && 4806 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4807 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 4808 << SemaRef.getLangOpts().CPlusPlus; 4809 HasErrors = true; 4810 } 4811 4812 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4813 // a Construct 4814 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4815 // parallel for construct is (are) private. 4816 // The loop iteration variable in the associated for-loop of a simd 4817 // construct with just one associated for-loop is linear with a 4818 // constant-linear-step that is the increment of the associated for-loop. 4819 // Exclude loop var from the list of variables with implicitly defined data 4820 // sharing attributes. 4821 VarsWithImplicitDSA.erase(LCDecl); 4822 4823 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4824 // in a Construct, C/C++]. 4825 // The loop iteration variable in the associated for-loop of a simd 4826 // construct with just one associated for-loop may be listed in a linear 4827 // clause with a constant-linear-step that is the increment of the 4828 // associated for-loop. 4829 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4830 // parallel for construct may be listed in a private or lastprivate clause. 4831 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4832 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4833 // declared in the loop and it is predetermined as a private. 4834 OpenMPClauseKind PredeterminedCKind = 4835 isOpenMPSimdDirective(DKind) 4836 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4837 : OMPC_private; 4838 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4839 DVar.CKind != PredeterminedCKind) || 4840 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4841 isOpenMPDistributeDirective(DKind)) && 4842 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4843 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4844 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4845 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 4846 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4847 << getOpenMPClauseName(PredeterminedCKind); 4848 if (DVar.RefExpr == nullptr) 4849 DVar.CKind = PredeterminedCKind; 4850 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4851 HasErrors = true; 4852 } else if (LoopDeclRefExpr != nullptr) { 4853 // Make the loop iteration variable private (for worksharing constructs), 4854 // linear (for simd directives with the only one associated loop) or 4855 // lastprivate (for simd directives with several collapsed or ordered 4856 // loops). 4857 if (DVar.CKind == OMPC_unknown) 4858 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 4859 [](OpenMPDirectiveKind) -> bool { return true; }, 4860 /*FromParent=*/false); 4861 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4862 } 4863 4864 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4865 4866 // Check test-expr. 4867 HasErrors |= ISC.checkAndSetCond(For->getCond()); 4868 4869 // Check incr-expr. 4870 HasErrors |= ISC.checkAndSetInc(For->getInc()); 4871 } 4872 4873 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4874 return HasErrors; 4875 4876 // Build the loop's iteration space representation. 4877 ResultIterSpace.PreCond = 4878 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4879 ResultIterSpace.NumIterations = ISC.buildNumIterations( 4880 DSA.getCurScope(), 4881 (isOpenMPWorksharingDirective(DKind) || 4882 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4883 Captures); 4884 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 4885 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 4886 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 4887 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 4888 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 4889 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 4890 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 4891 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 4892 4893 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4894 ResultIterSpace.NumIterations == nullptr || 4895 ResultIterSpace.CounterVar == nullptr || 4896 ResultIterSpace.PrivateCounterVar == nullptr || 4897 ResultIterSpace.CounterInit == nullptr || 4898 ResultIterSpace.CounterStep == nullptr); 4899 if (!HasErrors && DSA.isOrderedRegion()) { 4900 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 4901 if (CurrentNestedLoopCount < 4902 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 4903 DSA.getOrderedRegionParam().second->setLoopNumIterations( 4904 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 4905 DSA.getOrderedRegionParam().second->setLoopCounter( 4906 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 4907 } 4908 } 4909 for (auto &Pair : DSA.getDoacrossDependClauses()) { 4910 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 4911 // Erroneous case - clause has some problems. 4912 continue; 4913 } 4914 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 4915 Pair.second.size() <= CurrentNestedLoopCount) { 4916 // Erroneous case - clause has some problems. 4917 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 4918 continue; 4919 } 4920 Expr *CntValue; 4921 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 4922 CntValue = ISC.buildOrderedLoopData( 4923 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 4924 Pair.first->getDependencyLoc()); 4925 else 4926 CntValue = ISC.buildOrderedLoopData( 4927 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 4928 Pair.first->getDependencyLoc(), 4929 Pair.second[CurrentNestedLoopCount].first, 4930 Pair.second[CurrentNestedLoopCount].second); 4931 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 4932 } 4933 } 4934 4935 return HasErrors; 4936 } 4937 4938 /// Build 'VarRef = Start. 4939 static ExprResult 4940 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4941 ExprResult Start, 4942 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4943 // Build 'VarRef = Start. 4944 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4945 if (!NewStart.isUsable()) 4946 return ExprError(); 4947 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4948 VarRef.get()->getType())) { 4949 NewStart = SemaRef.PerformImplicitConversion( 4950 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4951 /*AllowExplicit=*/true); 4952 if (!NewStart.isUsable()) 4953 return ExprError(); 4954 } 4955 4956 ExprResult Init = 4957 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4958 return Init; 4959 } 4960 4961 /// Build 'VarRef = Start + Iter * Step'. 4962 static ExprResult buildCounterUpdate( 4963 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4964 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 4965 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 4966 // Add parentheses (for debugging purposes only). 4967 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4968 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4969 !Step.isUsable()) 4970 return ExprError(); 4971 4972 ExprResult NewStep = Step; 4973 if (Captures) 4974 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4975 if (NewStep.isInvalid()) 4976 return ExprError(); 4977 ExprResult Update = 4978 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4979 if (!Update.isUsable()) 4980 return ExprError(); 4981 4982 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4983 // 'VarRef = Start (+|-) Iter * Step'. 4984 ExprResult NewStart = Start; 4985 if (Captures) 4986 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4987 if (NewStart.isInvalid()) 4988 return ExprError(); 4989 4990 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4991 ExprResult SavedUpdate = Update; 4992 ExprResult UpdateVal; 4993 if (VarRef.get()->getType()->isOverloadableType() || 4994 NewStart.get()->getType()->isOverloadableType() || 4995 Update.get()->getType()->isOverloadableType()) { 4996 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4997 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4998 Update = 4999 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5000 if (Update.isUsable()) { 5001 UpdateVal = 5002 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5003 VarRef.get(), SavedUpdate.get()); 5004 if (UpdateVal.isUsable()) { 5005 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5006 UpdateVal.get()); 5007 } 5008 } 5009 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5010 } 5011 5012 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5013 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5014 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5015 NewStart.get(), SavedUpdate.get()); 5016 if (!Update.isUsable()) 5017 return ExprError(); 5018 5019 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5020 VarRef.get()->getType())) { 5021 Update = SemaRef.PerformImplicitConversion( 5022 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5023 if (!Update.isUsable()) 5024 return ExprError(); 5025 } 5026 5027 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5028 } 5029 return Update; 5030 } 5031 5032 /// Convert integer expression \a E to make it have at least \a Bits 5033 /// bits. 5034 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5035 if (E == nullptr) 5036 return ExprError(); 5037 ASTContext &C = SemaRef.Context; 5038 QualType OldType = E->getType(); 5039 unsigned HasBits = C.getTypeSize(OldType); 5040 if (HasBits >= Bits) 5041 return ExprResult(E); 5042 // OK to convert to signed, because new type has more bits than old. 5043 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5044 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5045 true); 5046 } 5047 5048 /// Check if the given expression \a E is a constant integer that fits 5049 /// into \a Bits bits. 5050 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5051 if (E == nullptr) 5052 return false; 5053 llvm::APSInt Result; 5054 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5055 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5056 return false; 5057 } 5058 5059 /// Build preinits statement for the given declarations. 5060 static Stmt *buildPreInits(ASTContext &Context, 5061 MutableArrayRef<Decl *> PreInits) { 5062 if (!PreInits.empty()) { 5063 return new (Context) DeclStmt( 5064 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5065 SourceLocation(), SourceLocation()); 5066 } 5067 return nullptr; 5068 } 5069 5070 /// Build preinits statement for the given declarations. 5071 static Stmt * 5072 buildPreInits(ASTContext &Context, 5073 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5074 if (!Captures.empty()) { 5075 SmallVector<Decl *, 16> PreInits; 5076 for (const auto &Pair : Captures) 5077 PreInits.push_back(Pair.second->getDecl()); 5078 return buildPreInits(Context, PreInits); 5079 } 5080 return nullptr; 5081 } 5082 5083 /// Build postupdate expression for the given list of postupdates expressions. 5084 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5085 Expr *PostUpdate = nullptr; 5086 if (!PostUpdates.empty()) { 5087 for (Expr *E : PostUpdates) { 5088 Expr *ConvE = S.BuildCStyleCastExpr( 5089 E->getExprLoc(), 5090 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5091 E->getExprLoc(), E) 5092 .get(); 5093 PostUpdate = PostUpdate 5094 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5095 PostUpdate, ConvE) 5096 .get() 5097 : ConvE; 5098 } 5099 } 5100 return PostUpdate; 5101 } 5102 5103 /// Called on a for stmt to check itself and nested loops (if any). 5104 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5105 /// number of collapsed loops otherwise. 5106 static unsigned 5107 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5108 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5109 DSAStackTy &DSA, 5110 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5111 OMPLoopDirective::HelperExprs &Built) { 5112 unsigned NestedLoopCount = 1; 5113 if (CollapseLoopCountExpr) { 5114 // Found 'collapse' clause - calculate collapse number. 5115 Expr::EvalResult Result; 5116 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 5117 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5118 } 5119 unsigned OrderedLoopCount = 1; 5120 if (OrderedLoopCountExpr) { 5121 // Found 'ordered' clause - calculate collapse number. 5122 Expr::EvalResult EVResult; 5123 if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { 5124 llvm::APSInt Result = EVResult.Val.getInt(); 5125 if (Result.getLimitedValue() < NestedLoopCount) { 5126 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5127 diag::err_omp_wrong_ordered_loop_count) 5128 << OrderedLoopCountExpr->getSourceRange(); 5129 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5130 diag::note_collapse_loop_count) 5131 << CollapseLoopCountExpr->getSourceRange(); 5132 } 5133 OrderedLoopCount = Result.getLimitedValue(); 5134 } 5135 } 5136 // This is helper routine for loop directives (e.g., 'for', 'simd', 5137 // 'for simd', etc.). 5138 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 5139 SmallVector<LoopIterationSpace, 4> IterSpaces; 5140 IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount)); 5141 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 5142 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5143 if (checkOpenMPIterationSpace( 5144 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5145 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5146 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5147 Captures)) 5148 return 0; 5149 // Move on to the next nested for loop, or to the loop body. 5150 // OpenMP [2.8.1, simd construct, Restrictions] 5151 // All loops associated with the construct must be perfectly nested; that 5152 // is, there must be no intervening code nor any OpenMP directive between 5153 // any two loops. 5154 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5155 } 5156 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 5157 if (checkOpenMPIterationSpace( 5158 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5159 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5160 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5161 Captures)) 5162 return 0; 5163 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 5164 // Handle initialization of captured loop iterator variables. 5165 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 5166 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 5167 Captures[DRE] = DRE; 5168 } 5169 } 5170 // Move on to the next nested for loop, or to the loop body. 5171 // OpenMP [2.8.1, simd construct, Restrictions] 5172 // All loops associated with the construct must be perfectly nested; that 5173 // is, there must be no intervening code nor any OpenMP directive between 5174 // any two loops. 5175 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5176 } 5177 5178 Built.clear(/* size */ NestedLoopCount); 5179 5180 if (SemaRef.CurContext->isDependentContext()) 5181 return NestedLoopCount; 5182 5183 // An example of what is generated for the following code: 5184 // 5185 // #pragma omp simd collapse(2) ordered(2) 5186 // for (i = 0; i < NI; ++i) 5187 // for (k = 0; k < NK; ++k) 5188 // for (j = J0; j < NJ; j+=2) { 5189 // <loop body> 5190 // } 5191 // 5192 // We generate the code below. 5193 // Note: the loop body may be outlined in CodeGen. 5194 // Note: some counters may be C++ classes, operator- is used to find number of 5195 // iterations and operator+= to calculate counter value. 5196 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 5197 // or i64 is currently supported). 5198 // 5199 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 5200 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 5201 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 5202 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 5203 // // similar updates for vars in clauses (e.g. 'linear') 5204 // <loop body (using local i and j)> 5205 // } 5206 // i = NI; // assign final values of counters 5207 // j = NJ; 5208 // 5209 5210 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 5211 // the iteration counts of the collapsed for loops. 5212 // Precondition tests if there is at least one iteration (all conditions are 5213 // true). 5214 auto PreCond = ExprResult(IterSpaces[0].PreCond); 5215 Expr *N0 = IterSpaces[0].NumIterations; 5216 ExprResult LastIteration32 = 5217 widenIterationCount(/*Bits=*/32, 5218 SemaRef 5219 .PerformImplicitConversion( 5220 N0->IgnoreImpCasts(), N0->getType(), 5221 Sema::AA_Converting, /*AllowExplicit=*/true) 5222 .get(), 5223 SemaRef); 5224 ExprResult LastIteration64 = widenIterationCount( 5225 /*Bits=*/64, 5226 SemaRef 5227 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 5228 Sema::AA_Converting, 5229 /*AllowExplicit=*/true) 5230 .get(), 5231 SemaRef); 5232 5233 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 5234 return NestedLoopCount; 5235 5236 ASTContext &C = SemaRef.Context; 5237 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 5238 5239 Scope *CurScope = DSA.getCurScope(); 5240 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 5241 if (PreCond.isUsable()) { 5242 PreCond = 5243 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 5244 PreCond.get(), IterSpaces[Cnt].PreCond); 5245 } 5246 Expr *N = IterSpaces[Cnt].NumIterations; 5247 SourceLocation Loc = N->getExprLoc(); 5248 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 5249 if (LastIteration32.isUsable()) 5250 LastIteration32 = SemaRef.BuildBinOp( 5251 CurScope, Loc, BO_Mul, LastIteration32.get(), 5252 SemaRef 5253 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5254 Sema::AA_Converting, 5255 /*AllowExplicit=*/true) 5256 .get()); 5257 if (LastIteration64.isUsable()) 5258 LastIteration64 = SemaRef.BuildBinOp( 5259 CurScope, Loc, BO_Mul, LastIteration64.get(), 5260 SemaRef 5261 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5262 Sema::AA_Converting, 5263 /*AllowExplicit=*/true) 5264 .get()); 5265 } 5266 5267 // Choose either the 32-bit or 64-bit version. 5268 ExprResult LastIteration = LastIteration64; 5269 if (LastIteration32.isUsable() && 5270 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 5271 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 5272 fitsInto( 5273 /*Bits=*/32, 5274 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 5275 LastIteration64.get(), SemaRef))) 5276 LastIteration = LastIteration32; 5277 QualType VType = LastIteration.get()->getType(); 5278 QualType RealVType = VType; 5279 QualType StrideVType = VType; 5280 if (isOpenMPTaskLoopDirective(DKind)) { 5281 VType = 5282 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 5283 StrideVType = 5284 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 5285 } 5286 5287 if (!LastIteration.isUsable()) 5288 return 0; 5289 5290 // Save the number of iterations. 5291 ExprResult NumIterations = LastIteration; 5292 { 5293 LastIteration = SemaRef.BuildBinOp( 5294 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 5295 LastIteration.get(), 5296 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5297 if (!LastIteration.isUsable()) 5298 return 0; 5299 } 5300 5301 // Calculate the last iteration number beforehand instead of doing this on 5302 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5303 llvm::APSInt Result; 5304 bool IsConstant = 5305 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5306 ExprResult CalcLastIteration; 5307 if (!IsConstant) { 5308 ExprResult SaveRef = 5309 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5310 LastIteration = SaveRef; 5311 5312 // Prepare SaveRef + 1. 5313 NumIterations = SemaRef.BuildBinOp( 5314 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 5315 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5316 if (!NumIterations.isUsable()) 5317 return 0; 5318 } 5319 5320 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5321 5322 // Build variables passed into runtime, necessary for worksharing directives. 5323 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 5324 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5325 isOpenMPDistributeDirective(DKind)) { 5326 // Lower bound variable, initialized with zero. 5327 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5328 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5329 SemaRef.AddInitializerToDecl(LBDecl, 5330 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5331 /*DirectInit*/ false); 5332 5333 // Upper bound variable, initialized with last iteration number. 5334 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 5335 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 5336 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 5337 /*DirectInit*/ false); 5338 5339 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 5340 // This will be used to implement clause 'lastprivate'. 5341 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 5342 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 5343 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 5344 SemaRef.AddInitializerToDecl(ILDecl, 5345 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5346 /*DirectInit*/ false); 5347 5348 // Stride variable returned by runtime (we initialize it to 1 by default). 5349 VarDecl *STDecl = 5350 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 5351 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 5352 SemaRef.AddInitializerToDecl(STDecl, 5353 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 5354 /*DirectInit*/ false); 5355 5356 // Build expression: UB = min(UB, LastIteration) 5357 // It is necessary for CodeGen of directives with static scheduling. 5358 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 5359 UB.get(), LastIteration.get()); 5360 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5361 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 5362 LastIteration.get(), UB.get()); 5363 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 5364 CondOp.get()); 5365 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 5366 5367 // If we have a combined directive that combines 'distribute', 'for' or 5368 // 'simd' we need to be able to access the bounds of the schedule of the 5369 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 5370 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 5371 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5372 // Lower bound variable, initialized with zero. 5373 VarDecl *CombLBDecl = 5374 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 5375 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 5376 SemaRef.AddInitializerToDecl( 5377 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5378 /*DirectInit*/ false); 5379 5380 // Upper bound variable, initialized with last iteration number. 5381 VarDecl *CombUBDecl = 5382 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 5383 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 5384 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 5385 /*DirectInit*/ false); 5386 5387 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 5388 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 5389 ExprResult CombCondOp = 5390 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 5391 LastIteration.get(), CombUB.get()); 5392 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 5393 CombCondOp.get()); 5394 CombEUB = 5395 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 5396 5397 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 5398 // We expect to have at least 2 more parameters than the 'parallel' 5399 // directive does - the lower and upper bounds of the previous schedule. 5400 assert(CD->getNumParams() >= 4 && 5401 "Unexpected number of parameters in loop combined directive"); 5402 5403 // Set the proper type for the bounds given what we learned from the 5404 // enclosed loops. 5405 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 5406 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 5407 5408 // Previous lower and upper bounds are obtained from the region 5409 // parameters. 5410 PrevLB = 5411 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 5412 PrevUB = 5413 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 5414 } 5415 } 5416 5417 // Build the iteration variable and its initialization before loop. 5418 ExprResult IV; 5419 ExprResult Init, CombInit; 5420 { 5421 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 5422 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 5423 Expr *RHS = 5424 (isOpenMPWorksharingDirective(DKind) || 5425 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5426 ? LB.get() 5427 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5428 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 5429 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 5430 5431 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5432 Expr *CombRHS = 5433 (isOpenMPWorksharingDirective(DKind) || 5434 isOpenMPTaskLoopDirective(DKind) || 5435 isOpenMPDistributeDirective(DKind)) 5436 ? CombLB.get() 5437 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5438 CombInit = 5439 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 5440 CombInit = 5441 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 5442 } 5443 } 5444 5445 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 5446 SourceLocation CondLoc = AStmt->getBeginLoc(); 5447 ExprResult Cond = 5448 (isOpenMPWorksharingDirective(DKind) || 5449 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5450 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 5451 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5452 NumIterations.get()); 5453 ExprResult CombDistCond; 5454 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5455 CombDistCond = 5456 SemaRef.BuildBinOp( 5457 CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get()); 5458 } 5459 5460 ExprResult CombCond; 5461 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5462 CombCond = 5463 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get()); 5464 } 5465 // Loop increment (IV = IV + 1) 5466 SourceLocation IncLoc = AStmt->getBeginLoc(); 5467 ExprResult Inc = 5468 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 5469 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 5470 if (!Inc.isUsable()) 5471 return 0; 5472 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 5473 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 5474 if (!Inc.isUsable()) 5475 return 0; 5476 5477 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 5478 // Used for directives with static scheduling. 5479 // In combined construct, add combined version that use CombLB and CombUB 5480 // base variables for the update 5481 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 5482 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5483 isOpenMPDistributeDirective(DKind)) { 5484 // LB + ST 5485 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 5486 if (!NextLB.isUsable()) 5487 return 0; 5488 // LB = LB + ST 5489 NextLB = 5490 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 5491 NextLB = 5492 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 5493 if (!NextLB.isUsable()) 5494 return 0; 5495 // UB + ST 5496 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 5497 if (!NextUB.isUsable()) 5498 return 0; 5499 // UB = UB + ST 5500 NextUB = 5501 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 5502 NextUB = 5503 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 5504 if (!NextUB.isUsable()) 5505 return 0; 5506 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5507 CombNextLB = 5508 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 5509 if (!NextLB.isUsable()) 5510 return 0; 5511 // LB = LB + ST 5512 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 5513 CombNextLB.get()); 5514 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 5515 /*DiscardedValue*/ false); 5516 if (!CombNextLB.isUsable()) 5517 return 0; 5518 // UB + ST 5519 CombNextUB = 5520 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 5521 if (!CombNextUB.isUsable()) 5522 return 0; 5523 // UB = UB + ST 5524 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 5525 CombNextUB.get()); 5526 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 5527 /*DiscardedValue*/ false); 5528 if (!CombNextUB.isUsable()) 5529 return 0; 5530 } 5531 } 5532 5533 // Create increment expression for distribute loop when combined in a same 5534 // directive with for as IV = IV + ST; ensure upper bound expression based 5535 // on PrevUB instead of NumIterations - used to implement 'for' when found 5536 // in combination with 'distribute', like in 'distribute parallel for' 5537 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 5538 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 5539 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5540 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); 5541 assert(DistCond.isUsable() && "distribute cond expr was not built"); 5542 5543 DistInc = 5544 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 5545 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5546 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 5547 DistInc.get()); 5548 DistInc = 5549 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 5550 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5551 5552 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 5553 // construct 5554 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 5555 ExprResult IsUBGreater = 5556 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 5557 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5558 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 5559 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 5560 CondOp.get()); 5561 PrevEUB = 5562 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 5563 5564 // Build IV <= PrevUB to be used in parallel for is in combination with 5565 // a distribute directive with schedule(static, 1) 5566 ParForInDistCond = 5567 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.get()); 5568 } 5569 5570 // Build updates and final values of the loop counters. 5571 bool HasErrors = false; 5572 Built.Counters.resize(NestedLoopCount); 5573 Built.Inits.resize(NestedLoopCount); 5574 Built.Updates.resize(NestedLoopCount); 5575 Built.Finals.resize(NestedLoopCount); 5576 { 5577 ExprResult Div; 5578 // Go from inner nested loop to outer. 5579 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 5580 LoopIterationSpace &IS = IterSpaces[Cnt]; 5581 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 5582 // Build: Iter = (IV / Div) % IS.NumIters 5583 // where Div is product of previous iterations' IS.NumIters. 5584 ExprResult Iter; 5585 if (Div.isUsable()) { 5586 Iter = 5587 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 5588 } else { 5589 Iter = IV; 5590 assert((Cnt == (int)NestedLoopCount - 1) && 5591 "unusable div expected on first iteration only"); 5592 } 5593 5594 if (Cnt != 0 && Iter.isUsable()) 5595 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 5596 IS.NumIterations); 5597 if (!Iter.isUsable()) { 5598 HasErrors = true; 5599 break; 5600 } 5601 5602 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 5603 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 5604 DeclRefExpr *CounterVar = buildDeclRefExpr( 5605 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 5606 /*RefersToCapture=*/true); 5607 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 5608 IS.CounterInit, Captures); 5609 if (!Init.isUsable()) { 5610 HasErrors = true; 5611 break; 5612 } 5613 ExprResult Update = buildCounterUpdate( 5614 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 5615 IS.CounterStep, IS.Subtract, &Captures); 5616 if (!Update.isUsable()) { 5617 HasErrors = true; 5618 break; 5619 } 5620 5621 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 5622 ExprResult Final = buildCounterUpdate( 5623 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 5624 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 5625 if (!Final.isUsable()) { 5626 HasErrors = true; 5627 break; 5628 } 5629 5630 // Build Div for the next iteration: Div <- Div * IS.NumIters 5631 if (Cnt != 0) { 5632 if (Div.isUnset()) 5633 Div = IS.NumIterations; 5634 else 5635 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 5636 IS.NumIterations); 5637 5638 // Add parentheses (for debugging purposes only). 5639 if (Div.isUsable()) 5640 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 5641 if (!Div.isUsable()) { 5642 HasErrors = true; 5643 break; 5644 } 5645 } 5646 if (!Update.isUsable() || !Final.isUsable()) { 5647 HasErrors = true; 5648 break; 5649 } 5650 // Save results 5651 Built.Counters[Cnt] = IS.CounterVar; 5652 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 5653 Built.Inits[Cnt] = Init.get(); 5654 Built.Updates[Cnt] = Update.get(); 5655 Built.Finals[Cnt] = Final.get(); 5656 } 5657 } 5658 5659 if (HasErrors) 5660 return 0; 5661 5662 // Save results 5663 Built.IterationVarRef = IV.get(); 5664 Built.LastIteration = LastIteration.get(); 5665 Built.NumIterations = NumIterations.get(); 5666 Built.CalcLastIteration = SemaRef 5667 .ActOnFinishFullExpr(CalcLastIteration.get(), 5668 /*DiscardedValue*/ false) 5669 .get(); 5670 Built.PreCond = PreCond.get(); 5671 Built.PreInits = buildPreInits(C, Captures); 5672 Built.Cond = Cond.get(); 5673 Built.Init = Init.get(); 5674 Built.Inc = Inc.get(); 5675 Built.LB = LB.get(); 5676 Built.UB = UB.get(); 5677 Built.IL = IL.get(); 5678 Built.ST = ST.get(); 5679 Built.EUB = EUB.get(); 5680 Built.NLB = NextLB.get(); 5681 Built.NUB = NextUB.get(); 5682 Built.PrevLB = PrevLB.get(); 5683 Built.PrevUB = PrevUB.get(); 5684 Built.DistInc = DistInc.get(); 5685 Built.PrevEUB = PrevEUB.get(); 5686 Built.DistCombinedFields.LB = CombLB.get(); 5687 Built.DistCombinedFields.UB = CombUB.get(); 5688 Built.DistCombinedFields.EUB = CombEUB.get(); 5689 Built.DistCombinedFields.Init = CombInit.get(); 5690 Built.DistCombinedFields.Cond = CombCond.get(); 5691 Built.DistCombinedFields.NLB = CombNextLB.get(); 5692 Built.DistCombinedFields.NUB = CombNextUB.get(); 5693 Built.DistCombinedFields.DistCond = CombDistCond.get(); 5694 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 5695 5696 return NestedLoopCount; 5697 } 5698 5699 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 5700 auto CollapseClauses = 5701 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 5702 if (CollapseClauses.begin() != CollapseClauses.end()) 5703 return (*CollapseClauses.begin())->getNumForLoops(); 5704 return nullptr; 5705 } 5706 5707 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 5708 auto OrderedClauses = 5709 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 5710 if (OrderedClauses.begin() != OrderedClauses.end()) 5711 return (*OrderedClauses.begin())->getNumForLoops(); 5712 return nullptr; 5713 } 5714 5715 static bool checkSimdlenSafelenSpecified(Sema &S, 5716 const ArrayRef<OMPClause *> Clauses) { 5717 const OMPSafelenClause *Safelen = nullptr; 5718 const OMPSimdlenClause *Simdlen = nullptr; 5719 5720 for (const OMPClause *Clause : Clauses) { 5721 if (Clause->getClauseKind() == OMPC_safelen) 5722 Safelen = cast<OMPSafelenClause>(Clause); 5723 else if (Clause->getClauseKind() == OMPC_simdlen) 5724 Simdlen = cast<OMPSimdlenClause>(Clause); 5725 if (Safelen && Simdlen) 5726 break; 5727 } 5728 5729 if (Simdlen && Safelen) { 5730 const Expr *SimdlenLength = Simdlen->getSimdlen(); 5731 const Expr *SafelenLength = Safelen->getSafelen(); 5732 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 5733 SimdlenLength->isInstantiationDependent() || 5734 SimdlenLength->containsUnexpandedParameterPack()) 5735 return false; 5736 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 5737 SafelenLength->isInstantiationDependent() || 5738 SafelenLength->containsUnexpandedParameterPack()) 5739 return false; 5740 Expr::EvalResult SimdlenResult, SafelenResult; 5741 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 5742 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 5743 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 5744 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 5745 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 5746 // If both simdlen and safelen clauses are specified, the value of the 5747 // simdlen parameter must be less than or equal to the value of the safelen 5748 // parameter. 5749 if (SimdlenRes > SafelenRes) { 5750 S.Diag(SimdlenLength->getExprLoc(), 5751 diag::err_omp_wrong_simdlen_safelen_values) 5752 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 5753 return true; 5754 } 5755 } 5756 return false; 5757 } 5758 5759 StmtResult 5760 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 5761 SourceLocation StartLoc, SourceLocation EndLoc, 5762 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5763 if (!AStmt) 5764 return StmtError(); 5765 5766 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5767 OMPLoopDirective::HelperExprs B; 5768 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5769 // define the nested loops number. 5770 unsigned NestedLoopCount = checkOpenMPLoop( 5771 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5772 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5773 if (NestedLoopCount == 0) 5774 return StmtError(); 5775 5776 assert((CurContext->isDependentContext() || B.builtAll()) && 5777 "omp simd loop exprs were not built"); 5778 5779 if (!CurContext->isDependentContext()) { 5780 // Finalize the clauses that need pre-built expressions for CodeGen. 5781 for (OMPClause *C : Clauses) { 5782 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5783 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5784 B.NumIterations, *this, CurScope, 5785 DSAStack)) 5786 return StmtError(); 5787 } 5788 } 5789 5790 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5791 return StmtError(); 5792 5793 setFunctionHasBranchProtectedScope(); 5794 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5795 Clauses, AStmt, B); 5796 } 5797 5798 StmtResult 5799 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 5800 SourceLocation StartLoc, SourceLocation EndLoc, 5801 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5802 if (!AStmt) 5803 return StmtError(); 5804 5805 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5806 OMPLoopDirective::HelperExprs B; 5807 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5808 // define the nested loops number. 5809 unsigned NestedLoopCount = checkOpenMPLoop( 5810 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5811 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5812 if (NestedLoopCount == 0) 5813 return StmtError(); 5814 5815 assert((CurContext->isDependentContext() || B.builtAll()) && 5816 "omp for loop exprs were not built"); 5817 5818 if (!CurContext->isDependentContext()) { 5819 // Finalize the clauses that need pre-built expressions for CodeGen. 5820 for (OMPClause *C : Clauses) { 5821 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5822 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5823 B.NumIterations, *this, CurScope, 5824 DSAStack)) 5825 return StmtError(); 5826 } 5827 } 5828 5829 setFunctionHasBranchProtectedScope(); 5830 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5831 Clauses, AStmt, B, DSAStack->isCancelRegion()); 5832 } 5833 5834 StmtResult Sema::ActOnOpenMPForSimdDirective( 5835 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5836 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 5837 if (!AStmt) 5838 return StmtError(); 5839 5840 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5841 OMPLoopDirective::HelperExprs B; 5842 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5843 // define the nested loops number. 5844 unsigned NestedLoopCount = 5845 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5846 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5847 VarsWithImplicitDSA, B); 5848 if (NestedLoopCount == 0) 5849 return StmtError(); 5850 5851 assert((CurContext->isDependentContext() || B.builtAll()) && 5852 "omp for simd loop exprs were not built"); 5853 5854 if (!CurContext->isDependentContext()) { 5855 // Finalize the clauses that need pre-built expressions for CodeGen. 5856 for (OMPClause *C : Clauses) { 5857 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5858 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5859 B.NumIterations, *this, CurScope, 5860 DSAStack)) 5861 return StmtError(); 5862 } 5863 } 5864 5865 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5866 return StmtError(); 5867 5868 setFunctionHasBranchProtectedScope(); 5869 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5870 Clauses, AStmt, B); 5871 } 5872 5873 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5874 Stmt *AStmt, 5875 SourceLocation StartLoc, 5876 SourceLocation EndLoc) { 5877 if (!AStmt) 5878 return StmtError(); 5879 5880 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5881 auto BaseStmt = AStmt; 5882 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5883 BaseStmt = CS->getCapturedStmt(); 5884 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5885 auto S = C->children(); 5886 if (S.begin() == S.end()) 5887 return StmtError(); 5888 // All associated statements must be '#pragma omp section' except for 5889 // the first one. 5890 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5891 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5892 if (SectionStmt) 5893 Diag(SectionStmt->getBeginLoc(), 5894 diag::err_omp_sections_substmt_not_section); 5895 return StmtError(); 5896 } 5897 cast<OMPSectionDirective>(SectionStmt) 5898 ->setHasCancel(DSAStack->isCancelRegion()); 5899 } 5900 } else { 5901 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 5902 return StmtError(); 5903 } 5904 5905 setFunctionHasBranchProtectedScope(); 5906 5907 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5908 DSAStack->isCancelRegion()); 5909 } 5910 5911 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5912 SourceLocation StartLoc, 5913 SourceLocation EndLoc) { 5914 if (!AStmt) 5915 return StmtError(); 5916 5917 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5918 5919 setFunctionHasBranchProtectedScope(); 5920 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5921 5922 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5923 DSAStack->isCancelRegion()); 5924 } 5925 5926 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5927 Stmt *AStmt, 5928 SourceLocation StartLoc, 5929 SourceLocation EndLoc) { 5930 if (!AStmt) 5931 return StmtError(); 5932 5933 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5934 5935 setFunctionHasBranchProtectedScope(); 5936 5937 // OpenMP [2.7.3, single Construct, Restrictions] 5938 // The copyprivate clause must not be used with the nowait clause. 5939 const OMPClause *Nowait = nullptr; 5940 const OMPClause *Copyprivate = nullptr; 5941 for (const OMPClause *Clause : Clauses) { 5942 if (Clause->getClauseKind() == OMPC_nowait) 5943 Nowait = Clause; 5944 else if (Clause->getClauseKind() == OMPC_copyprivate) 5945 Copyprivate = Clause; 5946 if (Copyprivate && Nowait) { 5947 Diag(Copyprivate->getBeginLoc(), 5948 diag::err_omp_single_copyprivate_with_nowait); 5949 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 5950 return StmtError(); 5951 } 5952 } 5953 5954 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5955 } 5956 5957 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5958 SourceLocation StartLoc, 5959 SourceLocation EndLoc) { 5960 if (!AStmt) 5961 return StmtError(); 5962 5963 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5964 5965 setFunctionHasBranchProtectedScope(); 5966 5967 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5968 } 5969 5970 StmtResult Sema::ActOnOpenMPCriticalDirective( 5971 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5972 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5973 if (!AStmt) 5974 return StmtError(); 5975 5976 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5977 5978 bool ErrorFound = false; 5979 llvm::APSInt Hint; 5980 SourceLocation HintLoc; 5981 bool DependentHint = false; 5982 for (const OMPClause *C : Clauses) { 5983 if (C->getClauseKind() == OMPC_hint) { 5984 if (!DirName.getName()) { 5985 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 5986 ErrorFound = true; 5987 } 5988 Expr *E = cast<OMPHintClause>(C)->getHint(); 5989 if (E->isTypeDependent() || E->isValueDependent() || 5990 E->isInstantiationDependent()) { 5991 DependentHint = true; 5992 } else { 5993 Hint = E->EvaluateKnownConstInt(Context); 5994 HintLoc = C->getBeginLoc(); 5995 } 5996 } 5997 } 5998 if (ErrorFound) 5999 return StmtError(); 6000 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6001 if (Pair.first && DirName.getName() && !DependentHint) { 6002 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6003 Diag(StartLoc, diag::err_omp_critical_with_hint); 6004 if (HintLoc.isValid()) 6005 Diag(HintLoc, diag::note_omp_critical_hint_here) 6006 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6007 else 6008 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6009 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6010 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6011 << 1 6012 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6013 /*Radix=*/10, /*Signed=*/false); 6014 } else { 6015 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6016 } 6017 } 6018 } 6019 6020 setFunctionHasBranchProtectedScope(); 6021 6022 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6023 Clauses, AStmt); 6024 if (!Pair.first && DirName.getName() && !DependentHint) 6025 DSAStack->addCriticalWithHint(Dir, Hint); 6026 return Dir; 6027 } 6028 6029 StmtResult Sema::ActOnOpenMPParallelForDirective( 6030 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6031 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6032 if (!AStmt) 6033 return StmtError(); 6034 6035 auto *CS = cast<CapturedStmt>(AStmt); 6036 // 1.2.2 OpenMP Language Terminology 6037 // Structured block - An executable statement with a single entry at the 6038 // top and a single exit at the bottom. 6039 // The point of exit cannot be a branch out of the structured block. 6040 // longjmp() and throw() must not violate the entry/exit criteria. 6041 CS->getCapturedDecl()->setNothrow(); 6042 6043 OMPLoopDirective::HelperExprs B; 6044 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6045 // define the nested loops number. 6046 unsigned NestedLoopCount = 6047 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6048 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6049 VarsWithImplicitDSA, B); 6050 if (NestedLoopCount == 0) 6051 return StmtError(); 6052 6053 assert((CurContext->isDependentContext() || B.builtAll()) && 6054 "omp parallel for loop exprs were not built"); 6055 6056 if (!CurContext->isDependentContext()) { 6057 // Finalize the clauses that need pre-built expressions for CodeGen. 6058 for (OMPClause *C : Clauses) { 6059 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6060 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6061 B.NumIterations, *this, CurScope, 6062 DSAStack)) 6063 return StmtError(); 6064 } 6065 } 6066 6067 setFunctionHasBranchProtectedScope(); 6068 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6069 NestedLoopCount, Clauses, AStmt, B, 6070 DSAStack->isCancelRegion()); 6071 } 6072 6073 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6074 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6075 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6076 if (!AStmt) 6077 return StmtError(); 6078 6079 auto *CS = cast<CapturedStmt>(AStmt); 6080 // 1.2.2 OpenMP Language Terminology 6081 // Structured block - An executable statement with a single entry at the 6082 // top and a single exit at the bottom. 6083 // The point of exit cannot be a branch out of the structured block. 6084 // longjmp() and throw() must not violate the entry/exit criteria. 6085 CS->getCapturedDecl()->setNothrow(); 6086 6087 OMPLoopDirective::HelperExprs B; 6088 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6089 // define the nested loops number. 6090 unsigned NestedLoopCount = 6091 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 6092 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6093 VarsWithImplicitDSA, B); 6094 if (NestedLoopCount == 0) 6095 return StmtError(); 6096 6097 if (!CurContext->isDependentContext()) { 6098 // Finalize the clauses that need pre-built expressions for CodeGen. 6099 for (OMPClause *C : Clauses) { 6100 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6101 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6102 B.NumIterations, *this, CurScope, 6103 DSAStack)) 6104 return StmtError(); 6105 } 6106 } 6107 6108 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6109 return StmtError(); 6110 6111 setFunctionHasBranchProtectedScope(); 6112 return OMPParallelForSimdDirective::Create( 6113 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6114 } 6115 6116 StmtResult 6117 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 6118 Stmt *AStmt, SourceLocation StartLoc, 6119 SourceLocation EndLoc) { 6120 if (!AStmt) 6121 return StmtError(); 6122 6123 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6124 auto BaseStmt = AStmt; 6125 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6126 BaseStmt = CS->getCapturedStmt(); 6127 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6128 auto S = C->children(); 6129 if (S.begin() == S.end()) 6130 return StmtError(); 6131 // All associated statements must be '#pragma omp section' except for 6132 // the first one. 6133 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6134 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6135 if (SectionStmt) 6136 Diag(SectionStmt->getBeginLoc(), 6137 diag::err_omp_parallel_sections_substmt_not_section); 6138 return StmtError(); 6139 } 6140 cast<OMPSectionDirective>(SectionStmt) 6141 ->setHasCancel(DSAStack->isCancelRegion()); 6142 } 6143 } else { 6144 Diag(AStmt->getBeginLoc(), 6145 diag::err_omp_parallel_sections_not_compound_stmt); 6146 return StmtError(); 6147 } 6148 6149 setFunctionHasBranchProtectedScope(); 6150 6151 return OMPParallelSectionsDirective::Create( 6152 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 6153 } 6154 6155 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 6156 Stmt *AStmt, SourceLocation StartLoc, 6157 SourceLocation EndLoc) { 6158 if (!AStmt) 6159 return StmtError(); 6160 6161 auto *CS = cast<CapturedStmt>(AStmt); 6162 // 1.2.2 OpenMP Language Terminology 6163 // Structured block - An executable statement with a single entry at the 6164 // top and a single exit at the bottom. 6165 // The point of exit cannot be a branch out of the structured block. 6166 // longjmp() and throw() must not violate the entry/exit criteria. 6167 CS->getCapturedDecl()->setNothrow(); 6168 6169 setFunctionHasBranchProtectedScope(); 6170 6171 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6172 DSAStack->isCancelRegion()); 6173 } 6174 6175 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 6176 SourceLocation EndLoc) { 6177 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 6178 } 6179 6180 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 6181 SourceLocation EndLoc) { 6182 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 6183 } 6184 6185 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 6186 SourceLocation EndLoc) { 6187 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 6188 } 6189 6190 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 6191 Stmt *AStmt, 6192 SourceLocation StartLoc, 6193 SourceLocation EndLoc) { 6194 if (!AStmt) 6195 return StmtError(); 6196 6197 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6198 6199 setFunctionHasBranchProtectedScope(); 6200 6201 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 6202 AStmt, 6203 DSAStack->getTaskgroupReductionRef()); 6204 } 6205 6206 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 6207 SourceLocation StartLoc, 6208 SourceLocation EndLoc) { 6209 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 6210 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 6211 } 6212 6213 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 6214 Stmt *AStmt, 6215 SourceLocation StartLoc, 6216 SourceLocation EndLoc) { 6217 const OMPClause *DependFound = nullptr; 6218 const OMPClause *DependSourceClause = nullptr; 6219 const OMPClause *DependSinkClause = nullptr; 6220 bool ErrorFound = false; 6221 const OMPThreadsClause *TC = nullptr; 6222 const OMPSIMDClause *SC = nullptr; 6223 for (const OMPClause *C : Clauses) { 6224 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 6225 DependFound = C; 6226 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 6227 if (DependSourceClause) { 6228 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 6229 << getOpenMPDirectiveName(OMPD_ordered) 6230 << getOpenMPClauseName(OMPC_depend) << 2; 6231 ErrorFound = true; 6232 } else { 6233 DependSourceClause = C; 6234 } 6235 if (DependSinkClause) { 6236 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6237 << 0; 6238 ErrorFound = true; 6239 } 6240 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 6241 if (DependSourceClause) { 6242 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6243 << 1; 6244 ErrorFound = true; 6245 } 6246 DependSinkClause = C; 6247 } 6248 } else if (C->getClauseKind() == OMPC_threads) { 6249 TC = cast<OMPThreadsClause>(C); 6250 } else if (C->getClauseKind() == OMPC_simd) { 6251 SC = cast<OMPSIMDClause>(C); 6252 } 6253 } 6254 if (!ErrorFound && !SC && 6255 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 6256 // OpenMP [2.8.1,simd Construct, Restrictions] 6257 // An ordered construct with the simd clause is the only OpenMP construct 6258 // that can appear in the simd region. 6259 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 6260 ErrorFound = true; 6261 } else if (DependFound && (TC || SC)) { 6262 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 6263 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 6264 ErrorFound = true; 6265 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 6266 Diag(DependFound->getBeginLoc(), 6267 diag::err_omp_ordered_directive_without_param); 6268 ErrorFound = true; 6269 } else if (TC || Clauses.empty()) { 6270 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 6271 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 6272 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 6273 << (TC != nullptr); 6274 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 6275 ErrorFound = true; 6276 } 6277 } 6278 if ((!AStmt && !DependFound) || ErrorFound) 6279 return StmtError(); 6280 6281 if (AStmt) { 6282 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6283 6284 setFunctionHasBranchProtectedScope(); 6285 } 6286 6287 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6288 } 6289 6290 namespace { 6291 /// Helper class for checking expression in 'omp atomic [update]' 6292 /// construct. 6293 class OpenMPAtomicUpdateChecker { 6294 /// Error results for atomic update expressions. 6295 enum ExprAnalysisErrorCode { 6296 /// A statement is not an expression statement. 6297 NotAnExpression, 6298 /// Expression is not builtin binary or unary operation. 6299 NotABinaryOrUnaryExpression, 6300 /// Unary operation is not post-/pre- increment/decrement operation. 6301 NotAnUnaryIncDecExpression, 6302 /// An expression is not of scalar type. 6303 NotAScalarType, 6304 /// A binary operation is not an assignment operation. 6305 NotAnAssignmentOp, 6306 /// RHS part of the binary operation is not a binary expression. 6307 NotABinaryExpression, 6308 /// RHS part is not additive/multiplicative/shift/biwise binary 6309 /// expression. 6310 NotABinaryOperator, 6311 /// RHS binary operation does not have reference to the updated LHS 6312 /// part. 6313 NotAnUpdateExpression, 6314 /// No errors is found. 6315 NoError 6316 }; 6317 /// Reference to Sema. 6318 Sema &SemaRef; 6319 /// A location for note diagnostics (when error is found). 6320 SourceLocation NoteLoc; 6321 /// 'x' lvalue part of the source atomic expression. 6322 Expr *X; 6323 /// 'expr' rvalue part of the source atomic expression. 6324 Expr *E; 6325 /// Helper expression of the form 6326 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6327 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6328 Expr *UpdateExpr; 6329 /// Is 'x' a LHS in a RHS part of full update expression. It is 6330 /// important for non-associative operations. 6331 bool IsXLHSInRHSPart; 6332 BinaryOperatorKind Op; 6333 SourceLocation OpLoc; 6334 /// true if the source expression is a postfix unary operation, false 6335 /// if it is a prefix unary operation. 6336 bool IsPostfixUpdate; 6337 6338 public: 6339 OpenMPAtomicUpdateChecker(Sema &SemaRef) 6340 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 6341 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 6342 /// Check specified statement that it is suitable for 'atomic update' 6343 /// constructs and extract 'x', 'expr' and Operation from the original 6344 /// expression. If DiagId and NoteId == 0, then only check is performed 6345 /// without error notification. 6346 /// \param DiagId Diagnostic which should be emitted if error is found. 6347 /// \param NoteId Diagnostic note for the main error message. 6348 /// \return true if statement is not an update expression, false otherwise. 6349 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 6350 /// Return the 'x' lvalue part of the source atomic expression. 6351 Expr *getX() const { return X; } 6352 /// Return the 'expr' rvalue part of the source atomic expression. 6353 Expr *getExpr() const { return E; } 6354 /// Return the update expression used in calculation of the updated 6355 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6356 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6357 Expr *getUpdateExpr() const { return UpdateExpr; } 6358 /// Return true if 'x' is LHS in RHS part of full update expression, 6359 /// false otherwise. 6360 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 6361 6362 /// true if the source expression is a postfix unary operation, false 6363 /// if it is a prefix unary operation. 6364 bool isPostfixUpdate() const { return IsPostfixUpdate; } 6365 6366 private: 6367 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 6368 unsigned NoteId = 0); 6369 }; 6370 } // namespace 6371 6372 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 6373 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 6374 ExprAnalysisErrorCode ErrorFound = NoError; 6375 SourceLocation ErrorLoc, NoteLoc; 6376 SourceRange ErrorRange, NoteRange; 6377 // Allowed constructs are: 6378 // x = x binop expr; 6379 // x = expr binop x; 6380 if (AtomicBinOp->getOpcode() == BO_Assign) { 6381 X = AtomicBinOp->getLHS(); 6382 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 6383 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 6384 if (AtomicInnerBinOp->isMultiplicativeOp() || 6385 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 6386 AtomicInnerBinOp->isBitwiseOp()) { 6387 Op = AtomicInnerBinOp->getOpcode(); 6388 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 6389 Expr *LHS = AtomicInnerBinOp->getLHS(); 6390 Expr *RHS = AtomicInnerBinOp->getRHS(); 6391 llvm::FoldingSetNodeID XId, LHSId, RHSId; 6392 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 6393 /*Canonical=*/true); 6394 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 6395 /*Canonical=*/true); 6396 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 6397 /*Canonical=*/true); 6398 if (XId == LHSId) { 6399 E = RHS; 6400 IsXLHSInRHSPart = true; 6401 } else if (XId == RHSId) { 6402 E = LHS; 6403 IsXLHSInRHSPart = false; 6404 } else { 6405 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6406 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6407 NoteLoc = X->getExprLoc(); 6408 NoteRange = X->getSourceRange(); 6409 ErrorFound = NotAnUpdateExpression; 6410 } 6411 } else { 6412 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6413 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6414 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 6415 NoteRange = SourceRange(NoteLoc, NoteLoc); 6416 ErrorFound = NotABinaryOperator; 6417 } 6418 } else { 6419 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 6420 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 6421 ErrorFound = NotABinaryExpression; 6422 } 6423 } else { 6424 ErrorLoc = AtomicBinOp->getExprLoc(); 6425 ErrorRange = AtomicBinOp->getSourceRange(); 6426 NoteLoc = AtomicBinOp->getOperatorLoc(); 6427 NoteRange = SourceRange(NoteLoc, NoteLoc); 6428 ErrorFound = NotAnAssignmentOp; 6429 } 6430 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6431 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6432 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6433 return true; 6434 } 6435 if (SemaRef.CurContext->isDependentContext()) 6436 E = X = UpdateExpr = nullptr; 6437 return ErrorFound != NoError; 6438 } 6439 6440 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 6441 unsigned NoteId) { 6442 ExprAnalysisErrorCode ErrorFound = NoError; 6443 SourceLocation ErrorLoc, NoteLoc; 6444 SourceRange ErrorRange, NoteRange; 6445 // Allowed constructs are: 6446 // x++; 6447 // x--; 6448 // ++x; 6449 // --x; 6450 // x binop= expr; 6451 // x = x binop expr; 6452 // x = expr binop x; 6453 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 6454 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 6455 if (AtomicBody->getType()->isScalarType() || 6456 AtomicBody->isInstantiationDependent()) { 6457 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 6458 AtomicBody->IgnoreParenImpCasts())) { 6459 // Check for Compound Assignment Operation 6460 Op = BinaryOperator::getOpForCompoundAssignment( 6461 AtomicCompAssignOp->getOpcode()); 6462 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 6463 E = AtomicCompAssignOp->getRHS(); 6464 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 6465 IsXLHSInRHSPart = true; 6466 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 6467 AtomicBody->IgnoreParenImpCasts())) { 6468 // Check for Binary Operation 6469 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 6470 return true; 6471 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 6472 AtomicBody->IgnoreParenImpCasts())) { 6473 // Check for Unary Operation 6474 if (AtomicUnaryOp->isIncrementDecrementOp()) { 6475 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 6476 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 6477 OpLoc = AtomicUnaryOp->getOperatorLoc(); 6478 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 6479 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 6480 IsXLHSInRHSPart = true; 6481 } else { 6482 ErrorFound = NotAnUnaryIncDecExpression; 6483 ErrorLoc = AtomicUnaryOp->getExprLoc(); 6484 ErrorRange = AtomicUnaryOp->getSourceRange(); 6485 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 6486 NoteRange = SourceRange(NoteLoc, NoteLoc); 6487 } 6488 } else if (!AtomicBody->isInstantiationDependent()) { 6489 ErrorFound = NotABinaryOrUnaryExpression; 6490 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 6491 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 6492 } 6493 } else { 6494 ErrorFound = NotAScalarType; 6495 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 6496 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6497 } 6498 } else { 6499 ErrorFound = NotAnExpression; 6500 NoteLoc = ErrorLoc = S->getBeginLoc(); 6501 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6502 } 6503 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6504 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6505 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6506 return true; 6507 } 6508 if (SemaRef.CurContext->isDependentContext()) 6509 E = X = UpdateExpr = nullptr; 6510 if (ErrorFound == NoError && E && X) { 6511 // Build an update expression of form 'OpaqueValueExpr(x) binop 6512 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 6513 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 6514 auto *OVEX = new (SemaRef.getASTContext()) 6515 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 6516 auto *OVEExpr = new (SemaRef.getASTContext()) 6517 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 6518 ExprResult Update = 6519 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 6520 IsXLHSInRHSPart ? OVEExpr : OVEX); 6521 if (Update.isInvalid()) 6522 return true; 6523 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 6524 Sema::AA_Casting); 6525 if (Update.isInvalid()) 6526 return true; 6527 UpdateExpr = Update.get(); 6528 } 6529 return ErrorFound != NoError; 6530 } 6531 6532 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 6533 Stmt *AStmt, 6534 SourceLocation StartLoc, 6535 SourceLocation EndLoc) { 6536 if (!AStmt) 6537 return StmtError(); 6538 6539 auto *CS = cast<CapturedStmt>(AStmt); 6540 // 1.2.2 OpenMP Language Terminology 6541 // Structured block - An executable statement with a single entry at the 6542 // top and a single exit at the bottom. 6543 // The point of exit cannot be a branch out of the structured block. 6544 // longjmp() and throw() must not violate the entry/exit criteria. 6545 OpenMPClauseKind AtomicKind = OMPC_unknown; 6546 SourceLocation AtomicKindLoc; 6547 for (const OMPClause *C : Clauses) { 6548 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 6549 C->getClauseKind() == OMPC_update || 6550 C->getClauseKind() == OMPC_capture) { 6551 if (AtomicKind != OMPC_unknown) { 6552 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 6553 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 6554 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 6555 << getOpenMPClauseName(AtomicKind); 6556 } else { 6557 AtomicKind = C->getClauseKind(); 6558 AtomicKindLoc = C->getBeginLoc(); 6559 } 6560 } 6561 } 6562 6563 Stmt *Body = CS->getCapturedStmt(); 6564 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 6565 Body = EWC->getSubExpr(); 6566 6567 Expr *X = nullptr; 6568 Expr *V = nullptr; 6569 Expr *E = nullptr; 6570 Expr *UE = nullptr; 6571 bool IsXLHSInRHSPart = false; 6572 bool IsPostfixUpdate = false; 6573 // OpenMP [2.12.6, atomic Construct] 6574 // In the next expressions: 6575 // * x and v (as applicable) are both l-value expressions with scalar type. 6576 // * During the execution of an atomic region, multiple syntactic 6577 // occurrences of x must designate the same storage location. 6578 // * Neither of v and expr (as applicable) may access the storage location 6579 // designated by x. 6580 // * Neither of x and expr (as applicable) may access the storage location 6581 // designated by v. 6582 // * expr is an expression with scalar type. 6583 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 6584 // * binop, binop=, ++, and -- are not overloaded operators. 6585 // * The expression x binop expr must be numerically equivalent to x binop 6586 // (expr). This requirement is satisfied if the operators in expr have 6587 // precedence greater than binop, or by using parentheses around expr or 6588 // subexpressions of expr. 6589 // * The expression expr binop x must be numerically equivalent to (expr) 6590 // binop x. This requirement is satisfied if the operators in expr have 6591 // precedence equal to or greater than binop, or by using parentheses around 6592 // expr or subexpressions of expr. 6593 // * For forms that allow multiple occurrences of x, the number of times 6594 // that x is evaluated is unspecified. 6595 if (AtomicKind == OMPC_read) { 6596 enum { 6597 NotAnExpression, 6598 NotAnAssignmentOp, 6599 NotAScalarType, 6600 NotAnLValue, 6601 NoError 6602 } ErrorFound = NoError; 6603 SourceLocation ErrorLoc, NoteLoc; 6604 SourceRange ErrorRange, NoteRange; 6605 // If clause is read: 6606 // v = x; 6607 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6608 const auto *AtomicBinOp = 6609 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6610 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6611 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6612 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 6613 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6614 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 6615 if (!X->isLValue() || !V->isLValue()) { 6616 const Expr *NotLValueExpr = X->isLValue() ? V : X; 6617 ErrorFound = NotAnLValue; 6618 ErrorLoc = AtomicBinOp->getExprLoc(); 6619 ErrorRange = AtomicBinOp->getSourceRange(); 6620 NoteLoc = NotLValueExpr->getExprLoc(); 6621 NoteRange = NotLValueExpr->getSourceRange(); 6622 } 6623 } else if (!X->isInstantiationDependent() || 6624 !V->isInstantiationDependent()) { 6625 const Expr *NotScalarExpr = 6626 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6627 ? V 6628 : X; 6629 ErrorFound = NotAScalarType; 6630 ErrorLoc = AtomicBinOp->getExprLoc(); 6631 ErrorRange = AtomicBinOp->getSourceRange(); 6632 NoteLoc = NotScalarExpr->getExprLoc(); 6633 NoteRange = NotScalarExpr->getSourceRange(); 6634 } 6635 } else if (!AtomicBody->isInstantiationDependent()) { 6636 ErrorFound = NotAnAssignmentOp; 6637 ErrorLoc = AtomicBody->getExprLoc(); 6638 ErrorRange = AtomicBody->getSourceRange(); 6639 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6640 : AtomicBody->getExprLoc(); 6641 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6642 : AtomicBody->getSourceRange(); 6643 } 6644 } else { 6645 ErrorFound = NotAnExpression; 6646 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6647 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6648 } 6649 if (ErrorFound != NoError) { 6650 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 6651 << ErrorRange; 6652 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6653 << NoteRange; 6654 return StmtError(); 6655 } 6656 if (CurContext->isDependentContext()) 6657 V = X = nullptr; 6658 } else if (AtomicKind == OMPC_write) { 6659 enum { 6660 NotAnExpression, 6661 NotAnAssignmentOp, 6662 NotAScalarType, 6663 NotAnLValue, 6664 NoError 6665 } ErrorFound = NoError; 6666 SourceLocation ErrorLoc, NoteLoc; 6667 SourceRange ErrorRange, NoteRange; 6668 // If clause is write: 6669 // x = expr; 6670 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6671 const auto *AtomicBinOp = 6672 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6673 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6674 X = AtomicBinOp->getLHS(); 6675 E = AtomicBinOp->getRHS(); 6676 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6677 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 6678 if (!X->isLValue()) { 6679 ErrorFound = NotAnLValue; 6680 ErrorLoc = AtomicBinOp->getExprLoc(); 6681 ErrorRange = AtomicBinOp->getSourceRange(); 6682 NoteLoc = X->getExprLoc(); 6683 NoteRange = X->getSourceRange(); 6684 } 6685 } else if (!X->isInstantiationDependent() || 6686 !E->isInstantiationDependent()) { 6687 const Expr *NotScalarExpr = 6688 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6689 ? E 6690 : X; 6691 ErrorFound = NotAScalarType; 6692 ErrorLoc = AtomicBinOp->getExprLoc(); 6693 ErrorRange = AtomicBinOp->getSourceRange(); 6694 NoteLoc = NotScalarExpr->getExprLoc(); 6695 NoteRange = NotScalarExpr->getSourceRange(); 6696 } 6697 } else if (!AtomicBody->isInstantiationDependent()) { 6698 ErrorFound = NotAnAssignmentOp; 6699 ErrorLoc = AtomicBody->getExprLoc(); 6700 ErrorRange = AtomicBody->getSourceRange(); 6701 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6702 : AtomicBody->getExprLoc(); 6703 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6704 : AtomicBody->getSourceRange(); 6705 } 6706 } else { 6707 ErrorFound = NotAnExpression; 6708 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6709 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6710 } 6711 if (ErrorFound != NoError) { 6712 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 6713 << ErrorRange; 6714 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6715 << NoteRange; 6716 return StmtError(); 6717 } 6718 if (CurContext->isDependentContext()) 6719 E = X = nullptr; 6720 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 6721 // If clause is update: 6722 // x++; 6723 // x--; 6724 // ++x; 6725 // --x; 6726 // x binop= expr; 6727 // x = x binop expr; 6728 // x = expr binop x; 6729 OpenMPAtomicUpdateChecker Checker(*this); 6730 if (Checker.checkStatement( 6731 Body, (AtomicKind == OMPC_update) 6732 ? diag::err_omp_atomic_update_not_expression_statement 6733 : diag::err_omp_atomic_not_expression_statement, 6734 diag::note_omp_atomic_update)) 6735 return StmtError(); 6736 if (!CurContext->isDependentContext()) { 6737 E = Checker.getExpr(); 6738 X = Checker.getX(); 6739 UE = Checker.getUpdateExpr(); 6740 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6741 } 6742 } else if (AtomicKind == OMPC_capture) { 6743 enum { 6744 NotAnAssignmentOp, 6745 NotACompoundStatement, 6746 NotTwoSubstatements, 6747 NotASpecificExpression, 6748 NoError 6749 } ErrorFound = NoError; 6750 SourceLocation ErrorLoc, NoteLoc; 6751 SourceRange ErrorRange, NoteRange; 6752 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6753 // If clause is a capture: 6754 // v = x++; 6755 // v = x--; 6756 // v = ++x; 6757 // v = --x; 6758 // v = x binop= expr; 6759 // v = x = x binop expr; 6760 // v = x = expr binop x; 6761 const auto *AtomicBinOp = 6762 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6763 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6764 V = AtomicBinOp->getLHS(); 6765 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6766 OpenMPAtomicUpdateChecker Checker(*this); 6767 if (Checker.checkStatement( 6768 Body, diag::err_omp_atomic_capture_not_expression_statement, 6769 diag::note_omp_atomic_update)) 6770 return StmtError(); 6771 E = Checker.getExpr(); 6772 X = Checker.getX(); 6773 UE = Checker.getUpdateExpr(); 6774 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6775 IsPostfixUpdate = Checker.isPostfixUpdate(); 6776 } else if (!AtomicBody->isInstantiationDependent()) { 6777 ErrorLoc = AtomicBody->getExprLoc(); 6778 ErrorRange = AtomicBody->getSourceRange(); 6779 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6780 : AtomicBody->getExprLoc(); 6781 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6782 : AtomicBody->getSourceRange(); 6783 ErrorFound = NotAnAssignmentOp; 6784 } 6785 if (ErrorFound != NoError) { 6786 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 6787 << ErrorRange; 6788 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6789 return StmtError(); 6790 } 6791 if (CurContext->isDependentContext()) 6792 UE = V = E = X = nullptr; 6793 } else { 6794 // If clause is a capture: 6795 // { v = x; x = expr; } 6796 // { v = x; x++; } 6797 // { v = x; x--; } 6798 // { v = x; ++x; } 6799 // { v = x; --x; } 6800 // { v = x; x binop= expr; } 6801 // { v = x; x = x binop expr; } 6802 // { v = x; x = expr binop x; } 6803 // { x++; v = x; } 6804 // { x--; v = x; } 6805 // { ++x; v = x; } 6806 // { --x; v = x; } 6807 // { x binop= expr; v = x; } 6808 // { x = x binop expr; v = x; } 6809 // { x = expr binop x; v = x; } 6810 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 6811 // Check that this is { expr1; expr2; } 6812 if (CS->size() == 2) { 6813 Stmt *First = CS->body_front(); 6814 Stmt *Second = CS->body_back(); 6815 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6816 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6817 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6818 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6819 // Need to find what subexpression is 'v' and what is 'x'. 6820 OpenMPAtomicUpdateChecker Checker(*this); 6821 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6822 BinaryOperator *BinOp = nullptr; 6823 if (IsUpdateExprFound) { 6824 BinOp = dyn_cast<BinaryOperator>(First); 6825 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6826 } 6827 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6828 // { v = x; x++; } 6829 // { v = x; x--; } 6830 // { v = x; ++x; } 6831 // { v = x; --x; } 6832 // { v = x; x binop= expr; } 6833 // { v = x; x = x binop expr; } 6834 // { v = x; x = expr binop x; } 6835 // Check that the first expression has form v = x. 6836 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6837 llvm::FoldingSetNodeID XId, PossibleXId; 6838 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6839 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6840 IsUpdateExprFound = XId == PossibleXId; 6841 if (IsUpdateExprFound) { 6842 V = BinOp->getLHS(); 6843 X = Checker.getX(); 6844 E = Checker.getExpr(); 6845 UE = Checker.getUpdateExpr(); 6846 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6847 IsPostfixUpdate = true; 6848 } 6849 } 6850 if (!IsUpdateExprFound) { 6851 IsUpdateExprFound = !Checker.checkStatement(First); 6852 BinOp = nullptr; 6853 if (IsUpdateExprFound) { 6854 BinOp = dyn_cast<BinaryOperator>(Second); 6855 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6856 } 6857 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6858 // { x++; v = x; } 6859 // { x--; v = x; } 6860 // { ++x; v = x; } 6861 // { --x; v = x; } 6862 // { x binop= expr; v = x; } 6863 // { x = x binop expr; v = x; } 6864 // { x = expr binop x; v = x; } 6865 // Check that the second expression has form v = x. 6866 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6867 llvm::FoldingSetNodeID XId, PossibleXId; 6868 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6869 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6870 IsUpdateExprFound = XId == PossibleXId; 6871 if (IsUpdateExprFound) { 6872 V = BinOp->getLHS(); 6873 X = Checker.getX(); 6874 E = Checker.getExpr(); 6875 UE = Checker.getUpdateExpr(); 6876 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6877 IsPostfixUpdate = false; 6878 } 6879 } 6880 } 6881 if (!IsUpdateExprFound) { 6882 // { v = x; x = expr; } 6883 auto *FirstExpr = dyn_cast<Expr>(First); 6884 auto *SecondExpr = dyn_cast<Expr>(Second); 6885 if (!FirstExpr || !SecondExpr || 6886 !(FirstExpr->isInstantiationDependent() || 6887 SecondExpr->isInstantiationDependent())) { 6888 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6889 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6890 ErrorFound = NotAnAssignmentOp; 6891 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6892 : First->getBeginLoc(); 6893 NoteRange = ErrorRange = FirstBinOp 6894 ? FirstBinOp->getSourceRange() 6895 : SourceRange(ErrorLoc, ErrorLoc); 6896 } else { 6897 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6898 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6899 ErrorFound = NotAnAssignmentOp; 6900 NoteLoc = ErrorLoc = SecondBinOp 6901 ? SecondBinOp->getOperatorLoc() 6902 : Second->getBeginLoc(); 6903 NoteRange = ErrorRange = 6904 SecondBinOp ? SecondBinOp->getSourceRange() 6905 : SourceRange(ErrorLoc, ErrorLoc); 6906 } else { 6907 Expr *PossibleXRHSInFirst = 6908 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6909 Expr *PossibleXLHSInSecond = 6910 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6911 llvm::FoldingSetNodeID X1Id, X2Id; 6912 PossibleXRHSInFirst->Profile(X1Id, Context, 6913 /*Canonical=*/true); 6914 PossibleXLHSInSecond->Profile(X2Id, Context, 6915 /*Canonical=*/true); 6916 IsUpdateExprFound = X1Id == X2Id; 6917 if (IsUpdateExprFound) { 6918 V = FirstBinOp->getLHS(); 6919 X = SecondBinOp->getLHS(); 6920 E = SecondBinOp->getRHS(); 6921 UE = nullptr; 6922 IsXLHSInRHSPart = false; 6923 IsPostfixUpdate = true; 6924 } else { 6925 ErrorFound = NotASpecificExpression; 6926 ErrorLoc = FirstBinOp->getExprLoc(); 6927 ErrorRange = FirstBinOp->getSourceRange(); 6928 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6929 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6930 } 6931 } 6932 } 6933 } 6934 } 6935 } else { 6936 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6937 NoteRange = ErrorRange = 6938 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 6939 ErrorFound = NotTwoSubstatements; 6940 } 6941 } else { 6942 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6943 NoteRange = ErrorRange = 6944 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 6945 ErrorFound = NotACompoundStatement; 6946 } 6947 if (ErrorFound != NoError) { 6948 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6949 << ErrorRange; 6950 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6951 return StmtError(); 6952 } 6953 if (CurContext->isDependentContext()) 6954 UE = V = E = X = nullptr; 6955 } 6956 } 6957 6958 setFunctionHasBranchProtectedScope(); 6959 6960 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6961 X, V, E, UE, IsXLHSInRHSPart, 6962 IsPostfixUpdate); 6963 } 6964 6965 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6966 Stmt *AStmt, 6967 SourceLocation StartLoc, 6968 SourceLocation EndLoc) { 6969 if (!AStmt) 6970 return StmtError(); 6971 6972 auto *CS = cast<CapturedStmt>(AStmt); 6973 // 1.2.2 OpenMP Language Terminology 6974 // Structured block - An executable statement with a single entry at the 6975 // top and a single exit at the bottom. 6976 // The point of exit cannot be a branch out of the structured block. 6977 // longjmp() and throw() must not violate the entry/exit criteria. 6978 CS->getCapturedDecl()->setNothrow(); 6979 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 6980 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6981 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6982 // 1.2.2 OpenMP Language Terminology 6983 // Structured block - An executable statement with a single entry at the 6984 // top and a single exit at the bottom. 6985 // The point of exit cannot be a branch out of the structured block. 6986 // longjmp() and throw() must not violate the entry/exit criteria. 6987 CS->getCapturedDecl()->setNothrow(); 6988 } 6989 6990 // OpenMP [2.16, Nesting of Regions] 6991 // If specified, a teams construct must be contained within a target 6992 // construct. That target construct must contain no statements or directives 6993 // outside of the teams construct. 6994 if (DSAStack->hasInnerTeamsRegion()) { 6995 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 6996 bool OMPTeamsFound = true; 6997 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 6998 auto I = CS->body_begin(); 6999 while (I != CS->body_end()) { 7000 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7001 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 7002 OMPTeamsFound = false; 7003 break; 7004 } 7005 ++I; 7006 } 7007 assert(I != CS->body_end() && "Not found statement"); 7008 S = *I; 7009 } else { 7010 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7011 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7012 } 7013 if (!OMPTeamsFound) { 7014 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7015 Diag(DSAStack->getInnerTeamsRegionLoc(), 7016 diag::note_omp_nested_teams_construct_here); 7017 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7018 << isa<OMPExecutableDirective>(S); 7019 return StmtError(); 7020 } 7021 } 7022 7023 setFunctionHasBranchProtectedScope(); 7024 7025 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7026 } 7027 7028 StmtResult 7029 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7030 Stmt *AStmt, SourceLocation StartLoc, 7031 SourceLocation EndLoc) { 7032 if (!AStmt) 7033 return StmtError(); 7034 7035 auto *CS = cast<CapturedStmt>(AStmt); 7036 // 1.2.2 OpenMP Language Terminology 7037 // Structured block - An executable statement with a single entry at the 7038 // top and a single exit at the bottom. 7039 // The point of exit cannot be a branch out of the structured block. 7040 // longjmp() and throw() must not violate the entry/exit criteria. 7041 CS->getCapturedDecl()->setNothrow(); 7042 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7043 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7044 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7045 // 1.2.2 OpenMP Language Terminology 7046 // Structured block - An executable statement with a single entry at the 7047 // top and a single exit at the bottom. 7048 // The point of exit cannot be a branch out of the structured block. 7049 // longjmp() and throw() must not violate the entry/exit criteria. 7050 CS->getCapturedDecl()->setNothrow(); 7051 } 7052 7053 setFunctionHasBranchProtectedScope(); 7054 7055 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7056 AStmt); 7057 } 7058 7059 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7060 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7061 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7062 if (!AStmt) 7063 return StmtError(); 7064 7065 auto *CS = cast<CapturedStmt>(AStmt); 7066 // 1.2.2 OpenMP Language Terminology 7067 // Structured block - An executable statement with a single entry at the 7068 // top and a single exit at the bottom. 7069 // The point of exit cannot be a branch out of the structured block. 7070 // longjmp() and throw() must not violate the entry/exit criteria. 7071 CS->getCapturedDecl()->setNothrow(); 7072 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7073 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7074 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7075 // 1.2.2 OpenMP Language Terminology 7076 // Structured block - An executable statement with a single entry at the 7077 // top and a single exit at the bottom. 7078 // The point of exit cannot be a branch out of the structured block. 7079 // longjmp() and throw() must not violate the entry/exit criteria. 7080 CS->getCapturedDecl()->setNothrow(); 7081 } 7082 7083 OMPLoopDirective::HelperExprs B; 7084 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7085 // define the nested loops number. 7086 unsigned NestedLoopCount = 7087 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 7088 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7089 VarsWithImplicitDSA, B); 7090 if (NestedLoopCount == 0) 7091 return StmtError(); 7092 7093 assert((CurContext->isDependentContext() || B.builtAll()) && 7094 "omp target parallel for loop exprs were not built"); 7095 7096 if (!CurContext->isDependentContext()) { 7097 // Finalize the clauses that need pre-built expressions for CodeGen. 7098 for (OMPClause *C : Clauses) { 7099 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7100 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7101 B.NumIterations, *this, CurScope, 7102 DSAStack)) 7103 return StmtError(); 7104 } 7105 } 7106 7107 setFunctionHasBranchProtectedScope(); 7108 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 7109 NestedLoopCount, Clauses, AStmt, 7110 B, DSAStack->isCancelRegion()); 7111 } 7112 7113 /// Check for existence of a map clause in the list of clauses. 7114 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 7115 const OpenMPClauseKind K) { 7116 return llvm::any_of( 7117 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 7118 } 7119 7120 template <typename... Params> 7121 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 7122 const Params... ClauseTypes) { 7123 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 7124 } 7125 7126 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 7127 Stmt *AStmt, 7128 SourceLocation StartLoc, 7129 SourceLocation EndLoc) { 7130 if (!AStmt) 7131 return StmtError(); 7132 7133 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7134 7135 // OpenMP [2.10.1, Restrictions, p. 97] 7136 // At least one map clause must appear on the directive. 7137 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 7138 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7139 << "'map' or 'use_device_ptr'" 7140 << getOpenMPDirectiveName(OMPD_target_data); 7141 return StmtError(); 7142 } 7143 7144 setFunctionHasBranchProtectedScope(); 7145 7146 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7147 AStmt); 7148 } 7149 7150 StmtResult 7151 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 7152 SourceLocation StartLoc, 7153 SourceLocation EndLoc, Stmt *AStmt) { 7154 if (!AStmt) 7155 return StmtError(); 7156 7157 auto *CS = cast<CapturedStmt>(AStmt); 7158 // 1.2.2 OpenMP Language Terminology 7159 // Structured block - An executable statement with a single entry at the 7160 // top and a single exit at the bottom. 7161 // The point of exit cannot be a branch out of the structured block. 7162 // longjmp() and throw() must not violate the entry/exit criteria. 7163 CS->getCapturedDecl()->setNothrow(); 7164 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 7165 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7166 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7167 // 1.2.2 OpenMP Language Terminology 7168 // Structured block - An executable statement with a single entry at the 7169 // top and a single exit at the bottom. 7170 // The point of exit cannot be a branch out of the structured block. 7171 // longjmp() and throw() must not violate the entry/exit criteria. 7172 CS->getCapturedDecl()->setNothrow(); 7173 } 7174 7175 // OpenMP [2.10.2, Restrictions, p. 99] 7176 // At least one map clause must appear on the directive. 7177 if (!hasClauses(Clauses, OMPC_map)) { 7178 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7179 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 7180 return StmtError(); 7181 } 7182 7183 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7184 AStmt); 7185 } 7186 7187 StmtResult 7188 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 7189 SourceLocation StartLoc, 7190 SourceLocation EndLoc, Stmt *AStmt) { 7191 if (!AStmt) 7192 return StmtError(); 7193 7194 auto *CS = cast<CapturedStmt>(AStmt); 7195 // 1.2.2 OpenMP Language Terminology 7196 // Structured block - An executable statement with a single entry at the 7197 // top and a single exit at the bottom. 7198 // The point of exit cannot be a branch out of the structured block. 7199 // longjmp() and throw() must not violate the entry/exit criteria. 7200 CS->getCapturedDecl()->setNothrow(); 7201 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 7202 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7203 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7204 // 1.2.2 OpenMP Language Terminology 7205 // Structured block - An executable statement with a single entry at the 7206 // top and a single exit at the bottom. 7207 // The point of exit cannot be a branch out of the structured block. 7208 // longjmp() and throw() must not violate the entry/exit criteria. 7209 CS->getCapturedDecl()->setNothrow(); 7210 } 7211 7212 // OpenMP [2.10.3, Restrictions, p. 102] 7213 // At least one map clause must appear on the directive. 7214 if (!hasClauses(Clauses, OMPC_map)) { 7215 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7216 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 7217 return StmtError(); 7218 } 7219 7220 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7221 AStmt); 7222 } 7223 7224 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 7225 SourceLocation StartLoc, 7226 SourceLocation EndLoc, 7227 Stmt *AStmt) { 7228 if (!AStmt) 7229 return StmtError(); 7230 7231 auto *CS = cast<CapturedStmt>(AStmt); 7232 // 1.2.2 OpenMP Language Terminology 7233 // Structured block - An executable statement with a single entry at the 7234 // top and a single exit at the bottom. 7235 // The point of exit cannot be a branch out of the structured block. 7236 // longjmp() and throw() must not violate the entry/exit criteria. 7237 CS->getCapturedDecl()->setNothrow(); 7238 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 7239 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7240 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7241 // 1.2.2 OpenMP Language Terminology 7242 // Structured block - An executable statement with a single entry at the 7243 // top and a single exit at the bottom. 7244 // The point of exit cannot be a branch out of the structured block. 7245 // longjmp() and throw() must not violate the entry/exit criteria. 7246 CS->getCapturedDecl()->setNothrow(); 7247 } 7248 7249 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 7250 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 7251 return StmtError(); 7252 } 7253 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 7254 AStmt); 7255 } 7256 7257 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 7258 Stmt *AStmt, SourceLocation StartLoc, 7259 SourceLocation EndLoc) { 7260 if (!AStmt) 7261 return StmtError(); 7262 7263 auto *CS = cast<CapturedStmt>(AStmt); 7264 // 1.2.2 OpenMP Language Terminology 7265 // Structured block - An executable statement with a single entry at the 7266 // top and a single exit at the bottom. 7267 // The point of exit cannot be a branch out of the structured block. 7268 // longjmp() and throw() must not violate the entry/exit criteria. 7269 CS->getCapturedDecl()->setNothrow(); 7270 7271 setFunctionHasBranchProtectedScope(); 7272 7273 DSAStack->setParentTeamsRegionLoc(StartLoc); 7274 7275 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7276 } 7277 7278 StmtResult 7279 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 7280 SourceLocation EndLoc, 7281 OpenMPDirectiveKind CancelRegion) { 7282 if (DSAStack->isParentNowaitRegion()) { 7283 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 7284 return StmtError(); 7285 } 7286 if (DSAStack->isParentOrderedRegion()) { 7287 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 7288 return StmtError(); 7289 } 7290 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 7291 CancelRegion); 7292 } 7293 7294 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 7295 SourceLocation StartLoc, 7296 SourceLocation EndLoc, 7297 OpenMPDirectiveKind CancelRegion) { 7298 if (DSAStack->isParentNowaitRegion()) { 7299 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 7300 return StmtError(); 7301 } 7302 if (DSAStack->isParentOrderedRegion()) { 7303 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 7304 return StmtError(); 7305 } 7306 DSAStack->setParentCancelRegion(/*Cancel=*/true); 7307 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7308 CancelRegion); 7309 } 7310 7311 static bool checkGrainsizeNumTasksClauses(Sema &S, 7312 ArrayRef<OMPClause *> Clauses) { 7313 const OMPClause *PrevClause = nullptr; 7314 bool ErrorFound = false; 7315 for (const OMPClause *C : Clauses) { 7316 if (C->getClauseKind() == OMPC_grainsize || 7317 C->getClauseKind() == OMPC_num_tasks) { 7318 if (!PrevClause) 7319 PrevClause = C; 7320 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 7321 S.Diag(C->getBeginLoc(), 7322 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 7323 << getOpenMPClauseName(C->getClauseKind()) 7324 << getOpenMPClauseName(PrevClause->getClauseKind()); 7325 S.Diag(PrevClause->getBeginLoc(), 7326 diag::note_omp_previous_grainsize_num_tasks) 7327 << getOpenMPClauseName(PrevClause->getClauseKind()); 7328 ErrorFound = true; 7329 } 7330 } 7331 } 7332 return ErrorFound; 7333 } 7334 7335 static bool checkReductionClauseWithNogroup(Sema &S, 7336 ArrayRef<OMPClause *> Clauses) { 7337 const OMPClause *ReductionClause = nullptr; 7338 const OMPClause *NogroupClause = nullptr; 7339 for (const OMPClause *C : Clauses) { 7340 if (C->getClauseKind() == OMPC_reduction) { 7341 ReductionClause = C; 7342 if (NogroupClause) 7343 break; 7344 continue; 7345 } 7346 if (C->getClauseKind() == OMPC_nogroup) { 7347 NogroupClause = C; 7348 if (ReductionClause) 7349 break; 7350 continue; 7351 } 7352 } 7353 if (ReductionClause && NogroupClause) { 7354 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 7355 << SourceRange(NogroupClause->getBeginLoc(), 7356 NogroupClause->getEndLoc()); 7357 return true; 7358 } 7359 return false; 7360 } 7361 7362 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 7363 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7364 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7365 if (!AStmt) 7366 return StmtError(); 7367 7368 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7369 OMPLoopDirective::HelperExprs B; 7370 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7371 // define the nested loops number. 7372 unsigned NestedLoopCount = 7373 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 7374 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7375 VarsWithImplicitDSA, B); 7376 if (NestedLoopCount == 0) 7377 return StmtError(); 7378 7379 assert((CurContext->isDependentContext() || B.builtAll()) && 7380 "omp for loop exprs were not built"); 7381 7382 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7383 // The grainsize clause and num_tasks clause are mutually exclusive and may 7384 // not appear on the same taskloop directive. 7385 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7386 return StmtError(); 7387 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7388 // If a reduction clause is present on the taskloop directive, the nogroup 7389 // clause must not be specified. 7390 if (checkReductionClauseWithNogroup(*this, Clauses)) 7391 return StmtError(); 7392 7393 setFunctionHasBranchProtectedScope(); 7394 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 7395 NestedLoopCount, Clauses, AStmt, B); 7396 } 7397 7398 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 7399 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7400 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7401 if (!AStmt) 7402 return StmtError(); 7403 7404 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7405 OMPLoopDirective::HelperExprs B; 7406 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7407 // define the nested loops number. 7408 unsigned NestedLoopCount = 7409 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 7410 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7411 VarsWithImplicitDSA, B); 7412 if (NestedLoopCount == 0) 7413 return StmtError(); 7414 7415 assert((CurContext->isDependentContext() || B.builtAll()) && 7416 "omp for loop exprs were not built"); 7417 7418 if (!CurContext->isDependentContext()) { 7419 // Finalize the clauses that need pre-built expressions for CodeGen. 7420 for (OMPClause *C : Clauses) { 7421 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7422 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7423 B.NumIterations, *this, CurScope, 7424 DSAStack)) 7425 return StmtError(); 7426 } 7427 } 7428 7429 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7430 // The grainsize clause and num_tasks clause are mutually exclusive and may 7431 // not appear on the same taskloop directive. 7432 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7433 return StmtError(); 7434 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7435 // If a reduction clause is present on the taskloop directive, the nogroup 7436 // clause must not be specified. 7437 if (checkReductionClauseWithNogroup(*this, Clauses)) 7438 return StmtError(); 7439 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7440 return StmtError(); 7441 7442 setFunctionHasBranchProtectedScope(); 7443 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 7444 NestedLoopCount, Clauses, AStmt, B); 7445 } 7446 7447 StmtResult Sema::ActOnOpenMPDistributeDirective( 7448 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7449 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7450 if (!AStmt) 7451 return StmtError(); 7452 7453 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7454 OMPLoopDirective::HelperExprs B; 7455 // In presence of clause 'collapse' with number of loops, it will 7456 // define the nested loops number. 7457 unsigned NestedLoopCount = 7458 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 7459 nullptr /*ordered not a clause on distribute*/, AStmt, 7460 *this, *DSAStack, VarsWithImplicitDSA, B); 7461 if (NestedLoopCount == 0) 7462 return StmtError(); 7463 7464 assert((CurContext->isDependentContext() || B.builtAll()) && 7465 "omp for loop exprs were not built"); 7466 7467 setFunctionHasBranchProtectedScope(); 7468 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 7469 NestedLoopCount, Clauses, AStmt, B); 7470 } 7471 7472 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 7473 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7474 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7475 if (!AStmt) 7476 return StmtError(); 7477 7478 auto *CS = cast<CapturedStmt>(AStmt); 7479 // 1.2.2 OpenMP Language Terminology 7480 // Structured block - An executable statement with a single entry at the 7481 // top and a single exit at the bottom. 7482 // The point of exit cannot be a branch out of the structured block. 7483 // longjmp() and throw() must not violate the entry/exit criteria. 7484 CS->getCapturedDecl()->setNothrow(); 7485 for (int ThisCaptureLevel = 7486 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 7487 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7488 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7489 // 1.2.2 OpenMP Language Terminology 7490 // Structured block - An executable statement with a single entry at the 7491 // top and a single exit at the bottom. 7492 // The point of exit cannot be a branch out of the structured block. 7493 // longjmp() and throw() must not violate the entry/exit criteria. 7494 CS->getCapturedDecl()->setNothrow(); 7495 } 7496 7497 OMPLoopDirective::HelperExprs B; 7498 // In presence of clause 'collapse' with number of loops, it will 7499 // define the nested loops number. 7500 unsigned NestedLoopCount = checkOpenMPLoop( 7501 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7502 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7503 VarsWithImplicitDSA, B); 7504 if (NestedLoopCount == 0) 7505 return StmtError(); 7506 7507 assert((CurContext->isDependentContext() || B.builtAll()) && 7508 "omp for loop exprs were not built"); 7509 7510 setFunctionHasBranchProtectedScope(); 7511 return OMPDistributeParallelForDirective::Create( 7512 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7513 DSAStack->isCancelRegion()); 7514 } 7515 7516 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 7517 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7518 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7519 if (!AStmt) 7520 return StmtError(); 7521 7522 auto *CS = cast<CapturedStmt>(AStmt); 7523 // 1.2.2 OpenMP Language Terminology 7524 // Structured block - An executable statement with a single entry at the 7525 // top and a single exit at the bottom. 7526 // The point of exit cannot be a branch out of the structured block. 7527 // longjmp() and throw() must not violate the entry/exit criteria. 7528 CS->getCapturedDecl()->setNothrow(); 7529 for (int ThisCaptureLevel = 7530 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 7531 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7532 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7533 // 1.2.2 OpenMP Language Terminology 7534 // Structured block - An executable statement with a single entry at the 7535 // top and a single exit at the bottom. 7536 // The point of exit cannot be a branch out of the structured block. 7537 // longjmp() and throw() must not violate the entry/exit criteria. 7538 CS->getCapturedDecl()->setNothrow(); 7539 } 7540 7541 OMPLoopDirective::HelperExprs B; 7542 // In presence of clause 'collapse' with number of loops, it will 7543 // define the nested loops number. 7544 unsigned NestedLoopCount = checkOpenMPLoop( 7545 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7546 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7547 VarsWithImplicitDSA, B); 7548 if (NestedLoopCount == 0) 7549 return StmtError(); 7550 7551 assert((CurContext->isDependentContext() || B.builtAll()) && 7552 "omp for loop exprs were not built"); 7553 7554 if (!CurContext->isDependentContext()) { 7555 // Finalize the clauses that need pre-built expressions for CodeGen. 7556 for (OMPClause *C : Clauses) { 7557 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7558 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7559 B.NumIterations, *this, CurScope, 7560 DSAStack)) 7561 return StmtError(); 7562 } 7563 } 7564 7565 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7566 return StmtError(); 7567 7568 setFunctionHasBranchProtectedScope(); 7569 return OMPDistributeParallelForSimdDirective::Create( 7570 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7571 } 7572 7573 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 7574 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7575 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7576 if (!AStmt) 7577 return StmtError(); 7578 7579 auto *CS = cast<CapturedStmt>(AStmt); 7580 // 1.2.2 OpenMP Language Terminology 7581 // Structured block - An executable statement with a single entry at the 7582 // top and a single exit at the bottom. 7583 // The point of exit cannot be a branch out of the structured block. 7584 // longjmp() and throw() must not violate the entry/exit criteria. 7585 CS->getCapturedDecl()->setNothrow(); 7586 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 7587 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7588 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7589 // 1.2.2 OpenMP Language Terminology 7590 // Structured block - An executable statement with a single entry at the 7591 // top and a single exit at the bottom. 7592 // The point of exit cannot be a branch out of the structured block. 7593 // longjmp() and throw() must not violate the entry/exit criteria. 7594 CS->getCapturedDecl()->setNothrow(); 7595 } 7596 7597 OMPLoopDirective::HelperExprs B; 7598 // In presence of clause 'collapse' with number of loops, it will 7599 // define the nested loops number. 7600 unsigned NestedLoopCount = 7601 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 7602 nullptr /*ordered not a clause on distribute*/, CS, *this, 7603 *DSAStack, VarsWithImplicitDSA, B); 7604 if (NestedLoopCount == 0) 7605 return StmtError(); 7606 7607 assert((CurContext->isDependentContext() || B.builtAll()) && 7608 "omp for loop exprs were not built"); 7609 7610 if (!CurContext->isDependentContext()) { 7611 // Finalize the clauses that need pre-built expressions for CodeGen. 7612 for (OMPClause *C : Clauses) { 7613 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7614 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7615 B.NumIterations, *this, CurScope, 7616 DSAStack)) 7617 return StmtError(); 7618 } 7619 } 7620 7621 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7622 return StmtError(); 7623 7624 setFunctionHasBranchProtectedScope(); 7625 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 7626 NestedLoopCount, Clauses, AStmt, B); 7627 } 7628 7629 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 7630 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7631 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7632 if (!AStmt) 7633 return StmtError(); 7634 7635 auto *CS = cast<CapturedStmt>(AStmt); 7636 // 1.2.2 OpenMP Language Terminology 7637 // Structured block - An executable statement with a single entry at the 7638 // top and a single exit at the bottom. 7639 // The point of exit cannot be a branch out of the structured block. 7640 // longjmp() and throw() must not violate the entry/exit criteria. 7641 CS->getCapturedDecl()->setNothrow(); 7642 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7643 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7644 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7645 // 1.2.2 OpenMP Language Terminology 7646 // Structured block - An executable statement with a single entry at the 7647 // top and a single exit at the bottom. 7648 // The point of exit cannot be a branch out of the structured block. 7649 // longjmp() and throw() must not violate the entry/exit criteria. 7650 CS->getCapturedDecl()->setNothrow(); 7651 } 7652 7653 OMPLoopDirective::HelperExprs B; 7654 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7655 // define the nested loops number. 7656 unsigned NestedLoopCount = checkOpenMPLoop( 7657 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 7658 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7659 VarsWithImplicitDSA, B); 7660 if (NestedLoopCount == 0) 7661 return StmtError(); 7662 7663 assert((CurContext->isDependentContext() || B.builtAll()) && 7664 "omp target parallel for simd loop exprs were not built"); 7665 7666 if (!CurContext->isDependentContext()) { 7667 // Finalize the clauses that need pre-built expressions for CodeGen. 7668 for (OMPClause *C : Clauses) { 7669 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7670 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7671 B.NumIterations, *this, CurScope, 7672 DSAStack)) 7673 return StmtError(); 7674 } 7675 } 7676 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7677 return StmtError(); 7678 7679 setFunctionHasBranchProtectedScope(); 7680 return OMPTargetParallelForSimdDirective::Create( 7681 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7682 } 7683 7684 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 7685 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7686 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7687 if (!AStmt) 7688 return StmtError(); 7689 7690 auto *CS = cast<CapturedStmt>(AStmt); 7691 // 1.2.2 OpenMP Language Terminology 7692 // Structured block - An executable statement with a single entry at the 7693 // top and a single exit at the bottom. 7694 // The point of exit cannot be a branch out of the structured block. 7695 // longjmp() and throw() must not violate the entry/exit criteria. 7696 CS->getCapturedDecl()->setNothrow(); 7697 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 7698 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7699 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7700 // 1.2.2 OpenMP Language Terminology 7701 // Structured block - An executable statement with a single entry at the 7702 // top and a single exit at the bottom. 7703 // The point of exit cannot be a branch out of the structured block. 7704 // longjmp() and throw() must not violate the entry/exit criteria. 7705 CS->getCapturedDecl()->setNothrow(); 7706 } 7707 7708 OMPLoopDirective::HelperExprs B; 7709 // In presence of clause 'collapse' with number of loops, it will define the 7710 // nested loops number. 7711 unsigned NestedLoopCount = 7712 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 7713 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7714 VarsWithImplicitDSA, B); 7715 if (NestedLoopCount == 0) 7716 return StmtError(); 7717 7718 assert((CurContext->isDependentContext() || B.builtAll()) && 7719 "omp target simd loop exprs were not built"); 7720 7721 if (!CurContext->isDependentContext()) { 7722 // Finalize the clauses that need pre-built expressions for CodeGen. 7723 for (OMPClause *C : Clauses) { 7724 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7725 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7726 B.NumIterations, *this, CurScope, 7727 DSAStack)) 7728 return StmtError(); 7729 } 7730 } 7731 7732 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7733 return StmtError(); 7734 7735 setFunctionHasBranchProtectedScope(); 7736 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 7737 NestedLoopCount, Clauses, AStmt, B); 7738 } 7739 7740 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 7741 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7742 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7743 if (!AStmt) 7744 return StmtError(); 7745 7746 auto *CS = cast<CapturedStmt>(AStmt); 7747 // 1.2.2 OpenMP Language Terminology 7748 // Structured block - An executable statement with a single entry at the 7749 // top and a single exit at the bottom. 7750 // The point of exit cannot be a branch out of the structured block. 7751 // longjmp() and throw() must not violate the entry/exit criteria. 7752 CS->getCapturedDecl()->setNothrow(); 7753 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 7754 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7755 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7756 // 1.2.2 OpenMP Language Terminology 7757 // Structured block - An executable statement with a single entry at the 7758 // top and a single exit at the bottom. 7759 // The point of exit cannot be a branch out of the structured block. 7760 // longjmp() and throw() must not violate the entry/exit criteria. 7761 CS->getCapturedDecl()->setNothrow(); 7762 } 7763 7764 OMPLoopDirective::HelperExprs B; 7765 // In presence of clause 'collapse' with number of loops, it will 7766 // define the nested loops number. 7767 unsigned NestedLoopCount = 7768 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 7769 nullptr /*ordered not a clause on distribute*/, CS, *this, 7770 *DSAStack, VarsWithImplicitDSA, B); 7771 if (NestedLoopCount == 0) 7772 return StmtError(); 7773 7774 assert((CurContext->isDependentContext() || B.builtAll()) && 7775 "omp teams distribute loop exprs were not built"); 7776 7777 setFunctionHasBranchProtectedScope(); 7778 7779 DSAStack->setParentTeamsRegionLoc(StartLoc); 7780 7781 return OMPTeamsDistributeDirective::Create( 7782 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7783 } 7784 7785 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 7786 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7787 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7788 if (!AStmt) 7789 return StmtError(); 7790 7791 auto *CS = cast<CapturedStmt>(AStmt); 7792 // 1.2.2 OpenMP Language Terminology 7793 // Structured block - An executable statement with a single entry at the 7794 // top and a single exit at the bottom. 7795 // The point of exit cannot be a branch out of the structured block. 7796 // longjmp() and throw() must not violate the entry/exit criteria. 7797 CS->getCapturedDecl()->setNothrow(); 7798 for (int ThisCaptureLevel = 7799 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 7800 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7801 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7802 // 1.2.2 OpenMP Language Terminology 7803 // Structured block - An executable statement with a single entry at the 7804 // top and a single exit at the bottom. 7805 // The point of exit cannot be a branch out of the structured block. 7806 // longjmp() and throw() must not violate the entry/exit criteria. 7807 CS->getCapturedDecl()->setNothrow(); 7808 } 7809 7810 7811 OMPLoopDirective::HelperExprs B; 7812 // In presence of clause 'collapse' with number of loops, it will 7813 // define the nested loops number. 7814 unsigned NestedLoopCount = checkOpenMPLoop( 7815 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7816 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7817 VarsWithImplicitDSA, B); 7818 7819 if (NestedLoopCount == 0) 7820 return StmtError(); 7821 7822 assert((CurContext->isDependentContext() || B.builtAll()) && 7823 "omp teams distribute simd loop exprs were not built"); 7824 7825 if (!CurContext->isDependentContext()) { 7826 // Finalize the clauses that need pre-built expressions for CodeGen. 7827 for (OMPClause *C : Clauses) { 7828 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7829 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7830 B.NumIterations, *this, CurScope, 7831 DSAStack)) 7832 return StmtError(); 7833 } 7834 } 7835 7836 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7837 return StmtError(); 7838 7839 setFunctionHasBranchProtectedScope(); 7840 7841 DSAStack->setParentTeamsRegionLoc(StartLoc); 7842 7843 return OMPTeamsDistributeSimdDirective::Create( 7844 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7845 } 7846 7847 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 7848 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7849 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7850 if (!AStmt) 7851 return StmtError(); 7852 7853 auto *CS = cast<CapturedStmt>(AStmt); 7854 // 1.2.2 OpenMP Language Terminology 7855 // Structured block - An executable statement with a single entry at the 7856 // top and a single exit at the bottom. 7857 // The point of exit cannot be a branch out of the structured block. 7858 // longjmp() and throw() must not violate the entry/exit criteria. 7859 CS->getCapturedDecl()->setNothrow(); 7860 7861 for (int ThisCaptureLevel = 7862 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 7863 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7864 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7865 // 1.2.2 OpenMP Language Terminology 7866 // Structured block - An executable statement with a single entry at the 7867 // top and a single exit at the bottom. 7868 // The point of exit cannot be a branch out of the structured block. 7869 // longjmp() and throw() must not violate the entry/exit criteria. 7870 CS->getCapturedDecl()->setNothrow(); 7871 } 7872 7873 OMPLoopDirective::HelperExprs B; 7874 // In presence of clause 'collapse' with number of loops, it will 7875 // define the nested loops number. 7876 unsigned NestedLoopCount = checkOpenMPLoop( 7877 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7878 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7879 VarsWithImplicitDSA, B); 7880 7881 if (NestedLoopCount == 0) 7882 return StmtError(); 7883 7884 assert((CurContext->isDependentContext() || B.builtAll()) && 7885 "omp for loop exprs were not built"); 7886 7887 if (!CurContext->isDependentContext()) { 7888 // Finalize the clauses that need pre-built expressions for CodeGen. 7889 for (OMPClause *C : Clauses) { 7890 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7891 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7892 B.NumIterations, *this, CurScope, 7893 DSAStack)) 7894 return StmtError(); 7895 } 7896 } 7897 7898 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7899 return StmtError(); 7900 7901 setFunctionHasBranchProtectedScope(); 7902 7903 DSAStack->setParentTeamsRegionLoc(StartLoc); 7904 7905 return OMPTeamsDistributeParallelForSimdDirective::Create( 7906 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7907 } 7908 7909 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 7910 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7911 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7912 if (!AStmt) 7913 return StmtError(); 7914 7915 auto *CS = cast<CapturedStmt>(AStmt); 7916 // 1.2.2 OpenMP Language Terminology 7917 // Structured block - An executable statement with a single entry at the 7918 // top and a single exit at the bottom. 7919 // The point of exit cannot be a branch out of the structured block. 7920 // longjmp() and throw() must not violate the entry/exit criteria. 7921 CS->getCapturedDecl()->setNothrow(); 7922 7923 for (int ThisCaptureLevel = 7924 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 7925 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7926 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7927 // 1.2.2 OpenMP Language Terminology 7928 // Structured block - An executable statement with a single entry at the 7929 // top and a single exit at the bottom. 7930 // The point of exit cannot be a branch out of the structured block. 7931 // longjmp() and throw() must not violate the entry/exit criteria. 7932 CS->getCapturedDecl()->setNothrow(); 7933 } 7934 7935 OMPLoopDirective::HelperExprs B; 7936 // In presence of clause 'collapse' with number of loops, it will 7937 // define the nested loops number. 7938 unsigned NestedLoopCount = checkOpenMPLoop( 7939 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7940 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7941 VarsWithImplicitDSA, B); 7942 7943 if (NestedLoopCount == 0) 7944 return StmtError(); 7945 7946 assert((CurContext->isDependentContext() || B.builtAll()) && 7947 "omp for loop exprs were not built"); 7948 7949 setFunctionHasBranchProtectedScope(); 7950 7951 DSAStack->setParentTeamsRegionLoc(StartLoc); 7952 7953 return OMPTeamsDistributeParallelForDirective::Create( 7954 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7955 DSAStack->isCancelRegion()); 7956 } 7957 7958 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 7959 Stmt *AStmt, 7960 SourceLocation StartLoc, 7961 SourceLocation EndLoc) { 7962 if (!AStmt) 7963 return StmtError(); 7964 7965 auto *CS = cast<CapturedStmt>(AStmt); 7966 // 1.2.2 OpenMP Language Terminology 7967 // Structured block - An executable statement with a single entry at the 7968 // top and a single exit at the bottom. 7969 // The point of exit cannot be a branch out of the structured block. 7970 // longjmp() and throw() must not violate the entry/exit criteria. 7971 CS->getCapturedDecl()->setNothrow(); 7972 7973 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 7974 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7975 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7976 // 1.2.2 OpenMP Language Terminology 7977 // Structured block - An executable statement with a single entry at the 7978 // top and a single exit at the bottom. 7979 // The point of exit cannot be a branch out of the structured block. 7980 // longjmp() and throw() must not violate the entry/exit criteria. 7981 CS->getCapturedDecl()->setNothrow(); 7982 } 7983 setFunctionHasBranchProtectedScope(); 7984 7985 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 7986 AStmt); 7987 } 7988 7989 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 7990 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7991 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7992 if (!AStmt) 7993 return StmtError(); 7994 7995 auto *CS = cast<CapturedStmt>(AStmt); 7996 // 1.2.2 OpenMP Language Terminology 7997 // Structured block - An executable statement with a single entry at the 7998 // top and a single exit at the bottom. 7999 // The point of exit cannot be a branch out of the structured block. 8000 // longjmp() and throw() must not violate the entry/exit criteria. 8001 CS->getCapturedDecl()->setNothrow(); 8002 for (int ThisCaptureLevel = 8003 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8004 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8005 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8006 // 1.2.2 OpenMP Language Terminology 8007 // Structured block - An executable statement with a single entry at the 8008 // top and a single exit at the bottom. 8009 // The point of exit cannot be a branch out of the structured block. 8010 // longjmp() and throw() must not violate the entry/exit criteria. 8011 CS->getCapturedDecl()->setNothrow(); 8012 } 8013 8014 OMPLoopDirective::HelperExprs B; 8015 // In presence of clause 'collapse' with number of loops, it will 8016 // define the nested loops number. 8017 unsigned NestedLoopCount = checkOpenMPLoop( 8018 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8019 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8020 VarsWithImplicitDSA, B); 8021 if (NestedLoopCount == 0) 8022 return StmtError(); 8023 8024 assert((CurContext->isDependentContext() || B.builtAll()) && 8025 "omp target teams distribute loop exprs were not built"); 8026 8027 setFunctionHasBranchProtectedScope(); 8028 return OMPTargetTeamsDistributeDirective::Create( 8029 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8030 } 8031 8032 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8033 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8034 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8035 if (!AStmt) 8036 return StmtError(); 8037 8038 auto *CS = cast<CapturedStmt>(AStmt); 8039 // 1.2.2 OpenMP Language Terminology 8040 // Structured block - An executable statement with a single entry at the 8041 // top and a single exit at the bottom. 8042 // The point of exit cannot be a branch out of the structured block. 8043 // longjmp() and throw() must not violate the entry/exit criteria. 8044 CS->getCapturedDecl()->setNothrow(); 8045 for (int ThisCaptureLevel = 8046 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8047 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8048 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8049 // 1.2.2 OpenMP Language Terminology 8050 // Structured block - An executable statement with a single entry at the 8051 // top and a single exit at the bottom. 8052 // The point of exit cannot be a branch out of the structured block. 8053 // longjmp() and throw() must not violate the entry/exit criteria. 8054 CS->getCapturedDecl()->setNothrow(); 8055 } 8056 8057 OMPLoopDirective::HelperExprs B; 8058 // In presence of clause 'collapse' with number of loops, it will 8059 // define the nested loops number. 8060 unsigned NestedLoopCount = checkOpenMPLoop( 8061 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8062 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8063 VarsWithImplicitDSA, B); 8064 if (NestedLoopCount == 0) 8065 return StmtError(); 8066 8067 assert((CurContext->isDependentContext() || B.builtAll()) && 8068 "omp target teams distribute parallel for loop exprs were not built"); 8069 8070 if (!CurContext->isDependentContext()) { 8071 // Finalize the clauses that need pre-built expressions for CodeGen. 8072 for (OMPClause *C : Clauses) { 8073 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8074 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8075 B.NumIterations, *this, CurScope, 8076 DSAStack)) 8077 return StmtError(); 8078 } 8079 } 8080 8081 setFunctionHasBranchProtectedScope(); 8082 return OMPTargetTeamsDistributeParallelForDirective::Create( 8083 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8084 DSAStack->isCancelRegion()); 8085 } 8086 8087 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 8088 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8089 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8090 if (!AStmt) 8091 return StmtError(); 8092 8093 auto *CS = cast<CapturedStmt>(AStmt); 8094 // 1.2.2 OpenMP Language Terminology 8095 // Structured block - An executable statement with a single entry at the 8096 // top and a single exit at the bottom. 8097 // The point of exit cannot be a branch out of the structured block. 8098 // longjmp() and throw() must not violate the entry/exit criteria. 8099 CS->getCapturedDecl()->setNothrow(); 8100 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 8101 OMPD_target_teams_distribute_parallel_for_simd); 8102 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8103 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8104 // 1.2.2 OpenMP Language Terminology 8105 // Structured block - An executable statement with a single entry at the 8106 // top and a single exit at the bottom. 8107 // The point of exit cannot be a branch out of the structured block. 8108 // longjmp() and throw() must not violate the entry/exit criteria. 8109 CS->getCapturedDecl()->setNothrow(); 8110 } 8111 8112 OMPLoopDirective::HelperExprs B; 8113 // In presence of clause 'collapse' with number of loops, it will 8114 // define the nested loops number. 8115 unsigned NestedLoopCount = 8116 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 8117 getCollapseNumberExpr(Clauses), 8118 nullptr /*ordered not a clause on distribute*/, CS, *this, 8119 *DSAStack, VarsWithImplicitDSA, B); 8120 if (NestedLoopCount == 0) 8121 return StmtError(); 8122 8123 assert((CurContext->isDependentContext() || B.builtAll()) && 8124 "omp target teams distribute parallel for simd loop exprs were not " 8125 "built"); 8126 8127 if (!CurContext->isDependentContext()) { 8128 // Finalize the clauses that need pre-built expressions for CodeGen. 8129 for (OMPClause *C : Clauses) { 8130 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8131 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8132 B.NumIterations, *this, CurScope, 8133 DSAStack)) 8134 return StmtError(); 8135 } 8136 } 8137 8138 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8139 return StmtError(); 8140 8141 setFunctionHasBranchProtectedScope(); 8142 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 8143 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8144 } 8145 8146 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 8147 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8148 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8149 if (!AStmt) 8150 return StmtError(); 8151 8152 auto *CS = cast<CapturedStmt>(AStmt); 8153 // 1.2.2 OpenMP Language Terminology 8154 // Structured block - An executable statement with a single entry at the 8155 // top and a single exit at the bottom. 8156 // The point of exit cannot be a branch out of the structured block. 8157 // longjmp() and throw() must not violate the entry/exit criteria. 8158 CS->getCapturedDecl()->setNothrow(); 8159 for (int ThisCaptureLevel = 8160 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 8161 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8162 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8163 // 1.2.2 OpenMP Language Terminology 8164 // Structured block - An executable statement with a single entry at the 8165 // top and a single exit at the bottom. 8166 // The point of exit cannot be a branch out of the structured block. 8167 // longjmp() and throw() must not violate the entry/exit criteria. 8168 CS->getCapturedDecl()->setNothrow(); 8169 } 8170 8171 OMPLoopDirective::HelperExprs B; 8172 // In presence of clause 'collapse' with number of loops, it will 8173 // define the nested loops number. 8174 unsigned NestedLoopCount = checkOpenMPLoop( 8175 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8176 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8177 VarsWithImplicitDSA, B); 8178 if (NestedLoopCount == 0) 8179 return StmtError(); 8180 8181 assert((CurContext->isDependentContext() || B.builtAll()) && 8182 "omp target teams distribute simd loop exprs were not built"); 8183 8184 if (!CurContext->isDependentContext()) { 8185 // Finalize the clauses that need pre-built expressions for CodeGen. 8186 for (OMPClause *C : Clauses) { 8187 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8188 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8189 B.NumIterations, *this, CurScope, 8190 DSAStack)) 8191 return StmtError(); 8192 } 8193 } 8194 8195 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8196 return StmtError(); 8197 8198 setFunctionHasBranchProtectedScope(); 8199 return OMPTargetTeamsDistributeSimdDirective::Create( 8200 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8201 } 8202 8203 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 8204 SourceLocation StartLoc, 8205 SourceLocation LParenLoc, 8206 SourceLocation EndLoc) { 8207 OMPClause *Res = nullptr; 8208 switch (Kind) { 8209 case OMPC_final: 8210 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 8211 break; 8212 case OMPC_num_threads: 8213 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 8214 break; 8215 case OMPC_safelen: 8216 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 8217 break; 8218 case OMPC_simdlen: 8219 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 8220 break; 8221 case OMPC_collapse: 8222 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 8223 break; 8224 case OMPC_ordered: 8225 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 8226 break; 8227 case OMPC_device: 8228 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 8229 break; 8230 case OMPC_num_teams: 8231 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 8232 break; 8233 case OMPC_thread_limit: 8234 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 8235 break; 8236 case OMPC_priority: 8237 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 8238 break; 8239 case OMPC_grainsize: 8240 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 8241 break; 8242 case OMPC_num_tasks: 8243 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 8244 break; 8245 case OMPC_hint: 8246 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 8247 break; 8248 case OMPC_if: 8249 case OMPC_default: 8250 case OMPC_proc_bind: 8251 case OMPC_schedule: 8252 case OMPC_private: 8253 case OMPC_firstprivate: 8254 case OMPC_lastprivate: 8255 case OMPC_shared: 8256 case OMPC_reduction: 8257 case OMPC_task_reduction: 8258 case OMPC_in_reduction: 8259 case OMPC_linear: 8260 case OMPC_aligned: 8261 case OMPC_copyin: 8262 case OMPC_copyprivate: 8263 case OMPC_nowait: 8264 case OMPC_untied: 8265 case OMPC_mergeable: 8266 case OMPC_threadprivate: 8267 case OMPC_flush: 8268 case OMPC_read: 8269 case OMPC_write: 8270 case OMPC_update: 8271 case OMPC_capture: 8272 case OMPC_seq_cst: 8273 case OMPC_depend: 8274 case OMPC_threads: 8275 case OMPC_simd: 8276 case OMPC_map: 8277 case OMPC_nogroup: 8278 case OMPC_dist_schedule: 8279 case OMPC_defaultmap: 8280 case OMPC_unknown: 8281 case OMPC_uniform: 8282 case OMPC_to: 8283 case OMPC_from: 8284 case OMPC_use_device_ptr: 8285 case OMPC_is_device_ptr: 8286 case OMPC_unified_address: 8287 case OMPC_unified_shared_memory: 8288 case OMPC_reverse_offload: 8289 case OMPC_dynamic_allocators: 8290 case OMPC_atomic_default_mem_order: 8291 llvm_unreachable("Clause is not allowed."); 8292 } 8293 return Res; 8294 } 8295 8296 // An OpenMP directive such as 'target parallel' has two captured regions: 8297 // for the 'target' and 'parallel' respectively. This function returns 8298 // the region in which to capture expressions associated with a clause. 8299 // A return value of OMPD_unknown signifies that the expression should not 8300 // be captured. 8301 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 8302 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 8303 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 8304 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8305 switch (CKind) { 8306 case OMPC_if: 8307 switch (DKind) { 8308 case OMPD_target_parallel: 8309 case OMPD_target_parallel_for: 8310 case OMPD_target_parallel_for_simd: 8311 // If this clause applies to the nested 'parallel' region, capture within 8312 // the 'target' region, otherwise do not capture. 8313 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8314 CaptureRegion = OMPD_target; 8315 break; 8316 case OMPD_target_teams_distribute_parallel_for: 8317 case OMPD_target_teams_distribute_parallel_for_simd: 8318 // If this clause applies to the nested 'parallel' region, capture within 8319 // the 'teams' region, otherwise do not capture. 8320 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8321 CaptureRegion = OMPD_teams; 8322 break; 8323 case OMPD_teams_distribute_parallel_for: 8324 case OMPD_teams_distribute_parallel_for_simd: 8325 CaptureRegion = OMPD_teams; 8326 break; 8327 case OMPD_target_update: 8328 case OMPD_target_enter_data: 8329 case OMPD_target_exit_data: 8330 CaptureRegion = OMPD_task; 8331 break; 8332 case OMPD_cancel: 8333 case OMPD_parallel: 8334 case OMPD_parallel_sections: 8335 case OMPD_parallel_for: 8336 case OMPD_parallel_for_simd: 8337 case OMPD_target: 8338 case OMPD_target_simd: 8339 case OMPD_target_teams: 8340 case OMPD_target_teams_distribute: 8341 case OMPD_target_teams_distribute_simd: 8342 case OMPD_distribute_parallel_for: 8343 case OMPD_distribute_parallel_for_simd: 8344 case OMPD_task: 8345 case OMPD_taskloop: 8346 case OMPD_taskloop_simd: 8347 case OMPD_target_data: 8348 // Do not capture if-clause expressions. 8349 break; 8350 case OMPD_threadprivate: 8351 case OMPD_taskyield: 8352 case OMPD_barrier: 8353 case OMPD_taskwait: 8354 case OMPD_cancellation_point: 8355 case OMPD_flush: 8356 case OMPD_declare_reduction: 8357 case OMPD_declare_simd: 8358 case OMPD_declare_target: 8359 case OMPD_end_declare_target: 8360 case OMPD_teams: 8361 case OMPD_simd: 8362 case OMPD_for: 8363 case OMPD_for_simd: 8364 case OMPD_sections: 8365 case OMPD_section: 8366 case OMPD_single: 8367 case OMPD_master: 8368 case OMPD_critical: 8369 case OMPD_taskgroup: 8370 case OMPD_distribute: 8371 case OMPD_ordered: 8372 case OMPD_atomic: 8373 case OMPD_distribute_simd: 8374 case OMPD_teams_distribute: 8375 case OMPD_teams_distribute_simd: 8376 case OMPD_requires: 8377 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 8378 case OMPD_unknown: 8379 llvm_unreachable("Unknown OpenMP directive"); 8380 } 8381 break; 8382 case OMPC_num_threads: 8383 switch (DKind) { 8384 case OMPD_target_parallel: 8385 case OMPD_target_parallel_for: 8386 case OMPD_target_parallel_for_simd: 8387 CaptureRegion = OMPD_target; 8388 break; 8389 case OMPD_teams_distribute_parallel_for: 8390 case OMPD_teams_distribute_parallel_for_simd: 8391 case OMPD_target_teams_distribute_parallel_for: 8392 case OMPD_target_teams_distribute_parallel_for_simd: 8393 CaptureRegion = OMPD_teams; 8394 break; 8395 case OMPD_parallel: 8396 case OMPD_parallel_sections: 8397 case OMPD_parallel_for: 8398 case OMPD_parallel_for_simd: 8399 case OMPD_distribute_parallel_for: 8400 case OMPD_distribute_parallel_for_simd: 8401 // Do not capture num_threads-clause expressions. 8402 break; 8403 case OMPD_target_data: 8404 case OMPD_target_enter_data: 8405 case OMPD_target_exit_data: 8406 case OMPD_target_update: 8407 case OMPD_target: 8408 case OMPD_target_simd: 8409 case OMPD_target_teams: 8410 case OMPD_target_teams_distribute: 8411 case OMPD_target_teams_distribute_simd: 8412 case OMPD_cancel: 8413 case OMPD_task: 8414 case OMPD_taskloop: 8415 case OMPD_taskloop_simd: 8416 case OMPD_threadprivate: 8417 case OMPD_taskyield: 8418 case OMPD_barrier: 8419 case OMPD_taskwait: 8420 case OMPD_cancellation_point: 8421 case OMPD_flush: 8422 case OMPD_declare_reduction: 8423 case OMPD_declare_simd: 8424 case OMPD_declare_target: 8425 case OMPD_end_declare_target: 8426 case OMPD_teams: 8427 case OMPD_simd: 8428 case OMPD_for: 8429 case OMPD_for_simd: 8430 case OMPD_sections: 8431 case OMPD_section: 8432 case OMPD_single: 8433 case OMPD_master: 8434 case OMPD_critical: 8435 case OMPD_taskgroup: 8436 case OMPD_distribute: 8437 case OMPD_ordered: 8438 case OMPD_atomic: 8439 case OMPD_distribute_simd: 8440 case OMPD_teams_distribute: 8441 case OMPD_teams_distribute_simd: 8442 case OMPD_requires: 8443 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 8444 case OMPD_unknown: 8445 llvm_unreachable("Unknown OpenMP directive"); 8446 } 8447 break; 8448 case OMPC_num_teams: 8449 switch (DKind) { 8450 case OMPD_target_teams: 8451 case OMPD_target_teams_distribute: 8452 case OMPD_target_teams_distribute_simd: 8453 case OMPD_target_teams_distribute_parallel_for: 8454 case OMPD_target_teams_distribute_parallel_for_simd: 8455 CaptureRegion = OMPD_target; 8456 break; 8457 case OMPD_teams_distribute_parallel_for: 8458 case OMPD_teams_distribute_parallel_for_simd: 8459 case OMPD_teams: 8460 case OMPD_teams_distribute: 8461 case OMPD_teams_distribute_simd: 8462 // Do not capture num_teams-clause expressions. 8463 break; 8464 case OMPD_distribute_parallel_for: 8465 case OMPD_distribute_parallel_for_simd: 8466 case OMPD_task: 8467 case OMPD_taskloop: 8468 case OMPD_taskloop_simd: 8469 case OMPD_target_data: 8470 case OMPD_target_enter_data: 8471 case OMPD_target_exit_data: 8472 case OMPD_target_update: 8473 case OMPD_cancel: 8474 case OMPD_parallel: 8475 case OMPD_parallel_sections: 8476 case OMPD_parallel_for: 8477 case OMPD_parallel_for_simd: 8478 case OMPD_target: 8479 case OMPD_target_simd: 8480 case OMPD_target_parallel: 8481 case OMPD_target_parallel_for: 8482 case OMPD_target_parallel_for_simd: 8483 case OMPD_threadprivate: 8484 case OMPD_taskyield: 8485 case OMPD_barrier: 8486 case OMPD_taskwait: 8487 case OMPD_cancellation_point: 8488 case OMPD_flush: 8489 case OMPD_declare_reduction: 8490 case OMPD_declare_simd: 8491 case OMPD_declare_target: 8492 case OMPD_end_declare_target: 8493 case OMPD_simd: 8494 case OMPD_for: 8495 case OMPD_for_simd: 8496 case OMPD_sections: 8497 case OMPD_section: 8498 case OMPD_single: 8499 case OMPD_master: 8500 case OMPD_critical: 8501 case OMPD_taskgroup: 8502 case OMPD_distribute: 8503 case OMPD_ordered: 8504 case OMPD_atomic: 8505 case OMPD_distribute_simd: 8506 case OMPD_requires: 8507 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8508 case OMPD_unknown: 8509 llvm_unreachable("Unknown OpenMP directive"); 8510 } 8511 break; 8512 case OMPC_thread_limit: 8513 switch (DKind) { 8514 case OMPD_target_teams: 8515 case OMPD_target_teams_distribute: 8516 case OMPD_target_teams_distribute_simd: 8517 case OMPD_target_teams_distribute_parallel_for: 8518 case OMPD_target_teams_distribute_parallel_for_simd: 8519 CaptureRegion = OMPD_target; 8520 break; 8521 case OMPD_teams_distribute_parallel_for: 8522 case OMPD_teams_distribute_parallel_for_simd: 8523 case OMPD_teams: 8524 case OMPD_teams_distribute: 8525 case OMPD_teams_distribute_simd: 8526 // Do not capture thread_limit-clause expressions. 8527 break; 8528 case OMPD_distribute_parallel_for: 8529 case OMPD_distribute_parallel_for_simd: 8530 case OMPD_task: 8531 case OMPD_taskloop: 8532 case OMPD_taskloop_simd: 8533 case OMPD_target_data: 8534 case OMPD_target_enter_data: 8535 case OMPD_target_exit_data: 8536 case OMPD_target_update: 8537 case OMPD_cancel: 8538 case OMPD_parallel: 8539 case OMPD_parallel_sections: 8540 case OMPD_parallel_for: 8541 case OMPD_parallel_for_simd: 8542 case OMPD_target: 8543 case OMPD_target_simd: 8544 case OMPD_target_parallel: 8545 case OMPD_target_parallel_for: 8546 case OMPD_target_parallel_for_simd: 8547 case OMPD_threadprivate: 8548 case OMPD_taskyield: 8549 case OMPD_barrier: 8550 case OMPD_taskwait: 8551 case OMPD_cancellation_point: 8552 case OMPD_flush: 8553 case OMPD_declare_reduction: 8554 case OMPD_declare_simd: 8555 case OMPD_declare_target: 8556 case OMPD_end_declare_target: 8557 case OMPD_simd: 8558 case OMPD_for: 8559 case OMPD_for_simd: 8560 case OMPD_sections: 8561 case OMPD_section: 8562 case OMPD_single: 8563 case OMPD_master: 8564 case OMPD_critical: 8565 case OMPD_taskgroup: 8566 case OMPD_distribute: 8567 case OMPD_ordered: 8568 case OMPD_atomic: 8569 case OMPD_distribute_simd: 8570 case OMPD_requires: 8571 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 8572 case OMPD_unknown: 8573 llvm_unreachable("Unknown OpenMP directive"); 8574 } 8575 break; 8576 case OMPC_schedule: 8577 switch (DKind) { 8578 case OMPD_parallel_for: 8579 case OMPD_parallel_for_simd: 8580 case OMPD_distribute_parallel_for: 8581 case OMPD_distribute_parallel_for_simd: 8582 case OMPD_teams_distribute_parallel_for: 8583 case OMPD_teams_distribute_parallel_for_simd: 8584 case OMPD_target_parallel_for: 8585 case OMPD_target_parallel_for_simd: 8586 case OMPD_target_teams_distribute_parallel_for: 8587 case OMPD_target_teams_distribute_parallel_for_simd: 8588 CaptureRegion = OMPD_parallel; 8589 break; 8590 case OMPD_for: 8591 case OMPD_for_simd: 8592 // Do not capture schedule-clause expressions. 8593 break; 8594 case OMPD_task: 8595 case OMPD_taskloop: 8596 case OMPD_taskloop_simd: 8597 case OMPD_target_data: 8598 case OMPD_target_enter_data: 8599 case OMPD_target_exit_data: 8600 case OMPD_target_update: 8601 case OMPD_teams: 8602 case OMPD_teams_distribute: 8603 case OMPD_teams_distribute_simd: 8604 case OMPD_target_teams_distribute: 8605 case OMPD_target_teams_distribute_simd: 8606 case OMPD_target: 8607 case OMPD_target_simd: 8608 case OMPD_target_parallel: 8609 case OMPD_cancel: 8610 case OMPD_parallel: 8611 case OMPD_parallel_sections: 8612 case OMPD_threadprivate: 8613 case OMPD_taskyield: 8614 case OMPD_barrier: 8615 case OMPD_taskwait: 8616 case OMPD_cancellation_point: 8617 case OMPD_flush: 8618 case OMPD_declare_reduction: 8619 case OMPD_declare_simd: 8620 case OMPD_declare_target: 8621 case OMPD_end_declare_target: 8622 case OMPD_simd: 8623 case OMPD_sections: 8624 case OMPD_section: 8625 case OMPD_single: 8626 case OMPD_master: 8627 case OMPD_critical: 8628 case OMPD_taskgroup: 8629 case OMPD_distribute: 8630 case OMPD_ordered: 8631 case OMPD_atomic: 8632 case OMPD_distribute_simd: 8633 case OMPD_target_teams: 8634 case OMPD_requires: 8635 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8636 case OMPD_unknown: 8637 llvm_unreachable("Unknown OpenMP directive"); 8638 } 8639 break; 8640 case OMPC_dist_schedule: 8641 switch (DKind) { 8642 case OMPD_teams_distribute_parallel_for: 8643 case OMPD_teams_distribute_parallel_for_simd: 8644 case OMPD_teams_distribute: 8645 case OMPD_teams_distribute_simd: 8646 case OMPD_target_teams_distribute_parallel_for: 8647 case OMPD_target_teams_distribute_parallel_for_simd: 8648 case OMPD_target_teams_distribute: 8649 case OMPD_target_teams_distribute_simd: 8650 CaptureRegion = OMPD_teams; 8651 break; 8652 case OMPD_distribute_parallel_for: 8653 case OMPD_distribute_parallel_for_simd: 8654 case OMPD_distribute: 8655 case OMPD_distribute_simd: 8656 // Do not capture thread_limit-clause expressions. 8657 break; 8658 case OMPD_parallel_for: 8659 case OMPD_parallel_for_simd: 8660 case OMPD_target_parallel_for_simd: 8661 case OMPD_target_parallel_for: 8662 case OMPD_task: 8663 case OMPD_taskloop: 8664 case OMPD_taskloop_simd: 8665 case OMPD_target_data: 8666 case OMPD_target_enter_data: 8667 case OMPD_target_exit_data: 8668 case OMPD_target_update: 8669 case OMPD_teams: 8670 case OMPD_target: 8671 case OMPD_target_simd: 8672 case OMPD_target_parallel: 8673 case OMPD_cancel: 8674 case OMPD_parallel: 8675 case OMPD_parallel_sections: 8676 case OMPD_threadprivate: 8677 case OMPD_taskyield: 8678 case OMPD_barrier: 8679 case OMPD_taskwait: 8680 case OMPD_cancellation_point: 8681 case OMPD_flush: 8682 case OMPD_declare_reduction: 8683 case OMPD_declare_simd: 8684 case OMPD_declare_target: 8685 case OMPD_end_declare_target: 8686 case OMPD_simd: 8687 case OMPD_for: 8688 case OMPD_for_simd: 8689 case OMPD_sections: 8690 case OMPD_section: 8691 case OMPD_single: 8692 case OMPD_master: 8693 case OMPD_critical: 8694 case OMPD_taskgroup: 8695 case OMPD_ordered: 8696 case OMPD_atomic: 8697 case OMPD_target_teams: 8698 case OMPD_requires: 8699 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8700 case OMPD_unknown: 8701 llvm_unreachable("Unknown OpenMP directive"); 8702 } 8703 break; 8704 case OMPC_device: 8705 switch (DKind) { 8706 case OMPD_target_update: 8707 case OMPD_target_enter_data: 8708 case OMPD_target_exit_data: 8709 case OMPD_target: 8710 case OMPD_target_simd: 8711 case OMPD_target_teams: 8712 case OMPD_target_parallel: 8713 case OMPD_target_teams_distribute: 8714 case OMPD_target_teams_distribute_simd: 8715 case OMPD_target_parallel_for: 8716 case OMPD_target_parallel_for_simd: 8717 case OMPD_target_teams_distribute_parallel_for: 8718 case OMPD_target_teams_distribute_parallel_for_simd: 8719 CaptureRegion = OMPD_task; 8720 break; 8721 case OMPD_target_data: 8722 // Do not capture device-clause expressions. 8723 break; 8724 case OMPD_teams_distribute_parallel_for: 8725 case OMPD_teams_distribute_parallel_for_simd: 8726 case OMPD_teams: 8727 case OMPD_teams_distribute: 8728 case OMPD_teams_distribute_simd: 8729 case OMPD_distribute_parallel_for: 8730 case OMPD_distribute_parallel_for_simd: 8731 case OMPD_task: 8732 case OMPD_taskloop: 8733 case OMPD_taskloop_simd: 8734 case OMPD_cancel: 8735 case OMPD_parallel: 8736 case OMPD_parallel_sections: 8737 case OMPD_parallel_for: 8738 case OMPD_parallel_for_simd: 8739 case OMPD_threadprivate: 8740 case OMPD_taskyield: 8741 case OMPD_barrier: 8742 case OMPD_taskwait: 8743 case OMPD_cancellation_point: 8744 case OMPD_flush: 8745 case OMPD_declare_reduction: 8746 case OMPD_declare_simd: 8747 case OMPD_declare_target: 8748 case OMPD_end_declare_target: 8749 case OMPD_simd: 8750 case OMPD_for: 8751 case OMPD_for_simd: 8752 case OMPD_sections: 8753 case OMPD_section: 8754 case OMPD_single: 8755 case OMPD_master: 8756 case OMPD_critical: 8757 case OMPD_taskgroup: 8758 case OMPD_distribute: 8759 case OMPD_ordered: 8760 case OMPD_atomic: 8761 case OMPD_distribute_simd: 8762 case OMPD_requires: 8763 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8764 case OMPD_unknown: 8765 llvm_unreachable("Unknown OpenMP directive"); 8766 } 8767 break; 8768 case OMPC_firstprivate: 8769 case OMPC_lastprivate: 8770 case OMPC_reduction: 8771 case OMPC_task_reduction: 8772 case OMPC_in_reduction: 8773 case OMPC_linear: 8774 case OMPC_default: 8775 case OMPC_proc_bind: 8776 case OMPC_final: 8777 case OMPC_safelen: 8778 case OMPC_simdlen: 8779 case OMPC_collapse: 8780 case OMPC_private: 8781 case OMPC_shared: 8782 case OMPC_aligned: 8783 case OMPC_copyin: 8784 case OMPC_copyprivate: 8785 case OMPC_ordered: 8786 case OMPC_nowait: 8787 case OMPC_untied: 8788 case OMPC_mergeable: 8789 case OMPC_threadprivate: 8790 case OMPC_flush: 8791 case OMPC_read: 8792 case OMPC_write: 8793 case OMPC_update: 8794 case OMPC_capture: 8795 case OMPC_seq_cst: 8796 case OMPC_depend: 8797 case OMPC_threads: 8798 case OMPC_simd: 8799 case OMPC_map: 8800 case OMPC_priority: 8801 case OMPC_grainsize: 8802 case OMPC_nogroup: 8803 case OMPC_num_tasks: 8804 case OMPC_hint: 8805 case OMPC_defaultmap: 8806 case OMPC_unknown: 8807 case OMPC_uniform: 8808 case OMPC_to: 8809 case OMPC_from: 8810 case OMPC_use_device_ptr: 8811 case OMPC_is_device_ptr: 8812 case OMPC_unified_address: 8813 case OMPC_unified_shared_memory: 8814 case OMPC_reverse_offload: 8815 case OMPC_dynamic_allocators: 8816 case OMPC_atomic_default_mem_order: 8817 llvm_unreachable("Unexpected OpenMP clause."); 8818 } 8819 return CaptureRegion; 8820 } 8821 8822 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 8823 Expr *Condition, SourceLocation StartLoc, 8824 SourceLocation LParenLoc, 8825 SourceLocation NameModifierLoc, 8826 SourceLocation ColonLoc, 8827 SourceLocation EndLoc) { 8828 Expr *ValExpr = Condition; 8829 Stmt *HelperValStmt = nullptr; 8830 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8831 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 8832 !Condition->isInstantiationDependent() && 8833 !Condition->containsUnexpandedParameterPack()) { 8834 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 8835 if (Val.isInvalid()) 8836 return nullptr; 8837 8838 ValExpr = Val.get(); 8839 8840 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8841 CaptureRegion = 8842 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 8843 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 8844 ValExpr = MakeFullExpr(ValExpr).get(); 8845 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8846 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8847 HelperValStmt = buildPreInits(Context, Captures); 8848 } 8849 } 8850 8851 return new (Context) 8852 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 8853 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 8854 } 8855 8856 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 8857 SourceLocation StartLoc, 8858 SourceLocation LParenLoc, 8859 SourceLocation EndLoc) { 8860 Expr *ValExpr = Condition; 8861 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 8862 !Condition->isInstantiationDependent() && 8863 !Condition->containsUnexpandedParameterPack()) { 8864 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 8865 if (Val.isInvalid()) 8866 return nullptr; 8867 8868 ValExpr = MakeFullExpr(Val.get()).get(); 8869 } 8870 8871 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 8872 } 8873 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 8874 Expr *Op) { 8875 if (!Op) 8876 return ExprError(); 8877 8878 class IntConvertDiagnoser : public ICEConvertDiagnoser { 8879 public: 8880 IntConvertDiagnoser() 8881 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 8882 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 8883 QualType T) override { 8884 return S.Diag(Loc, diag::err_omp_not_integral) << T; 8885 } 8886 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 8887 QualType T) override { 8888 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 8889 } 8890 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 8891 QualType T, 8892 QualType ConvTy) override { 8893 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 8894 } 8895 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 8896 QualType ConvTy) override { 8897 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 8898 << ConvTy->isEnumeralType() << ConvTy; 8899 } 8900 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 8901 QualType T) override { 8902 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 8903 } 8904 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 8905 QualType ConvTy) override { 8906 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 8907 << ConvTy->isEnumeralType() << ConvTy; 8908 } 8909 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 8910 QualType) override { 8911 llvm_unreachable("conversion functions are permitted"); 8912 } 8913 } ConvertDiagnoser; 8914 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 8915 } 8916 8917 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 8918 OpenMPClauseKind CKind, 8919 bool StrictlyPositive) { 8920 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 8921 !ValExpr->isInstantiationDependent()) { 8922 SourceLocation Loc = ValExpr->getExprLoc(); 8923 ExprResult Value = 8924 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 8925 if (Value.isInvalid()) 8926 return false; 8927 8928 ValExpr = Value.get(); 8929 // The expression must evaluate to a non-negative integer value. 8930 llvm::APSInt Result; 8931 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 8932 Result.isSigned() && 8933 !((!StrictlyPositive && Result.isNonNegative()) || 8934 (StrictlyPositive && Result.isStrictlyPositive()))) { 8935 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 8936 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 8937 << ValExpr->getSourceRange(); 8938 return false; 8939 } 8940 } 8941 return true; 8942 } 8943 8944 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 8945 SourceLocation StartLoc, 8946 SourceLocation LParenLoc, 8947 SourceLocation EndLoc) { 8948 Expr *ValExpr = NumThreads; 8949 Stmt *HelperValStmt = nullptr; 8950 8951 // OpenMP [2.5, Restrictions] 8952 // The num_threads expression must evaluate to a positive integer value. 8953 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 8954 /*StrictlyPositive=*/true)) 8955 return nullptr; 8956 8957 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8958 OpenMPDirectiveKind CaptureRegion = 8959 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 8960 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 8961 ValExpr = MakeFullExpr(ValExpr).get(); 8962 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8963 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8964 HelperValStmt = buildPreInits(Context, Captures); 8965 } 8966 8967 return new (Context) OMPNumThreadsClause( 8968 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 8969 } 8970 8971 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 8972 OpenMPClauseKind CKind, 8973 bool StrictlyPositive) { 8974 if (!E) 8975 return ExprError(); 8976 if (E->isValueDependent() || E->isTypeDependent() || 8977 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 8978 return E; 8979 llvm::APSInt Result; 8980 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 8981 if (ICE.isInvalid()) 8982 return ExprError(); 8983 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 8984 (!StrictlyPositive && !Result.isNonNegative())) { 8985 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 8986 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 8987 << E->getSourceRange(); 8988 return ExprError(); 8989 } 8990 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 8991 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 8992 << E->getSourceRange(); 8993 return ExprError(); 8994 } 8995 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 8996 DSAStack->setAssociatedLoops(Result.getExtValue()); 8997 else if (CKind == OMPC_ordered) 8998 DSAStack->setAssociatedLoops(Result.getExtValue()); 8999 return ICE; 9000 } 9001 9002 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9003 SourceLocation LParenLoc, 9004 SourceLocation EndLoc) { 9005 // OpenMP [2.8.1, simd construct, Description] 9006 // The parameter of the safelen clause must be a constant 9007 // positive integer expression. 9008 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9009 if (Safelen.isInvalid()) 9010 return nullptr; 9011 return new (Context) 9012 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9013 } 9014 9015 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9016 SourceLocation LParenLoc, 9017 SourceLocation EndLoc) { 9018 // OpenMP [2.8.1, simd construct, Description] 9019 // The parameter of the simdlen clause must be a constant 9020 // positive integer expression. 9021 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9022 if (Simdlen.isInvalid()) 9023 return nullptr; 9024 return new (Context) 9025 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9026 } 9027 9028 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 9029 SourceLocation StartLoc, 9030 SourceLocation LParenLoc, 9031 SourceLocation EndLoc) { 9032 // OpenMP [2.7.1, loop construct, Description] 9033 // OpenMP [2.8.1, simd construct, Description] 9034 // OpenMP [2.9.6, distribute construct, Description] 9035 // The parameter of the collapse clause must be a constant 9036 // positive integer expression. 9037 ExprResult NumForLoopsResult = 9038 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 9039 if (NumForLoopsResult.isInvalid()) 9040 return nullptr; 9041 return new (Context) 9042 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 9043 } 9044 9045 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 9046 SourceLocation EndLoc, 9047 SourceLocation LParenLoc, 9048 Expr *NumForLoops) { 9049 // OpenMP [2.7.1, loop construct, Description] 9050 // OpenMP [2.8.1, simd construct, Description] 9051 // OpenMP [2.9.6, distribute construct, Description] 9052 // The parameter of the ordered clause must be a constant 9053 // positive integer expression if any. 9054 if (NumForLoops && LParenLoc.isValid()) { 9055 ExprResult NumForLoopsResult = 9056 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 9057 if (NumForLoopsResult.isInvalid()) 9058 return nullptr; 9059 NumForLoops = NumForLoopsResult.get(); 9060 } else { 9061 NumForLoops = nullptr; 9062 } 9063 auto *Clause = OMPOrderedClause::Create( 9064 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 9065 StartLoc, LParenLoc, EndLoc); 9066 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 9067 return Clause; 9068 } 9069 9070 OMPClause *Sema::ActOnOpenMPSimpleClause( 9071 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 9072 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9073 OMPClause *Res = nullptr; 9074 switch (Kind) { 9075 case OMPC_default: 9076 Res = 9077 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 9078 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9079 break; 9080 case OMPC_proc_bind: 9081 Res = ActOnOpenMPProcBindClause( 9082 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 9083 LParenLoc, EndLoc); 9084 break; 9085 case OMPC_atomic_default_mem_order: 9086 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 9087 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 9088 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9089 break; 9090 case OMPC_if: 9091 case OMPC_final: 9092 case OMPC_num_threads: 9093 case OMPC_safelen: 9094 case OMPC_simdlen: 9095 case OMPC_collapse: 9096 case OMPC_schedule: 9097 case OMPC_private: 9098 case OMPC_firstprivate: 9099 case OMPC_lastprivate: 9100 case OMPC_shared: 9101 case OMPC_reduction: 9102 case OMPC_task_reduction: 9103 case OMPC_in_reduction: 9104 case OMPC_linear: 9105 case OMPC_aligned: 9106 case OMPC_copyin: 9107 case OMPC_copyprivate: 9108 case OMPC_ordered: 9109 case OMPC_nowait: 9110 case OMPC_untied: 9111 case OMPC_mergeable: 9112 case OMPC_threadprivate: 9113 case OMPC_flush: 9114 case OMPC_read: 9115 case OMPC_write: 9116 case OMPC_update: 9117 case OMPC_capture: 9118 case OMPC_seq_cst: 9119 case OMPC_depend: 9120 case OMPC_device: 9121 case OMPC_threads: 9122 case OMPC_simd: 9123 case OMPC_map: 9124 case OMPC_num_teams: 9125 case OMPC_thread_limit: 9126 case OMPC_priority: 9127 case OMPC_grainsize: 9128 case OMPC_nogroup: 9129 case OMPC_num_tasks: 9130 case OMPC_hint: 9131 case OMPC_dist_schedule: 9132 case OMPC_defaultmap: 9133 case OMPC_unknown: 9134 case OMPC_uniform: 9135 case OMPC_to: 9136 case OMPC_from: 9137 case OMPC_use_device_ptr: 9138 case OMPC_is_device_ptr: 9139 case OMPC_unified_address: 9140 case OMPC_unified_shared_memory: 9141 case OMPC_reverse_offload: 9142 case OMPC_dynamic_allocators: 9143 llvm_unreachable("Clause is not allowed."); 9144 } 9145 return Res; 9146 } 9147 9148 static std::string 9149 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 9150 ArrayRef<unsigned> Exclude = llvm::None) { 9151 SmallString<256> Buffer; 9152 llvm::raw_svector_ostream Out(Buffer); 9153 unsigned Bound = Last >= 2 ? Last - 2 : 0; 9154 unsigned Skipped = Exclude.size(); 9155 auto S = Exclude.begin(), E = Exclude.end(); 9156 for (unsigned I = First; I < Last; ++I) { 9157 if (std::find(S, E, I) != E) { 9158 --Skipped; 9159 continue; 9160 } 9161 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 9162 if (I == Bound - Skipped) 9163 Out << " or "; 9164 else if (I != Bound + 1 - Skipped) 9165 Out << ", "; 9166 } 9167 return Out.str(); 9168 } 9169 9170 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 9171 SourceLocation KindKwLoc, 9172 SourceLocation StartLoc, 9173 SourceLocation LParenLoc, 9174 SourceLocation EndLoc) { 9175 if (Kind == OMPC_DEFAULT_unknown) { 9176 static_assert(OMPC_DEFAULT_unknown > 0, 9177 "OMPC_DEFAULT_unknown not greater than 0"); 9178 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9179 << getListOfPossibleValues(OMPC_default, /*First=*/0, 9180 /*Last=*/OMPC_DEFAULT_unknown) 9181 << getOpenMPClauseName(OMPC_default); 9182 return nullptr; 9183 } 9184 switch (Kind) { 9185 case OMPC_DEFAULT_none: 9186 DSAStack->setDefaultDSANone(KindKwLoc); 9187 break; 9188 case OMPC_DEFAULT_shared: 9189 DSAStack->setDefaultDSAShared(KindKwLoc); 9190 break; 9191 case OMPC_DEFAULT_unknown: 9192 llvm_unreachable("Clause kind is not allowed."); 9193 break; 9194 } 9195 return new (Context) 9196 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9197 } 9198 9199 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 9200 SourceLocation KindKwLoc, 9201 SourceLocation StartLoc, 9202 SourceLocation LParenLoc, 9203 SourceLocation EndLoc) { 9204 if (Kind == OMPC_PROC_BIND_unknown) { 9205 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9206 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 9207 /*Last=*/OMPC_PROC_BIND_unknown) 9208 << getOpenMPClauseName(OMPC_proc_bind); 9209 return nullptr; 9210 } 9211 return new (Context) 9212 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9213 } 9214 9215 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 9216 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 9217 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9218 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 9219 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9220 << getListOfPossibleValues( 9221 OMPC_atomic_default_mem_order, /*First=*/0, 9222 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 9223 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 9224 return nullptr; 9225 } 9226 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 9227 LParenLoc, EndLoc); 9228 } 9229 9230 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 9231 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 9232 SourceLocation StartLoc, SourceLocation LParenLoc, 9233 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 9234 SourceLocation EndLoc) { 9235 OMPClause *Res = nullptr; 9236 switch (Kind) { 9237 case OMPC_schedule: 9238 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 9239 assert(Argument.size() == NumberOfElements && 9240 ArgumentLoc.size() == NumberOfElements); 9241 Res = ActOnOpenMPScheduleClause( 9242 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 9243 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 9244 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 9245 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 9246 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 9247 break; 9248 case OMPC_if: 9249 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 9250 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 9251 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 9252 DelimLoc, EndLoc); 9253 break; 9254 case OMPC_dist_schedule: 9255 Res = ActOnOpenMPDistScheduleClause( 9256 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 9257 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 9258 break; 9259 case OMPC_defaultmap: 9260 enum { Modifier, DefaultmapKind }; 9261 Res = ActOnOpenMPDefaultmapClause( 9262 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 9263 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 9264 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 9265 EndLoc); 9266 break; 9267 case OMPC_final: 9268 case OMPC_num_threads: 9269 case OMPC_safelen: 9270 case OMPC_simdlen: 9271 case OMPC_collapse: 9272 case OMPC_default: 9273 case OMPC_proc_bind: 9274 case OMPC_private: 9275 case OMPC_firstprivate: 9276 case OMPC_lastprivate: 9277 case OMPC_shared: 9278 case OMPC_reduction: 9279 case OMPC_task_reduction: 9280 case OMPC_in_reduction: 9281 case OMPC_linear: 9282 case OMPC_aligned: 9283 case OMPC_copyin: 9284 case OMPC_copyprivate: 9285 case OMPC_ordered: 9286 case OMPC_nowait: 9287 case OMPC_untied: 9288 case OMPC_mergeable: 9289 case OMPC_threadprivate: 9290 case OMPC_flush: 9291 case OMPC_read: 9292 case OMPC_write: 9293 case OMPC_update: 9294 case OMPC_capture: 9295 case OMPC_seq_cst: 9296 case OMPC_depend: 9297 case OMPC_device: 9298 case OMPC_threads: 9299 case OMPC_simd: 9300 case OMPC_map: 9301 case OMPC_num_teams: 9302 case OMPC_thread_limit: 9303 case OMPC_priority: 9304 case OMPC_grainsize: 9305 case OMPC_nogroup: 9306 case OMPC_num_tasks: 9307 case OMPC_hint: 9308 case OMPC_unknown: 9309 case OMPC_uniform: 9310 case OMPC_to: 9311 case OMPC_from: 9312 case OMPC_use_device_ptr: 9313 case OMPC_is_device_ptr: 9314 case OMPC_unified_address: 9315 case OMPC_unified_shared_memory: 9316 case OMPC_reverse_offload: 9317 case OMPC_dynamic_allocators: 9318 case OMPC_atomic_default_mem_order: 9319 llvm_unreachable("Clause is not allowed."); 9320 } 9321 return Res; 9322 } 9323 9324 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 9325 OpenMPScheduleClauseModifier M2, 9326 SourceLocation M1Loc, SourceLocation M2Loc) { 9327 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 9328 SmallVector<unsigned, 2> Excluded; 9329 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 9330 Excluded.push_back(M2); 9331 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 9332 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 9333 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 9334 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 9335 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 9336 << getListOfPossibleValues(OMPC_schedule, 9337 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 9338 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9339 Excluded) 9340 << getOpenMPClauseName(OMPC_schedule); 9341 return true; 9342 } 9343 return false; 9344 } 9345 9346 OMPClause *Sema::ActOnOpenMPScheduleClause( 9347 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 9348 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 9349 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 9350 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 9351 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 9352 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 9353 return nullptr; 9354 // OpenMP, 2.7.1, Loop Construct, Restrictions 9355 // Either the monotonic modifier or the nonmonotonic modifier can be specified 9356 // but not both. 9357 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 9358 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 9359 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 9360 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 9361 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 9362 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 9363 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 9364 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 9365 return nullptr; 9366 } 9367 if (Kind == OMPC_SCHEDULE_unknown) { 9368 std::string Values; 9369 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 9370 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 9371 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9372 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9373 Exclude); 9374 } else { 9375 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9376 /*Last=*/OMPC_SCHEDULE_unknown); 9377 } 9378 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 9379 << Values << getOpenMPClauseName(OMPC_schedule); 9380 return nullptr; 9381 } 9382 // OpenMP, 2.7.1, Loop Construct, Restrictions 9383 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 9384 // schedule(guided). 9385 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 9386 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 9387 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 9388 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 9389 diag::err_omp_schedule_nonmonotonic_static); 9390 return nullptr; 9391 } 9392 Expr *ValExpr = ChunkSize; 9393 Stmt *HelperValStmt = nullptr; 9394 if (ChunkSize) { 9395 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 9396 !ChunkSize->isInstantiationDependent() && 9397 !ChunkSize->containsUnexpandedParameterPack()) { 9398 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 9399 ExprResult Val = 9400 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 9401 if (Val.isInvalid()) 9402 return nullptr; 9403 9404 ValExpr = Val.get(); 9405 9406 // OpenMP [2.7.1, Restrictions] 9407 // chunk_size must be a loop invariant integer expression with a positive 9408 // value. 9409 llvm::APSInt Result; 9410 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 9411 if (Result.isSigned() && !Result.isStrictlyPositive()) { 9412 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 9413 << "schedule" << 1 << ChunkSize->getSourceRange(); 9414 return nullptr; 9415 } 9416 } else if (getOpenMPCaptureRegionForClause( 9417 DSAStack->getCurrentDirective(), OMPC_schedule) != 9418 OMPD_unknown && 9419 !CurContext->isDependentContext()) { 9420 ValExpr = MakeFullExpr(ValExpr).get(); 9421 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9422 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9423 HelperValStmt = buildPreInits(Context, Captures); 9424 } 9425 } 9426 } 9427 9428 return new (Context) 9429 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 9430 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 9431 } 9432 9433 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 9434 SourceLocation StartLoc, 9435 SourceLocation EndLoc) { 9436 OMPClause *Res = nullptr; 9437 switch (Kind) { 9438 case OMPC_ordered: 9439 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 9440 break; 9441 case OMPC_nowait: 9442 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 9443 break; 9444 case OMPC_untied: 9445 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 9446 break; 9447 case OMPC_mergeable: 9448 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 9449 break; 9450 case OMPC_read: 9451 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 9452 break; 9453 case OMPC_write: 9454 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 9455 break; 9456 case OMPC_update: 9457 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 9458 break; 9459 case OMPC_capture: 9460 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 9461 break; 9462 case OMPC_seq_cst: 9463 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 9464 break; 9465 case OMPC_threads: 9466 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 9467 break; 9468 case OMPC_simd: 9469 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 9470 break; 9471 case OMPC_nogroup: 9472 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 9473 break; 9474 case OMPC_unified_address: 9475 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 9476 break; 9477 case OMPC_unified_shared_memory: 9478 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9479 break; 9480 case OMPC_reverse_offload: 9481 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 9482 break; 9483 case OMPC_dynamic_allocators: 9484 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 9485 break; 9486 case OMPC_if: 9487 case OMPC_final: 9488 case OMPC_num_threads: 9489 case OMPC_safelen: 9490 case OMPC_simdlen: 9491 case OMPC_collapse: 9492 case OMPC_schedule: 9493 case OMPC_private: 9494 case OMPC_firstprivate: 9495 case OMPC_lastprivate: 9496 case OMPC_shared: 9497 case OMPC_reduction: 9498 case OMPC_task_reduction: 9499 case OMPC_in_reduction: 9500 case OMPC_linear: 9501 case OMPC_aligned: 9502 case OMPC_copyin: 9503 case OMPC_copyprivate: 9504 case OMPC_default: 9505 case OMPC_proc_bind: 9506 case OMPC_threadprivate: 9507 case OMPC_flush: 9508 case OMPC_depend: 9509 case OMPC_device: 9510 case OMPC_map: 9511 case OMPC_num_teams: 9512 case OMPC_thread_limit: 9513 case OMPC_priority: 9514 case OMPC_grainsize: 9515 case OMPC_num_tasks: 9516 case OMPC_hint: 9517 case OMPC_dist_schedule: 9518 case OMPC_defaultmap: 9519 case OMPC_unknown: 9520 case OMPC_uniform: 9521 case OMPC_to: 9522 case OMPC_from: 9523 case OMPC_use_device_ptr: 9524 case OMPC_is_device_ptr: 9525 case OMPC_atomic_default_mem_order: 9526 llvm_unreachable("Clause is not allowed."); 9527 } 9528 return Res; 9529 } 9530 9531 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 9532 SourceLocation EndLoc) { 9533 DSAStack->setNowaitRegion(); 9534 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 9535 } 9536 9537 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 9538 SourceLocation EndLoc) { 9539 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 9540 } 9541 9542 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 9543 SourceLocation EndLoc) { 9544 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 9545 } 9546 9547 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 9548 SourceLocation EndLoc) { 9549 return new (Context) OMPReadClause(StartLoc, EndLoc); 9550 } 9551 9552 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 9553 SourceLocation EndLoc) { 9554 return new (Context) OMPWriteClause(StartLoc, EndLoc); 9555 } 9556 9557 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 9558 SourceLocation EndLoc) { 9559 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 9560 } 9561 9562 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 9563 SourceLocation EndLoc) { 9564 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 9565 } 9566 9567 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 9568 SourceLocation EndLoc) { 9569 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 9570 } 9571 9572 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 9573 SourceLocation EndLoc) { 9574 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 9575 } 9576 9577 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 9578 SourceLocation EndLoc) { 9579 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 9580 } 9581 9582 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 9583 SourceLocation EndLoc) { 9584 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 9585 } 9586 9587 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 9588 SourceLocation EndLoc) { 9589 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 9590 } 9591 9592 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 9593 SourceLocation EndLoc) { 9594 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9595 } 9596 9597 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 9598 SourceLocation EndLoc) { 9599 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 9600 } 9601 9602 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 9603 SourceLocation EndLoc) { 9604 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 9605 } 9606 9607 OMPClause *Sema::ActOnOpenMPVarListClause( 9608 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 9609 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 9610 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 9611 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 9612 OpenMPLinearClauseKind LinKind, 9613 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 9614 ArrayRef<SourceLocation> MapTypeModifiersLoc, 9615 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 9616 SourceLocation DepLinMapLoc) { 9617 OMPClause *Res = nullptr; 9618 switch (Kind) { 9619 case OMPC_private: 9620 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9621 break; 9622 case OMPC_firstprivate: 9623 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9624 break; 9625 case OMPC_lastprivate: 9626 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9627 break; 9628 case OMPC_shared: 9629 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 9630 break; 9631 case OMPC_reduction: 9632 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9633 EndLoc, ReductionIdScopeSpec, ReductionId); 9634 break; 9635 case OMPC_task_reduction: 9636 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9637 EndLoc, ReductionIdScopeSpec, 9638 ReductionId); 9639 break; 9640 case OMPC_in_reduction: 9641 Res = 9642 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 9643 EndLoc, ReductionIdScopeSpec, ReductionId); 9644 break; 9645 case OMPC_linear: 9646 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 9647 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 9648 break; 9649 case OMPC_aligned: 9650 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 9651 ColonLoc, EndLoc); 9652 break; 9653 case OMPC_copyin: 9654 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 9655 break; 9656 case OMPC_copyprivate: 9657 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 9658 break; 9659 case OMPC_flush: 9660 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 9661 break; 9662 case OMPC_depend: 9663 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 9664 StartLoc, LParenLoc, EndLoc); 9665 break; 9666 case OMPC_map: 9667 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType, 9668 IsMapTypeImplicit, DepLinMapLoc, ColonLoc, 9669 VarList, StartLoc, LParenLoc, EndLoc); 9670 break; 9671 case OMPC_to: 9672 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 9673 break; 9674 case OMPC_from: 9675 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 9676 break; 9677 case OMPC_use_device_ptr: 9678 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 9679 break; 9680 case OMPC_is_device_ptr: 9681 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 9682 break; 9683 case OMPC_if: 9684 case OMPC_final: 9685 case OMPC_num_threads: 9686 case OMPC_safelen: 9687 case OMPC_simdlen: 9688 case OMPC_collapse: 9689 case OMPC_default: 9690 case OMPC_proc_bind: 9691 case OMPC_schedule: 9692 case OMPC_ordered: 9693 case OMPC_nowait: 9694 case OMPC_untied: 9695 case OMPC_mergeable: 9696 case OMPC_threadprivate: 9697 case OMPC_read: 9698 case OMPC_write: 9699 case OMPC_update: 9700 case OMPC_capture: 9701 case OMPC_seq_cst: 9702 case OMPC_device: 9703 case OMPC_threads: 9704 case OMPC_simd: 9705 case OMPC_num_teams: 9706 case OMPC_thread_limit: 9707 case OMPC_priority: 9708 case OMPC_grainsize: 9709 case OMPC_nogroup: 9710 case OMPC_num_tasks: 9711 case OMPC_hint: 9712 case OMPC_dist_schedule: 9713 case OMPC_defaultmap: 9714 case OMPC_unknown: 9715 case OMPC_uniform: 9716 case OMPC_unified_address: 9717 case OMPC_unified_shared_memory: 9718 case OMPC_reverse_offload: 9719 case OMPC_dynamic_allocators: 9720 case OMPC_atomic_default_mem_order: 9721 llvm_unreachable("Clause is not allowed."); 9722 } 9723 return Res; 9724 } 9725 9726 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 9727 ExprObjectKind OK, SourceLocation Loc) { 9728 ExprResult Res = BuildDeclRefExpr( 9729 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 9730 if (!Res.isUsable()) 9731 return ExprError(); 9732 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 9733 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 9734 if (!Res.isUsable()) 9735 return ExprError(); 9736 } 9737 if (VK != VK_LValue && Res.get()->isGLValue()) { 9738 Res = DefaultLvalueConversion(Res.get()); 9739 if (!Res.isUsable()) 9740 return ExprError(); 9741 } 9742 return Res; 9743 } 9744 9745 static std::pair<ValueDecl *, bool> 9746 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 9747 SourceRange &ERange, bool AllowArraySection = false) { 9748 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 9749 RefExpr->containsUnexpandedParameterPack()) 9750 return std::make_pair(nullptr, true); 9751 9752 // OpenMP [3.1, C/C++] 9753 // A list item is a variable name. 9754 // OpenMP [2.9.3.3, Restrictions, p.1] 9755 // A variable that is part of another variable (as an array or 9756 // structure element) cannot appear in a private clause. 9757 RefExpr = RefExpr->IgnoreParens(); 9758 enum { 9759 NoArrayExpr = -1, 9760 ArraySubscript = 0, 9761 OMPArraySection = 1 9762 } IsArrayExpr = NoArrayExpr; 9763 if (AllowArraySection) { 9764 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 9765 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 9766 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 9767 Base = TempASE->getBase()->IgnoreParenImpCasts(); 9768 RefExpr = Base; 9769 IsArrayExpr = ArraySubscript; 9770 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 9771 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 9772 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 9773 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 9774 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 9775 Base = TempASE->getBase()->IgnoreParenImpCasts(); 9776 RefExpr = Base; 9777 IsArrayExpr = OMPArraySection; 9778 } 9779 } 9780 ELoc = RefExpr->getExprLoc(); 9781 ERange = RefExpr->getSourceRange(); 9782 RefExpr = RefExpr->IgnoreParenImpCasts(); 9783 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 9784 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 9785 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 9786 (S.getCurrentThisType().isNull() || !ME || 9787 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 9788 !isa<FieldDecl>(ME->getMemberDecl()))) { 9789 if (IsArrayExpr != NoArrayExpr) { 9790 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 9791 << ERange; 9792 } else { 9793 S.Diag(ELoc, 9794 AllowArraySection 9795 ? diag::err_omp_expected_var_name_member_expr_or_array_item 9796 : diag::err_omp_expected_var_name_member_expr) 9797 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 9798 } 9799 return std::make_pair(nullptr, false); 9800 } 9801 return std::make_pair( 9802 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 9803 } 9804 9805 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 9806 SourceLocation StartLoc, 9807 SourceLocation LParenLoc, 9808 SourceLocation EndLoc) { 9809 SmallVector<Expr *, 8> Vars; 9810 SmallVector<Expr *, 8> PrivateCopies; 9811 for (Expr *RefExpr : VarList) { 9812 assert(RefExpr && "NULL expr in OpenMP private clause."); 9813 SourceLocation ELoc; 9814 SourceRange ERange; 9815 Expr *SimpleRefExpr = RefExpr; 9816 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9817 if (Res.second) { 9818 // It will be analyzed later. 9819 Vars.push_back(RefExpr); 9820 PrivateCopies.push_back(nullptr); 9821 } 9822 ValueDecl *D = Res.first; 9823 if (!D) 9824 continue; 9825 9826 QualType Type = D->getType(); 9827 auto *VD = dyn_cast<VarDecl>(D); 9828 9829 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9830 // A variable that appears in a private clause must not have an incomplete 9831 // type or a reference type. 9832 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 9833 continue; 9834 Type = Type.getNonReferenceType(); 9835 9836 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 9837 // A variable that is privatized must not have a const-qualified type 9838 // unless it is of class type with a mutable member. This restriction does 9839 // not apply to the firstprivate clause. 9840 // 9841 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 9842 // A variable that appears in a private clause must not have a 9843 // const-qualified type unless it is of class type with a mutable member. 9844 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 9845 continue; 9846 9847 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9848 // in a Construct] 9849 // Variables with the predetermined data-sharing attributes may not be 9850 // listed in data-sharing attributes clauses, except for the cases 9851 // listed below. For these exceptions only, listing a predetermined 9852 // variable in a data-sharing attribute clause is allowed and overrides 9853 // the variable's predetermined data-sharing attributes. 9854 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 9855 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 9856 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9857 << getOpenMPClauseName(OMPC_private); 9858 reportOriginalDsa(*this, DSAStack, D, DVar); 9859 continue; 9860 } 9861 9862 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9863 // Variably modified types are not supported for tasks. 9864 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 9865 isOpenMPTaskingDirective(CurrDir)) { 9866 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9867 << getOpenMPClauseName(OMPC_private) << Type 9868 << getOpenMPDirectiveName(CurrDir); 9869 bool IsDecl = 9870 !VD || 9871 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9872 Diag(D->getLocation(), 9873 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9874 << D; 9875 continue; 9876 } 9877 9878 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9879 // A list item cannot appear in both a map clause and a data-sharing 9880 // attribute clause on the same construct 9881 if (isOpenMPTargetExecutionDirective(CurrDir)) { 9882 OpenMPClauseKind ConflictKind; 9883 if (DSAStack->checkMappableExprComponentListsForDecl( 9884 VD, /*CurrentRegionOnly=*/true, 9885 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 9886 OpenMPClauseKind WhereFoundClauseKind) -> bool { 9887 ConflictKind = WhereFoundClauseKind; 9888 return true; 9889 })) { 9890 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 9891 << getOpenMPClauseName(OMPC_private) 9892 << getOpenMPClauseName(ConflictKind) 9893 << getOpenMPDirectiveName(CurrDir); 9894 reportOriginalDsa(*this, DSAStack, D, DVar); 9895 continue; 9896 } 9897 } 9898 9899 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 9900 // A variable of class type (or array thereof) that appears in a private 9901 // clause requires an accessible, unambiguous default constructor for the 9902 // class type. 9903 // Generate helper private variable and initialize it with the default 9904 // value. The address of the original variable is replaced by the address of 9905 // the new private variable in CodeGen. This new variable is not added to 9906 // IdResolver, so the code in the OpenMP region uses original variable for 9907 // proper diagnostics. 9908 Type = Type.getUnqualifiedType(); 9909 VarDecl *VDPrivate = 9910 buildVarDecl(*this, ELoc, Type, D->getName(), 9911 D->hasAttrs() ? &D->getAttrs() : nullptr, 9912 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 9913 ActOnUninitializedDecl(VDPrivate); 9914 if (VDPrivate->isInvalidDecl()) 9915 continue; 9916 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 9917 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 9918 9919 DeclRefExpr *Ref = nullptr; 9920 if (!VD && !CurContext->isDependentContext()) 9921 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9922 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 9923 Vars.push_back((VD || CurContext->isDependentContext()) 9924 ? RefExpr->IgnoreParens() 9925 : Ref); 9926 PrivateCopies.push_back(VDPrivateRefExpr); 9927 } 9928 9929 if (Vars.empty()) 9930 return nullptr; 9931 9932 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9933 PrivateCopies); 9934 } 9935 9936 namespace { 9937 class DiagsUninitializedSeveretyRAII { 9938 private: 9939 DiagnosticsEngine &Diags; 9940 SourceLocation SavedLoc; 9941 bool IsIgnored = false; 9942 9943 public: 9944 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 9945 bool IsIgnored) 9946 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 9947 if (!IsIgnored) { 9948 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 9949 /*Map*/ diag::Severity::Ignored, Loc); 9950 } 9951 } 9952 ~DiagsUninitializedSeveretyRAII() { 9953 if (!IsIgnored) 9954 Diags.popMappings(SavedLoc); 9955 } 9956 }; 9957 } 9958 9959 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 9960 SourceLocation StartLoc, 9961 SourceLocation LParenLoc, 9962 SourceLocation EndLoc) { 9963 SmallVector<Expr *, 8> Vars; 9964 SmallVector<Expr *, 8> PrivateCopies; 9965 SmallVector<Expr *, 8> Inits; 9966 SmallVector<Decl *, 4> ExprCaptures; 9967 bool IsImplicitClause = 9968 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 9969 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 9970 9971 for (Expr *RefExpr : VarList) { 9972 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 9973 SourceLocation ELoc; 9974 SourceRange ERange; 9975 Expr *SimpleRefExpr = RefExpr; 9976 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9977 if (Res.second) { 9978 // It will be analyzed later. 9979 Vars.push_back(RefExpr); 9980 PrivateCopies.push_back(nullptr); 9981 Inits.push_back(nullptr); 9982 } 9983 ValueDecl *D = Res.first; 9984 if (!D) 9985 continue; 9986 9987 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 9988 QualType Type = D->getType(); 9989 auto *VD = dyn_cast<VarDecl>(D); 9990 9991 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9992 // A variable that appears in a private clause must not have an incomplete 9993 // type or a reference type. 9994 if (RequireCompleteType(ELoc, Type, 9995 diag::err_omp_firstprivate_incomplete_type)) 9996 continue; 9997 Type = Type.getNonReferenceType(); 9998 9999 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10000 // A variable of class type (or array thereof) that appears in a private 10001 // clause requires an accessible, unambiguous copy constructor for the 10002 // class type. 10003 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10004 10005 // If an implicit firstprivate variable found it was checked already. 10006 DSAStackTy::DSAVarData TopDVar; 10007 if (!IsImplicitClause) { 10008 DSAStackTy::DSAVarData DVar = 10009 DSAStack->getTopDSA(D, /*FromParent=*/false); 10010 TopDVar = DVar; 10011 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10012 bool IsConstant = ElemType.isConstant(Context); 10013 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10014 // A list item that specifies a given variable may not appear in more 10015 // than one clause on the same directive, except that a variable may be 10016 // specified in both firstprivate and lastprivate clauses. 10017 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10018 // A list item may appear in a firstprivate or lastprivate clause but not 10019 // both. 10020 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10021 (isOpenMPDistributeDirective(CurrDir) || 10022 DVar.CKind != OMPC_lastprivate) && 10023 DVar.RefExpr) { 10024 Diag(ELoc, diag::err_omp_wrong_dsa) 10025 << getOpenMPClauseName(DVar.CKind) 10026 << getOpenMPClauseName(OMPC_firstprivate); 10027 reportOriginalDsa(*this, DSAStack, D, DVar); 10028 continue; 10029 } 10030 10031 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10032 // in a Construct] 10033 // Variables with the predetermined data-sharing attributes may not be 10034 // listed in data-sharing attributes clauses, except for the cases 10035 // listed below. For these exceptions only, listing a predetermined 10036 // variable in a data-sharing attribute clause is allowed and overrides 10037 // the variable's predetermined data-sharing attributes. 10038 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10039 // in a Construct, C/C++, p.2] 10040 // Variables with const-qualified type having no mutable member may be 10041 // listed in a firstprivate clause, even if they are static data members. 10042 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 10043 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 10044 Diag(ELoc, diag::err_omp_wrong_dsa) 10045 << getOpenMPClauseName(DVar.CKind) 10046 << getOpenMPClauseName(OMPC_firstprivate); 10047 reportOriginalDsa(*this, DSAStack, D, DVar); 10048 continue; 10049 } 10050 10051 // OpenMP [2.9.3.4, Restrictions, p.2] 10052 // A list item that is private within a parallel region must not appear 10053 // in a firstprivate clause on a worksharing construct if any of the 10054 // worksharing regions arising from the worksharing construct ever bind 10055 // to any of the parallel regions arising from the parallel construct. 10056 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10057 // A list item that is private within a teams region must not appear in a 10058 // firstprivate clause on a distribute construct if any of the distribute 10059 // regions arising from the distribute construct ever bind to any of the 10060 // teams regions arising from the teams construct. 10061 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10062 // A list item that appears in a reduction clause of a teams construct 10063 // must not appear in a firstprivate clause on a distribute construct if 10064 // any of the distribute regions arising from the distribute construct 10065 // ever bind to any of the teams regions arising from the teams construct. 10066 if ((isOpenMPWorksharingDirective(CurrDir) || 10067 isOpenMPDistributeDirective(CurrDir)) && 10068 !isOpenMPParallelDirective(CurrDir) && 10069 !isOpenMPTeamsDirective(CurrDir)) { 10070 DVar = DSAStack->getImplicitDSA(D, true); 10071 if (DVar.CKind != OMPC_shared && 10072 (isOpenMPParallelDirective(DVar.DKind) || 10073 isOpenMPTeamsDirective(DVar.DKind) || 10074 DVar.DKind == OMPD_unknown)) { 10075 Diag(ELoc, diag::err_omp_required_access) 10076 << getOpenMPClauseName(OMPC_firstprivate) 10077 << getOpenMPClauseName(OMPC_shared); 10078 reportOriginalDsa(*this, DSAStack, D, DVar); 10079 continue; 10080 } 10081 } 10082 // OpenMP [2.9.3.4, Restrictions, p.3] 10083 // A list item that appears in a reduction clause of a parallel construct 10084 // must not appear in a firstprivate clause on a worksharing or task 10085 // construct if any of the worksharing or task regions arising from the 10086 // worksharing or task construct ever bind to any of the parallel regions 10087 // arising from the parallel construct. 10088 // OpenMP [2.9.3.4, Restrictions, p.4] 10089 // A list item that appears in a reduction clause in worksharing 10090 // construct must not appear in a firstprivate clause in a task construct 10091 // encountered during execution of any of the worksharing regions arising 10092 // from the worksharing construct. 10093 if (isOpenMPTaskingDirective(CurrDir)) { 10094 DVar = DSAStack->hasInnermostDSA( 10095 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 10096 [](OpenMPDirectiveKind K) { 10097 return isOpenMPParallelDirective(K) || 10098 isOpenMPWorksharingDirective(K) || 10099 isOpenMPTeamsDirective(K); 10100 }, 10101 /*FromParent=*/true); 10102 if (DVar.CKind == OMPC_reduction && 10103 (isOpenMPParallelDirective(DVar.DKind) || 10104 isOpenMPWorksharingDirective(DVar.DKind) || 10105 isOpenMPTeamsDirective(DVar.DKind))) { 10106 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 10107 << getOpenMPDirectiveName(DVar.DKind); 10108 reportOriginalDsa(*this, DSAStack, D, DVar); 10109 continue; 10110 } 10111 } 10112 10113 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10114 // A list item cannot appear in both a map clause and a data-sharing 10115 // attribute clause on the same construct 10116 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10117 OpenMPClauseKind ConflictKind; 10118 if (DSAStack->checkMappableExprComponentListsForDecl( 10119 VD, /*CurrentRegionOnly=*/true, 10120 [&ConflictKind]( 10121 OMPClauseMappableExprCommon::MappableExprComponentListRef, 10122 OpenMPClauseKind WhereFoundClauseKind) { 10123 ConflictKind = WhereFoundClauseKind; 10124 return true; 10125 })) { 10126 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10127 << getOpenMPClauseName(OMPC_firstprivate) 10128 << getOpenMPClauseName(ConflictKind) 10129 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10130 reportOriginalDsa(*this, DSAStack, D, DVar); 10131 continue; 10132 } 10133 } 10134 } 10135 10136 // Variably modified types are not supported for tasks. 10137 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10138 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 10139 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10140 << getOpenMPClauseName(OMPC_firstprivate) << Type 10141 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10142 bool IsDecl = 10143 !VD || 10144 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10145 Diag(D->getLocation(), 10146 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10147 << D; 10148 continue; 10149 } 10150 10151 Type = Type.getUnqualifiedType(); 10152 VarDecl *VDPrivate = 10153 buildVarDecl(*this, ELoc, Type, D->getName(), 10154 D->hasAttrs() ? &D->getAttrs() : nullptr, 10155 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10156 // Generate helper private variable and initialize it with the value of the 10157 // original variable. The address of the original variable is replaced by 10158 // the address of the new private variable in the CodeGen. This new variable 10159 // is not added to IdResolver, so the code in the OpenMP region uses 10160 // original variable for proper diagnostics and variable capturing. 10161 Expr *VDInitRefExpr = nullptr; 10162 // For arrays generate initializer for single element and replace it by the 10163 // original array element in CodeGen. 10164 if (Type->isArrayType()) { 10165 VarDecl *VDInit = 10166 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 10167 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 10168 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 10169 ElemType = ElemType.getUnqualifiedType(); 10170 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 10171 ".firstprivate.temp"); 10172 InitializedEntity Entity = 10173 InitializedEntity::InitializeVariable(VDInitTemp); 10174 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 10175 10176 InitializationSequence InitSeq(*this, Entity, Kind, Init); 10177 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 10178 if (Result.isInvalid()) 10179 VDPrivate->setInvalidDecl(); 10180 else 10181 VDPrivate->setInit(Result.getAs<Expr>()); 10182 // Remove temp variable declaration. 10183 Context.Deallocate(VDInitTemp); 10184 } else { 10185 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 10186 ".firstprivate.temp"); 10187 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 10188 RefExpr->getExprLoc()); 10189 AddInitializerToDecl(VDPrivate, 10190 DefaultLvalueConversion(VDInitRefExpr).get(), 10191 /*DirectInit=*/false); 10192 } 10193 if (VDPrivate->isInvalidDecl()) { 10194 if (IsImplicitClause) { 10195 Diag(RefExpr->getExprLoc(), 10196 diag::note_omp_task_predetermined_firstprivate_here); 10197 } 10198 continue; 10199 } 10200 CurContext->addDecl(VDPrivate); 10201 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10202 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 10203 RefExpr->getExprLoc()); 10204 DeclRefExpr *Ref = nullptr; 10205 if (!VD && !CurContext->isDependentContext()) { 10206 if (TopDVar.CKind == OMPC_lastprivate) { 10207 Ref = TopDVar.PrivateCopy; 10208 } else { 10209 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10210 if (!isOpenMPCapturedDecl(D)) 10211 ExprCaptures.push_back(Ref->getDecl()); 10212 } 10213 } 10214 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 10215 Vars.push_back((VD || CurContext->isDependentContext()) 10216 ? RefExpr->IgnoreParens() 10217 : Ref); 10218 PrivateCopies.push_back(VDPrivateRefExpr); 10219 Inits.push_back(VDInitRefExpr); 10220 } 10221 10222 if (Vars.empty()) 10223 return nullptr; 10224 10225 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10226 Vars, PrivateCopies, Inits, 10227 buildPreInits(Context, ExprCaptures)); 10228 } 10229 10230 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 10231 SourceLocation StartLoc, 10232 SourceLocation LParenLoc, 10233 SourceLocation EndLoc) { 10234 SmallVector<Expr *, 8> Vars; 10235 SmallVector<Expr *, 8> SrcExprs; 10236 SmallVector<Expr *, 8> DstExprs; 10237 SmallVector<Expr *, 8> AssignmentOps; 10238 SmallVector<Decl *, 4> ExprCaptures; 10239 SmallVector<Expr *, 4> ExprPostUpdates; 10240 for (Expr *RefExpr : VarList) { 10241 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10242 SourceLocation ELoc; 10243 SourceRange ERange; 10244 Expr *SimpleRefExpr = RefExpr; 10245 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10246 if (Res.second) { 10247 // It will be analyzed later. 10248 Vars.push_back(RefExpr); 10249 SrcExprs.push_back(nullptr); 10250 DstExprs.push_back(nullptr); 10251 AssignmentOps.push_back(nullptr); 10252 } 10253 ValueDecl *D = Res.first; 10254 if (!D) 10255 continue; 10256 10257 QualType Type = D->getType(); 10258 auto *VD = dyn_cast<VarDecl>(D); 10259 10260 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 10261 // A variable that appears in a lastprivate clause must not have an 10262 // incomplete type or a reference type. 10263 if (RequireCompleteType(ELoc, Type, 10264 diag::err_omp_lastprivate_incomplete_type)) 10265 continue; 10266 Type = Type.getNonReferenceType(); 10267 10268 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10269 // A variable that is privatized must not have a const-qualified type 10270 // unless it is of class type with a mutable member. This restriction does 10271 // not apply to the firstprivate clause. 10272 // 10273 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 10274 // A variable that appears in a lastprivate clause must not have a 10275 // const-qualified type unless it is of class type with a mutable member. 10276 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 10277 continue; 10278 10279 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10280 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10281 // in a Construct] 10282 // Variables with the predetermined data-sharing attributes may not be 10283 // listed in data-sharing attributes clauses, except for the cases 10284 // listed below. 10285 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10286 // A list item may appear in a firstprivate or lastprivate clause but not 10287 // both. 10288 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10289 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 10290 (isOpenMPDistributeDirective(CurrDir) || 10291 DVar.CKind != OMPC_firstprivate) && 10292 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 10293 Diag(ELoc, diag::err_omp_wrong_dsa) 10294 << getOpenMPClauseName(DVar.CKind) 10295 << getOpenMPClauseName(OMPC_lastprivate); 10296 reportOriginalDsa(*this, DSAStack, D, DVar); 10297 continue; 10298 } 10299 10300 // OpenMP [2.14.3.5, Restrictions, p.2] 10301 // A list item that is private within a parallel region, or that appears in 10302 // the reduction clause of a parallel construct, must not appear in a 10303 // lastprivate clause on a worksharing construct if any of the corresponding 10304 // worksharing regions ever binds to any of the corresponding parallel 10305 // regions. 10306 DSAStackTy::DSAVarData TopDVar = DVar; 10307 if (isOpenMPWorksharingDirective(CurrDir) && 10308 !isOpenMPParallelDirective(CurrDir) && 10309 !isOpenMPTeamsDirective(CurrDir)) { 10310 DVar = DSAStack->getImplicitDSA(D, true); 10311 if (DVar.CKind != OMPC_shared) { 10312 Diag(ELoc, diag::err_omp_required_access) 10313 << getOpenMPClauseName(OMPC_lastprivate) 10314 << getOpenMPClauseName(OMPC_shared); 10315 reportOriginalDsa(*this, DSAStack, D, DVar); 10316 continue; 10317 } 10318 } 10319 10320 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 10321 // A variable of class type (or array thereof) that appears in a 10322 // lastprivate clause requires an accessible, unambiguous default 10323 // constructor for the class type, unless the list item is also specified 10324 // in a firstprivate clause. 10325 // A variable of class type (or array thereof) that appears in a 10326 // lastprivate clause requires an accessible, unambiguous copy assignment 10327 // operator for the class type. 10328 Type = Context.getBaseElementType(Type).getNonReferenceType(); 10329 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 10330 Type.getUnqualifiedType(), ".lastprivate.src", 10331 D->hasAttrs() ? &D->getAttrs() : nullptr); 10332 DeclRefExpr *PseudoSrcExpr = 10333 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 10334 VarDecl *DstVD = 10335 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 10336 D->hasAttrs() ? &D->getAttrs() : nullptr); 10337 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10338 // For arrays generate assignment operation for single element and replace 10339 // it by the original array element in CodeGen. 10340 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 10341 PseudoDstExpr, PseudoSrcExpr); 10342 if (AssignmentOp.isInvalid()) 10343 continue; 10344 AssignmentOp = 10345 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 10346 if (AssignmentOp.isInvalid()) 10347 continue; 10348 10349 DeclRefExpr *Ref = nullptr; 10350 if (!VD && !CurContext->isDependentContext()) { 10351 if (TopDVar.CKind == OMPC_firstprivate) { 10352 Ref = TopDVar.PrivateCopy; 10353 } else { 10354 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10355 if (!isOpenMPCapturedDecl(D)) 10356 ExprCaptures.push_back(Ref->getDecl()); 10357 } 10358 if (TopDVar.CKind == OMPC_firstprivate || 10359 (!isOpenMPCapturedDecl(D) && 10360 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 10361 ExprResult RefRes = DefaultLvalueConversion(Ref); 10362 if (!RefRes.isUsable()) 10363 continue; 10364 ExprResult PostUpdateRes = 10365 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10366 RefRes.get()); 10367 if (!PostUpdateRes.isUsable()) 10368 continue; 10369 ExprPostUpdates.push_back( 10370 IgnoredValueConversions(PostUpdateRes.get()).get()); 10371 } 10372 } 10373 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 10374 Vars.push_back((VD || CurContext->isDependentContext()) 10375 ? RefExpr->IgnoreParens() 10376 : Ref); 10377 SrcExprs.push_back(PseudoSrcExpr); 10378 DstExprs.push_back(PseudoDstExpr); 10379 AssignmentOps.push_back(AssignmentOp.get()); 10380 } 10381 10382 if (Vars.empty()) 10383 return nullptr; 10384 10385 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10386 Vars, SrcExprs, DstExprs, AssignmentOps, 10387 buildPreInits(Context, ExprCaptures), 10388 buildPostUpdate(*this, ExprPostUpdates)); 10389 } 10390 10391 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 10392 SourceLocation StartLoc, 10393 SourceLocation LParenLoc, 10394 SourceLocation EndLoc) { 10395 SmallVector<Expr *, 8> Vars; 10396 for (Expr *RefExpr : VarList) { 10397 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10398 SourceLocation ELoc; 10399 SourceRange ERange; 10400 Expr *SimpleRefExpr = RefExpr; 10401 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10402 if (Res.second) { 10403 // It will be analyzed later. 10404 Vars.push_back(RefExpr); 10405 } 10406 ValueDecl *D = Res.first; 10407 if (!D) 10408 continue; 10409 10410 auto *VD = dyn_cast<VarDecl>(D); 10411 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10412 // in a Construct] 10413 // Variables with the predetermined data-sharing attributes may not be 10414 // listed in data-sharing attributes clauses, except for the cases 10415 // listed below. For these exceptions only, listing a predetermined 10416 // variable in a data-sharing attribute clause is allowed and overrides 10417 // the variable's predetermined data-sharing attributes. 10418 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10419 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 10420 DVar.RefExpr) { 10421 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10422 << getOpenMPClauseName(OMPC_shared); 10423 reportOriginalDsa(*this, DSAStack, D, DVar); 10424 continue; 10425 } 10426 10427 DeclRefExpr *Ref = nullptr; 10428 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 10429 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10430 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 10431 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 10432 ? RefExpr->IgnoreParens() 10433 : Ref); 10434 } 10435 10436 if (Vars.empty()) 10437 return nullptr; 10438 10439 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 10440 } 10441 10442 namespace { 10443 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 10444 DSAStackTy *Stack; 10445 10446 public: 10447 bool VisitDeclRefExpr(DeclRefExpr *E) { 10448 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 10449 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 10450 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 10451 return false; 10452 if (DVar.CKind != OMPC_unknown) 10453 return true; 10454 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 10455 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 10456 /*FromParent=*/true); 10457 return DVarPrivate.CKind != OMPC_unknown; 10458 } 10459 return false; 10460 } 10461 bool VisitStmt(Stmt *S) { 10462 for (Stmt *Child : S->children()) { 10463 if (Child && Visit(Child)) 10464 return true; 10465 } 10466 return false; 10467 } 10468 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 10469 }; 10470 } // namespace 10471 10472 namespace { 10473 // Transform MemberExpression for specified FieldDecl of current class to 10474 // DeclRefExpr to specified OMPCapturedExprDecl. 10475 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 10476 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 10477 ValueDecl *Field = nullptr; 10478 DeclRefExpr *CapturedExpr = nullptr; 10479 10480 public: 10481 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 10482 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 10483 10484 ExprResult TransformMemberExpr(MemberExpr *E) { 10485 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 10486 E->getMemberDecl() == Field) { 10487 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 10488 return CapturedExpr; 10489 } 10490 return BaseTransform::TransformMemberExpr(E); 10491 } 10492 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 10493 }; 10494 } // namespace 10495 10496 template <typename T, typename U> 10497 static T filterLookupForUDR(SmallVectorImpl<U> &Lookups, 10498 const llvm::function_ref<T(ValueDecl *)> Gen) { 10499 for (U &Set : Lookups) { 10500 for (auto *D : Set) { 10501 if (T Res = Gen(cast<ValueDecl>(D))) 10502 return Res; 10503 } 10504 } 10505 return T(); 10506 } 10507 10508 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 10509 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 10510 10511 for (auto RD : D->redecls()) { 10512 // Don't bother with extra checks if we already know this one isn't visible. 10513 if (RD == D) 10514 continue; 10515 10516 auto ND = cast<NamedDecl>(RD); 10517 if (LookupResult::isVisible(SemaRef, ND)) 10518 return ND; 10519 } 10520 10521 return nullptr; 10522 } 10523 10524 static void 10525 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId, 10526 SourceLocation Loc, QualType Ty, 10527 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 10528 // Find all of the associated namespaces and classes based on the 10529 // arguments we have. 10530 Sema::AssociatedNamespaceSet AssociatedNamespaces; 10531 Sema::AssociatedClassSet AssociatedClasses; 10532 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 10533 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 10534 AssociatedClasses); 10535 10536 // C++ [basic.lookup.argdep]p3: 10537 // Let X be the lookup set produced by unqualified lookup (3.4.1) 10538 // and let Y be the lookup set produced by argument dependent 10539 // lookup (defined as follows). If X contains [...] then Y is 10540 // empty. Otherwise Y is the set of declarations found in the 10541 // namespaces associated with the argument types as described 10542 // below. The set of declarations found by the lookup of the name 10543 // is the union of X and Y. 10544 // 10545 // Here, we compute Y and add its members to the overloaded 10546 // candidate set. 10547 for (auto *NS : AssociatedNamespaces) { 10548 // When considering an associated namespace, the lookup is the 10549 // same as the lookup performed when the associated namespace is 10550 // used as a qualifier (3.4.3.2) except that: 10551 // 10552 // -- Any using-directives in the associated namespace are 10553 // ignored. 10554 // 10555 // -- Any namespace-scope friend functions declared in 10556 // associated classes are visible within their respective 10557 // namespaces even if they are not visible during an ordinary 10558 // lookup (11.4). 10559 DeclContext::lookup_result R = NS->lookup(ReductionId.getName()); 10560 for (auto *D : R) { 10561 auto *Underlying = D; 10562 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10563 Underlying = USD->getTargetDecl(); 10564 10565 if (!isa<OMPDeclareReductionDecl>(Underlying)) 10566 continue; 10567 10568 if (!SemaRef.isVisible(D)) { 10569 D = findAcceptableDecl(SemaRef, D); 10570 if (!D) 10571 continue; 10572 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10573 Underlying = USD->getTargetDecl(); 10574 } 10575 Lookups.emplace_back(); 10576 Lookups.back().addDecl(Underlying); 10577 } 10578 } 10579 } 10580 10581 static ExprResult 10582 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 10583 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 10584 const DeclarationNameInfo &ReductionId, QualType Ty, 10585 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 10586 if (ReductionIdScopeSpec.isInvalid()) 10587 return ExprError(); 10588 SmallVector<UnresolvedSet<8>, 4> Lookups; 10589 if (S) { 10590 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10591 Lookup.suppressDiagnostics(); 10592 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 10593 NamedDecl *D = Lookup.getRepresentativeDecl(); 10594 do { 10595 S = S->getParent(); 10596 } while (S && !S->isDeclScope(D)); 10597 if (S) 10598 S = S->getParent(); 10599 Lookups.emplace_back(); 10600 Lookups.back().append(Lookup.begin(), Lookup.end()); 10601 Lookup.clear(); 10602 } 10603 } else if (auto *ULE = 10604 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 10605 Lookups.push_back(UnresolvedSet<8>()); 10606 Decl *PrevD = nullptr; 10607 for (NamedDecl *D : ULE->decls()) { 10608 if (D == PrevD) 10609 Lookups.push_back(UnresolvedSet<8>()); 10610 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 10611 Lookups.back().addDecl(DRD); 10612 PrevD = D; 10613 } 10614 } 10615 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 10616 Ty->isInstantiationDependentType() || 10617 Ty->containsUnexpandedParameterPack() || 10618 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) { 10619 return !D->isInvalidDecl() && 10620 (D->getType()->isDependentType() || 10621 D->getType()->isInstantiationDependentType() || 10622 D->getType()->containsUnexpandedParameterPack()); 10623 })) { 10624 UnresolvedSet<8> ResSet; 10625 for (const UnresolvedSet<8> &Set : Lookups) { 10626 if (Set.empty()) 10627 continue; 10628 ResSet.append(Set.begin(), Set.end()); 10629 // The last item marks the end of all declarations at the specified scope. 10630 ResSet.addDecl(Set[Set.size() - 1]); 10631 } 10632 return UnresolvedLookupExpr::Create( 10633 SemaRef.Context, /*NamingClass=*/nullptr, 10634 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 10635 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 10636 } 10637 // Lookup inside the classes. 10638 // C++ [over.match.oper]p3: 10639 // For a unary operator @ with an operand of a type whose 10640 // cv-unqualified version is T1, and for a binary operator @ with 10641 // a left operand of a type whose cv-unqualified version is T1 and 10642 // a right operand of a type whose cv-unqualified version is T2, 10643 // three sets of candidate functions, designated member 10644 // candidates, non-member candidates and built-in candidates, are 10645 // constructed as follows: 10646 // -- If T1 is a complete class type or a class currently being 10647 // defined, the set of member candidates is the result of the 10648 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 10649 // the set of member candidates is empty. 10650 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10651 Lookup.suppressDiagnostics(); 10652 if (const auto *TyRec = Ty->getAs<RecordType>()) { 10653 // Complete the type if it can be completed. 10654 // If the type is neither complete nor being defined, bail out now. 10655 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 10656 TyRec->getDecl()->getDefinition()) { 10657 Lookup.clear(); 10658 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 10659 if (Lookup.empty()) { 10660 Lookups.emplace_back(); 10661 Lookups.back().append(Lookup.begin(), Lookup.end()); 10662 } 10663 } 10664 } 10665 // Perform ADL. 10666 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 10667 if (auto *VD = filterLookupForUDR<ValueDecl *>( 10668 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 10669 if (!D->isInvalidDecl() && 10670 SemaRef.Context.hasSameType(D->getType(), Ty)) 10671 return D; 10672 return nullptr; 10673 })) 10674 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 10675 if (auto *VD = filterLookupForUDR<ValueDecl *>( 10676 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 10677 if (!D->isInvalidDecl() && 10678 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 10679 !Ty.isMoreQualifiedThan(D->getType())) 10680 return D; 10681 return nullptr; 10682 })) { 10683 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 10684 /*DetectVirtual=*/false); 10685 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 10686 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 10687 VD->getType().getUnqualifiedType()))) { 10688 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 10689 /*DiagID=*/0) != 10690 Sema::AR_inaccessible) { 10691 SemaRef.BuildBasePathArray(Paths, BasePath); 10692 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 10693 } 10694 } 10695 } 10696 } 10697 if (ReductionIdScopeSpec.isSet()) { 10698 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 10699 return ExprError(); 10700 } 10701 return ExprEmpty(); 10702 } 10703 10704 namespace { 10705 /// Data for the reduction-based clauses. 10706 struct ReductionData { 10707 /// List of original reduction items. 10708 SmallVector<Expr *, 8> Vars; 10709 /// List of private copies of the reduction items. 10710 SmallVector<Expr *, 8> Privates; 10711 /// LHS expressions for the reduction_op expressions. 10712 SmallVector<Expr *, 8> LHSs; 10713 /// RHS expressions for the reduction_op expressions. 10714 SmallVector<Expr *, 8> RHSs; 10715 /// Reduction operation expression. 10716 SmallVector<Expr *, 8> ReductionOps; 10717 /// Taskgroup descriptors for the corresponding reduction items in 10718 /// in_reduction clauses. 10719 SmallVector<Expr *, 8> TaskgroupDescriptors; 10720 /// List of captures for clause. 10721 SmallVector<Decl *, 4> ExprCaptures; 10722 /// List of postupdate expressions. 10723 SmallVector<Expr *, 4> ExprPostUpdates; 10724 ReductionData() = delete; 10725 /// Reserves required memory for the reduction data. 10726 ReductionData(unsigned Size) { 10727 Vars.reserve(Size); 10728 Privates.reserve(Size); 10729 LHSs.reserve(Size); 10730 RHSs.reserve(Size); 10731 ReductionOps.reserve(Size); 10732 TaskgroupDescriptors.reserve(Size); 10733 ExprCaptures.reserve(Size); 10734 ExprPostUpdates.reserve(Size); 10735 } 10736 /// Stores reduction item and reduction operation only (required for dependent 10737 /// reduction item). 10738 void push(Expr *Item, Expr *ReductionOp) { 10739 Vars.emplace_back(Item); 10740 Privates.emplace_back(nullptr); 10741 LHSs.emplace_back(nullptr); 10742 RHSs.emplace_back(nullptr); 10743 ReductionOps.emplace_back(ReductionOp); 10744 TaskgroupDescriptors.emplace_back(nullptr); 10745 } 10746 /// Stores reduction data. 10747 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 10748 Expr *TaskgroupDescriptor) { 10749 Vars.emplace_back(Item); 10750 Privates.emplace_back(Private); 10751 LHSs.emplace_back(LHS); 10752 RHSs.emplace_back(RHS); 10753 ReductionOps.emplace_back(ReductionOp); 10754 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 10755 } 10756 }; 10757 } // namespace 10758 10759 static bool checkOMPArraySectionConstantForReduction( 10760 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 10761 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 10762 const Expr *Length = OASE->getLength(); 10763 if (Length == nullptr) { 10764 // For array sections of the form [1:] or [:], we would need to analyze 10765 // the lower bound... 10766 if (OASE->getColonLoc().isValid()) 10767 return false; 10768 10769 // This is an array subscript which has implicit length 1! 10770 SingleElement = true; 10771 ArraySizes.push_back(llvm::APSInt::get(1)); 10772 } else { 10773 Expr::EvalResult Result; 10774 if (!Length->EvaluateAsInt(Result, Context)) 10775 return false; 10776 10777 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 10778 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 10779 ArraySizes.push_back(ConstantLengthValue); 10780 } 10781 10782 // Get the base of this array section and walk up from there. 10783 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 10784 10785 // We require length = 1 for all array sections except the right-most to 10786 // guarantee that the memory region is contiguous and has no holes in it. 10787 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 10788 Length = TempOASE->getLength(); 10789 if (Length == nullptr) { 10790 // For array sections of the form [1:] or [:], we would need to analyze 10791 // the lower bound... 10792 if (OASE->getColonLoc().isValid()) 10793 return false; 10794 10795 // This is an array subscript which has implicit length 1! 10796 ArraySizes.push_back(llvm::APSInt::get(1)); 10797 } else { 10798 Expr::EvalResult Result; 10799 if (!Length->EvaluateAsInt(Result, Context)) 10800 return false; 10801 10802 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 10803 if (ConstantLengthValue.getSExtValue() != 1) 10804 return false; 10805 10806 ArraySizes.push_back(ConstantLengthValue); 10807 } 10808 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 10809 } 10810 10811 // If we have a single element, we don't need to add the implicit lengths. 10812 if (!SingleElement) { 10813 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 10814 // Has implicit length 1! 10815 ArraySizes.push_back(llvm::APSInt::get(1)); 10816 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10817 } 10818 } 10819 10820 // This array section can be privatized as a single value or as a constant 10821 // sized array. 10822 return true; 10823 } 10824 10825 static bool actOnOMPReductionKindClause( 10826 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 10827 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10828 SourceLocation ColonLoc, SourceLocation EndLoc, 10829 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10830 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 10831 DeclarationName DN = ReductionId.getName(); 10832 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 10833 BinaryOperatorKind BOK = BO_Comma; 10834 10835 ASTContext &Context = S.Context; 10836 // OpenMP [2.14.3.6, reduction clause] 10837 // C 10838 // reduction-identifier is either an identifier or one of the following 10839 // operators: +, -, *, &, |, ^, && and || 10840 // C++ 10841 // reduction-identifier is either an id-expression or one of the following 10842 // operators: +, -, *, &, |, ^, && and || 10843 switch (OOK) { 10844 case OO_Plus: 10845 case OO_Minus: 10846 BOK = BO_Add; 10847 break; 10848 case OO_Star: 10849 BOK = BO_Mul; 10850 break; 10851 case OO_Amp: 10852 BOK = BO_And; 10853 break; 10854 case OO_Pipe: 10855 BOK = BO_Or; 10856 break; 10857 case OO_Caret: 10858 BOK = BO_Xor; 10859 break; 10860 case OO_AmpAmp: 10861 BOK = BO_LAnd; 10862 break; 10863 case OO_PipePipe: 10864 BOK = BO_LOr; 10865 break; 10866 case OO_New: 10867 case OO_Delete: 10868 case OO_Array_New: 10869 case OO_Array_Delete: 10870 case OO_Slash: 10871 case OO_Percent: 10872 case OO_Tilde: 10873 case OO_Exclaim: 10874 case OO_Equal: 10875 case OO_Less: 10876 case OO_Greater: 10877 case OO_LessEqual: 10878 case OO_GreaterEqual: 10879 case OO_PlusEqual: 10880 case OO_MinusEqual: 10881 case OO_StarEqual: 10882 case OO_SlashEqual: 10883 case OO_PercentEqual: 10884 case OO_CaretEqual: 10885 case OO_AmpEqual: 10886 case OO_PipeEqual: 10887 case OO_LessLess: 10888 case OO_GreaterGreater: 10889 case OO_LessLessEqual: 10890 case OO_GreaterGreaterEqual: 10891 case OO_EqualEqual: 10892 case OO_ExclaimEqual: 10893 case OO_Spaceship: 10894 case OO_PlusPlus: 10895 case OO_MinusMinus: 10896 case OO_Comma: 10897 case OO_ArrowStar: 10898 case OO_Arrow: 10899 case OO_Call: 10900 case OO_Subscript: 10901 case OO_Conditional: 10902 case OO_Coawait: 10903 case NUM_OVERLOADED_OPERATORS: 10904 llvm_unreachable("Unexpected reduction identifier"); 10905 case OO_None: 10906 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 10907 if (II->isStr("max")) 10908 BOK = BO_GT; 10909 else if (II->isStr("min")) 10910 BOK = BO_LT; 10911 } 10912 break; 10913 } 10914 SourceRange ReductionIdRange; 10915 if (ReductionIdScopeSpec.isValid()) 10916 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 10917 else 10918 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 10919 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 10920 10921 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 10922 bool FirstIter = true; 10923 for (Expr *RefExpr : VarList) { 10924 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 10925 // OpenMP [2.1, C/C++] 10926 // A list item is a variable or array section, subject to the restrictions 10927 // specified in Section 2.4 on page 42 and in each of the sections 10928 // describing clauses and directives for which a list appears. 10929 // OpenMP [2.14.3.3, Restrictions, p.1] 10930 // A variable that is part of another variable (as an array or 10931 // structure element) cannot appear in a private clause. 10932 if (!FirstIter && IR != ER) 10933 ++IR; 10934 FirstIter = false; 10935 SourceLocation ELoc; 10936 SourceRange ERange; 10937 Expr *SimpleRefExpr = RefExpr; 10938 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 10939 /*AllowArraySection=*/true); 10940 if (Res.second) { 10941 // Try to find 'declare reduction' corresponding construct before using 10942 // builtin/overloaded operators. 10943 QualType Type = Context.DependentTy; 10944 CXXCastPath BasePath; 10945 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10946 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10947 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10948 Expr *ReductionOp = nullptr; 10949 if (S.CurContext->isDependentContext() && 10950 (DeclareReductionRef.isUnset() || 10951 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 10952 ReductionOp = DeclareReductionRef.get(); 10953 // It will be analyzed later. 10954 RD.push(RefExpr, ReductionOp); 10955 } 10956 ValueDecl *D = Res.first; 10957 if (!D) 10958 continue; 10959 10960 Expr *TaskgroupDescriptor = nullptr; 10961 QualType Type; 10962 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 10963 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 10964 if (ASE) { 10965 Type = ASE->getType().getNonReferenceType(); 10966 } else if (OASE) { 10967 QualType BaseType = 10968 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 10969 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 10970 Type = ATy->getElementType(); 10971 else 10972 Type = BaseType->getPointeeType(); 10973 Type = Type.getNonReferenceType(); 10974 } else { 10975 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 10976 } 10977 auto *VD = dyn_cast<VarDecl>(D); 10978 10979 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10980 // A variable that appears in a private clause must not have an incomplete 10981 // type or a reference type. 10982 if (S.RequireCompleteType(ELoc, D->getType(), 10983 diag::err_omp_reduction_incomplete_type)) 10984 continue; 10985 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10986 // A list item that appears in a reduction clause must not be 10987 // const-qualified. 10988 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 10989 /*AcceptIfMutable*/ false, ASE || OASE)) 10990 continue; 10991 10992 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 10993 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 10994 // If a list-item is a reference type then it must bind to the same object 10995 // for all threads of the team. 10996 if (!ASE && !OASE) { 10997 if (VD) { 10998 VarDecl *VDDef = VD->getDefinition(); 10999 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11000 DSARefChecker Check(Stack); 11001 if (Check.Visit(VDDef->getInit())) { 11002 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11003 << getOpenMPClauseName(ClauseKind) << ERange; 11004 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11005 continue; 11006 } 11007 } 11008 } 11009 11010 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11011 // in a Construct] 11012 // Variables with the predetermined data-sharing attributes may not be 11013 // listed in data-sharing attributes clauses, except for the cases 11014 // listed below. For these exceptions only, listing a predetermined 11015 // variable in a data-sharing attribute clause is allowed and overrides 11016 // the variable's predetermined data-sharing attributes. 11017 // OpenMP [2.14.3.6, Restrictions, p.3] 11018 // Any number of reduction clauses can be specified on the directive, 11019 // but a list item can appear only once in the reduction clauses for that 11020 // directive. 11021 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11022 if (DVar.CKind == OMPC_reduction) { 11023 S.Diag(ELoc, diag::err_omp_once_referenced) 11024 << getOpenMPClauseName(ClauseKind); 11025 if (DVar.RefExpr) 11026 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 11027 continue; 11028 } 11029 if (DVar.CKind != OMPC_unknown) { 11030 S.Diag(ELoc, diag::err_omp_wrong_dsa) 11031 << getOpenMPClauseName(DVar.CKind) 11032 << getOpenMPClauseName(OMPC_reduction); 11033 reportOriginalDsa(S, Stack, D, DVar); 11034 continue; 11035 } 11036 11037 // OpenMP [2.14.3.6, Restrictions, p.1] 11038 // A list item that appears in a reduction clause of a worksharing 11039 // construct must be shared in the parallel regions to which any of the 11040 // worksharing regions arising from the worksharing construct bind. 11041 if (isOpenMPWorksharingDirective(CurrDir) && 11042 !isOpenMPParallelDirective(CurrDir) && 11043 !isOpenMPTeamsDirective(CurrDir)) { 11044 DVar = Stack->getImplicitDSA(D, true); 11045 if (DVar.CKind != OMPC_shared) { 11046 S.Diag(ELoc, diag::err_omp_required_access) 11047 << getOpenMPClauseName(OMPC_reduction) 11048 << getOpenMPClauseName(OMPC_shared); 11049 reportOriginalDsa(S, Stack, D, DVar); 11050 continue; 11051 } 11052 } 11053 } 11054 11055 // Try to find 'declare reduction' corresponding construct before using 11056 // builtin/overloaded operators. 11057 CXXCastPath BasePath; 11058 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11059 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11060 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11061 if (DeclareReductionRef.isInvalid()) 11062 continue; 11063 if (S.CurContext->isDependentContext() && 11064 (DeclareReductionRef.isUnset() || 11065 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 11066 RD.push(RefExpr, DeclareReductionRef.get()); 11067 continue; 11068 } 11069 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 11070 // Not allowed reduction identifier is found. 11071 S.Diag(ReductionId.getBeginLoc(), 11072 diag::err_omp_unknown_reduction_identifier) 11073 << Type << ReductionIdRange; 11074 continue; 11075 } 11076 11077 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11078 // The type of a list item that appears in a reduction clause must be valid 11079 // for the reduction-identifier. For a max or min reduction in C, the type 11080 // of the list item must be an allowed arithmetic data type: char, int, 11081 // float, double, or _Bool, possibly modified with long, short, signed, or 11082 // unsigned. For a max or min reduction in C++, the type of the list item 11083 // must be an allowed arithmetic data type: char, wchar_t, int, float, 11084 // double, or bool, possibly modified with long, short, signed, or unsigned. 11085 if (DeclareReductionRef.isUnset()) { 11086 if ((BOK == BO_GT || BOK == BO_LT) && 11087 !(Type->isScalarType() || 11088 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 11089 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 11090 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 11091 if (!ASE && !OASE) { 11092 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11093 VarDecl::DeclarationOnly; 11094 S.Diag(D->getLocation(), 11095 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11096 << D; 11097 } 11098 continue; 11099 } 11100 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 11101 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 11102 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 11103 << getOpenMPClauseName(ClauseKind); 11104 if (!ASE && !OASE) { 11105 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11106 VarDecl::DeclarationOnly; 11107 S.Diag(D->getLocation(), 11108 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11109 << D; 11110 } 11111 continue; 11112 } 11113 } 11114 11115 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 11116 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 11117 D->hasAttrs() ? &D->getAttrs() : nullptr); 11118 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 11119 D->hasAttrs() ? &D->getAttrs() : nullptr); 11120 QualType PrivateTy = Type; 11121 11122 // Try if we can determine constant lengths for all array sections and avoid 11123 // the VLA. 11124 bool ConstantLengthOASE = false; 11125 if (OASE) { 11126 bool SingleElement; 11127 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 11128 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 11129 Context, OASE, SingleElement, ArraySizes); 11130 11131 // If we don't have a single element, we must emit a constant array type. 11132 if (ConstantLengthOASE && !SingleElement) { 11133 for (llvm::APSInt &Size : ArraySizes) 11134 PrivateTy = Context.getConstantArrayType( 11135 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 11136 } 11137 } 11138 11139 if ((OASE && !ConstantLengthOASE) || 11140 (!OASE && !ASE && 11141 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 11142 if (!Context.getTargetInfo().isVLASupported() && 11143 S.shouldDiagnoseTargetSupportFromOpenMP()) { 11144 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 11145 S.Diag(ELoc, diag::note_vla_unsupported); 11146 continue; 11147 } 11148 // For arrays/array sections only: 11149 // Create pseudo array type for private copy. The size for this array will 11150 // be generated during codegen. 11151 // For array subscripts or single variables Private Ty is the same as Type 11152 // (type of the variable or single array element). 11153 PrivateTy = Context.getVariableArrayType( 11154 Type, 11155 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 11156 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 11157 } else if (!ASE && !OASE && 11158 Context.getAsArrayType(D->getType().getNonReferenceType())) { 11159 PrivateTy = D->getType().getNonReferenceType(); 11160 } 11161 // Private copy. 11162 VarDecl *PrivateVD = 11163 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 11164 D->hasAttrs() ? &D->getAttrs() : nullptr, 11165 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11166 // Add initializer for private variable. 11167 Expr *Init = nullptr; 11168 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 11169 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 11170 if (DeclareReductionRef.isUsable()) { 11171 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 11172 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 11173 if (DRD->getInitializer()) { 11174 Init = DRDRef; 11175 RHSVD->setInit(DRDRef); 11176 RHSVD->setInitStyle(VarDecl::CallInit); 11177 } 11178 } else { 11179 switch (BOK) { 11180 case BO_Add: 11181 case BO_Xor: 11182 case BO_Or: 11183 case BO_LOr: 11184 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 11185 if (Type->isScalarType() || Type->isAnyComplexType()) 11186 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 11187 break; 11188 case BO_Mul: 11189 case BO_LAnd: 11190 if (Type->isScalarType() || Type->isAnyComplexType()) { 11191 // '*' and '&&' reduction ops - initializer is '1'. 11192 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 11193 } 11194 break; 11195 case BO_And: { 11196 // '&' reduction op - initializer is '~0'. 11197 QualType OrigType = Type; 11198 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 11199 Type = ComplexTy->getElementType(); 11200 if (Type->isRealFloatingType()) { 11201 llvm::APFloat InitValue = 11202 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 11203 /*isIEEE=*/true); 11204 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11205 Type, ELoc); 11206 } else if (Type->isScalarType()) { 11207 uint64_t Size = Context.getTypeSize(Type); 11208 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 11209 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 11210 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11211 } 11212 if (Init && OrigType->isAnyComplexType()) { 11213 // Init = 0xFFFF + 0xFFFFi; 11214 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 11215 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 11216 } 11217 Type = OrigType; 11218 break; 11219 } 11220 case BO_LT: 11221 case BO_GT: { 11222 // 'min' reduction op - initializer is 'Largest representable number in 11223 // the reduction list item type'. 11224 // 'max' reduction op - initializer is 'Least representable number in 11225 // the reduction list item type'. 11226 if (Type->isIntegerType() || Type->isPointerType()) { 11227 bool IsSigned = Type->hasSignedIntegerRepresentation(); 11228 uint64_t Size = Context.getTypeSize(Type); 11229 QualType IntTy = 11230 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 11231 llvm::APInt InitValue = 11232 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 11233 : llvm::APInt::getMinValue(Size) 11234 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 11235 : llvm::APInt::getMaxValue(Size); 11236 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11237 if (Type->isPointerType()) { 11238 // Cast to pointer type. 11239 ExprResult CastExpr = S.BuildCStyleCastExpr( 11240 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 11241 if (CastExpr.isInvalid()) 11242 continue; 11243 Init = CastExpr.get(); 11244 } 11245 } else if (Type->isRealFloatingType()) { 11246 llvm::APFloat InitValue = llvm::APFloat::getLargest( 11247 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 11248 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11249 Type, ELoc); 11250 } 11251 break; 11252 } 11253 case BO_PtrMemD: 11254 case BO_PtrMemI: 11255 case BO_MulAssign: 11256 case BO_Div: 11257 case BO_Rem: 11258 case BO_Sub: 11259 case BO_Shl: 11260 case BO_Shr: 11261 case BO_LE: 11262 case BO_GE: 11263 case BO_EQ: 11264 case BO_NE: 11265 case BO_Cmp: 11266 case BO_AndAssign: 11267 case BO_XorAssign: 11268 case BO_OrAssign: 11269 case BO_Assign: 11270 case BO_AddAssign: 11271 case BO_SubAssign: 11272 case BO_DivAssign: 11273 case BO_RemAssign: 11274 case BO_ShlAssign: 11275 case BO_ShrAssign: 11276 case BO_Comma: 11277 llvm_unreachable("Unexpected reduction operation"); 11278 } 11279 } 11280 if (Init && DeclareReductionRef.isUnset()) 11281 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 11282 else if (!Init) 11283 S.ActOnUninitializedDecl(RHSVD); 11284 if (RHSVD->isInvalidDecl()) 11285 continue; 11286 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 11287 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 11288 << Type << ReductionIdRange; 11289 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11290 VarDecl::DeclarationOnly; 11291 S.Diag(D->getLocation(), 11292 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11293 << D; 11294 continue; 11295 } 11296 // Store initializer for single element in private copy. Will be used during 11297 // codegen. 11298 PrivateVD->setInit(RHSVD->getInit()); 11299 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 11300 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 11301 ExprResult ReductionOp; 11302 if (DeclareReductionRef.isUsable()) { 11303 QualType RedTy = DeclareReductionRef.get()->getType(); 11304 QualType PtrRedTy = Context.getPointerType(RedTy); 11305 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 11306 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 11307 if (!BasePath.empty()) { 11308 LHS = S.DefaultLvalueConversion(LHS.get()); 11309 RHS = S.DefaultLvalueConversion(RHS.get()); 11310 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11311 CK_UncheckedDerivedToBase, LHS.get(), 11312 &BasePath, LHS.get()->getValueKind()); 11313 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11314 CK_UncheckedDerivedToBase, RHS.get(), 11315 &BasePath, RHS.get()->getValueKind()); 11316 } 11317 FunctionProtoType::ExtProtoInfo EPI; 11318 QualType Params[] = {PtrRedTy, PtrRedTy}; 11319 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 11320 auto *OVE = new (Context) OpaqueValueExpr( 11321 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 11322 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 11323 Expr *Args[] = {LHS.get(), RHS.get()}; 11324 ReductionOp = 11325 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 11326 } else { 11327 ReductionOp = S.BuildBinOp( 11328 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 11329 if (ReductionOp.isUsable()) { 11330 if (BOK != BO_LT && BOK != BO_GT) { 11331 ReductionOp = 11332 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11333 BO_Assign, LHSDRE, ReductionOp.get()); 11334 } else { 11335 auto *ConditionalOp = new (Context) 11336 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 11337 Type, VK_LValue, OK_Ordinary); 11338 ReductionOp = 11339 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11340 BO_Assign, LHSDRE, ConditionalOp); 11341 } 11342 if (ReductionOp.isUsable()) 11343 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 11344 /*DiscardedValue*/ false); 11345 } 11346 if (!ReductionOp.isUsable()) 11347 continue; 11348 } 11349 11350 // OpenMP [2.15.4.6, Restrictions, p.2] 11351 // A list item that appears in an in_reduction clause of a task construct 11352 // must appear in a task_reduction clause of a construct associated with a 11353 // taskgroup region that includes the participating task in its taskgroup 11354 // set. The construct associated with the innermost region that meets this 11355 // condition must specify the same reduction-identifier as the in_reduction 11356 // clause. 11357 if (ClauseKind == OMPC_in_reduction) { 11358 SourceRange ParentSR; 11359 BinaryOperatorKind ParentBOK; 11360 const Expr *ParentReductionOp; 11361 Expr *ParentBOKTD, *ParentReductionOpTD; 11362 DSAStackTy::DSAVarData ParentBOKDSA = 11363 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 11364 ParentBOKTD); 11365 DSAStackTy::DSAVarData ParentReductionOpDSA = 11366 Stack->getTopMostTaskgroupReductionData( 11367 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 11368 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 11369 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 11370 if (!IsParentBOK && !IsParentReductionOp) { 11371 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 11372 continue; 11373 } 11374 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 11375 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 11376 IsParentReductionOp) { 11377 bool EmitError = true; 11378 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 11379 llvm::FoldingSetNodeID RedId, ParentRedId; 11380 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 11381 DeclareReductionRef.get()->Profile(RedId, Context, 11382 /*Canonical=*/true); 11383 EmitError = RedId != ParentRedId; 11384 } 11385 if (EmitError) { 11386 S.Diag(ReductionId.getBeginLoc(), 11387 diag::err_omp_reduction_identifier_mismatch) 11388 << ReductionIdRange << RefExpr->getSourceRange(); 11389 S.Diag(ParentSR.getBegin(), 11390 diag::note_omp_previous_reduction_identifier) 11391 << ParentSR 11392 << (IsParentBOK ? ParentBOKDSA.RefExpr 11393 : ParentReductionOpDSA.RefExpr) 11394 ->getSourceRange(); 11395 continue; 11396 } 11397 } 11398 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 11399 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 11400 } 11401 11402 DeclRefExpr *Ref = nullptr; 11403 Expr *VarsExpr = RefExpr->IgnoreParens(); 11404 if (!VD && !S.CurContext->isDependentContext()) { 11405 if (ASE || OASE) { 11406 TransformExprToCaptures RebuildToCapture(S, D); 11407 VarsExpr = 11408 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 11409 Ref = RebuildToCapture.getCapturedExpr(); 11410 } else { 11411 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 11412 } 11413 if (!S.isOpenMPCapturedDecl(D)) { 11414 RD.ExprCaptures.emplace_back(Ref->getDecl()); 11415 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11416 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 11417 if (!RefRes.isUsable()) 11418 continue; 11419 ExprResult PostUpdateRes = 11420 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11421 RefRes.get()); 11422 if (!PostUpdateRes.isUsable()) 11423 continue; 11424 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 11425 Stack->getCurrentDirective() == OMPD_taskgroup) { 11426 S.Diag(RefExpr->getExprLoc(), 11427 diag::err_omp_reduction_non_addressable_expression) 11428 << RefExpr->getSourceRange(); 11429 continue; 11430 } 11431 RD.ExprPostUpdates.emplace_back( 11432 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 11433 } 11434 } 11435 } 11436 // All reduction items are still marked as reduction (to do not increase 11437 // code base size). 11438 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 11439 if (CurrDir == OMPD_taskgroup) { 11440 if (DeclareReductionRef.isUsable()) 11441 Stack->addTaskgroupReductionData(D, ReductionIdRange, 11442 DeclareReductionRef.get()); 11443 else 11444 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 11445 } 11446 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 11447 TaskgroupDescriptor); 11448 } 11449 return RD.Vars.empty(); 11450 } 11451 11452 OMPClause *Sema::ActOnOpenMPReductionClause( 11453 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11454 SourceLocation ColonLoc, SourceLocation EndLoc, 11455 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11456 ArrayRef<Expr *> UnresolvedReductions) { 11457 ReductionData RD(VarList.size()); 11458 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 11459 StartLoc, LParenLoc, ColonLoc, EndLoc, 11460 ReductionIdScopeSpec, ReductionId, 11461 UnresolvedReductions, RD)) 11462 return nullptr; 11463 11464 return OMPReductionClause::Create( 11465 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11466 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11467 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11468 buildPreInits(Context, RD.ExprCaptures), 11469 buildPostUpdate(*this, RD.ExprPostUpdates)); 11470 } 11471 11472 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 11473 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11474 SourceLocation ColonLoc, SourceLocation EndLoc, 11475 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11476 ArrayRef<Expr *> UnresolvedReductions) { 11477 ReductionData RD(VarList.size()); 11478 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 11479 StartLoc, LParenLoc, ColonLoc, EndLoc, 11480 ReductionIdScopeSpec, ReductionId, 11481 UnresolvedReductions, RD)) 11482 return nullptr; 11483 11484 return OMPTaskReductionClause::Create( 11485 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11486 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11487 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11488 buildPreInits(Context, RD.ExprCaptures), 11489 buildPostUpdate(*this, RD.ExprPostUpdates)); 11490 } 11491 11492 OMPClause *Sema::ActOnOpenMPInReductionClause( 11493 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11494 SourceLocation ColonLoc, SourceLocation EndLoc, 11495 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11496 ArrayRef<Expr *> UnresolvedReductions) { 11497 ReductionData RD(VarList.size()); 11498 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 11499 StartLoc, LParenLoc, ColonLoc, EndLoc, 11500 ReductionIdScopeSpec, ReductionId, 11501 UnresolvedReductions, RD)) 11502 return nullptr; 11503 11504 return OMPInReductionClause::Create( 11505 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11506 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11507 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 11508 buildPreInits(Context, RD.ExprCaptures), 11509 buildPostUpdate(*this, RD.ExprPostUpdates)); 11510 } 11511 11512 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 11513 SourceLocation LinLoc) { 11514 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 11515 LinKind == OMPC_LINEAR_unknown) { 11516 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 11517 return true; 11518 } 11519 return false; 11520 } 11521 11522 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 11523 OpenMPLinearClauseKind LinKind, 11524 QualType Type) { 11525 const auto *VD = dyn_cast_or_null<VarDecl>(D); 11526 // A variable must not have an incomplete type or a reference type. 11527 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 11528 return true; 11529 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 11530 !Type->isReferenceType()) { 11531 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 11532 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 11533 return true; 11534 } 11535 Type = Type.getNonReferenceType(); 11536 11537 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11538 // A variable that is privatized must not have a const-qualified type 11539 // unless it is of class type with a mutable member. This restriction does 11540 // not apply to the firstprivate clause. 11541 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 11542 return true; 11543 11544 // A list item must be of integral or pointer type. 11545 Type = Type.getUnqualifiedType().getCanonicalType(); 11546 const auto *Ty = Type.getTypePtrOrNull(); 11547 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 11548 !Ty->isPointerType())) { 11549 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 11550 if (D) { 11551 bool IsDecl = 11552 !VD || 11553 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11554 Diag(D->getLocation(), 11555 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11556 << D; 11557 } 11558 return true; 11559 } 11560 return false; 11561 } 11562 11563 OMPClause *Sema::ActOnOpenMPLinearClause( 11564 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 11565 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 11566 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11567 SmallVector<Expr *, 8> Vars; 11568 SmallVector<Expr *, 8> Privates; 11569 SmallVector<Expr *, 8> Inits; 11570 SmallVector<Decl *, 4> ExprCaptures; 11571 SmallVector<Expr *, 4> ExprPostUpdates; 11572 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 11573 LinKind = OMPC_LINEAR_val; 11574 for (Expr *RefExpr : VarList) { 11575 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11576 SourceLocation ELoc; 11577 SourceRange ERange; 11578 Expr *SimpleRefExpr = RefExpr; 11579 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11580 if (Res.second) { 11581 // It will be analyzed later. 11582 Vars.push_back(RefExpr); 11583 Privates.push_back(nullptr); 11584 Inits.push_back(nullptr); 11585 } 11586 ValueDecl *D = Res.first; 11587 if (!D) 11588 continue; 11589 11590 QualType Type = D->getType(); 11591 auto *VD = dyn_cast<VarDecl>(D); 11592 11593 // OpenMP [2.14.3.7, linear clause] 11594 // A list-item cannot appear in more than one linear clause. 11595 // A list-item that appears in a linear clause cannot appear in any 11596 // other data-sharing attribute clause. 11597 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11598 if (DVar.RefExpr) { 11599 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11600 << getOpenMPClauseName(OMPC_linear); 11601 reportOriginalDsa(*this, DSAStack, D, DVar); 11602 continue; 11603 } 11604 11605 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 11606 continue; 11607 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11608 11609 // Build private copy of original var. 11610 VarDecl *Private = 11611 buildVarDecl(*this, ELoc, Type, D->getName(), 11612 D->hasAttrs() ? &D->getAttrs() : nullptr, 11613 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11614 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 11615 // Build var to save initial value. 11616 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 11617 Expr *InitExpr; 11618 DeclRefExpr *Ref = nullptr; 11619 if (!VD && !CurContext->isDependentContext()) { 11620 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11621 if (!isOpenMPCapturedDecl(D)) { 11622 ExprCaptures.push_back(Ref->getDecl()); 11623 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11624 ExprResult RefRes = DefaultLvalueConversion(Ref); 11625 if (!RefRes.isUsable()) 11626 continue; 11627 ExprResult PostUpdateRes = 11628 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 11629 SimpleRefExpr, RefRes.get()); 11630 if (!PostUpdateRes.isUsable()) 11631 continue; 11632 ExprPostUpdates.push_back( 11633 IgnoredValueConversions(PostUpdateRes.get()).get()); 11634 } 11635 } 11636 } 11637 if (LinKind == OMPC_LINEAR_uval) 11638 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 11639 else 11640 InitExpr = VD ? SimpleRefExpr : Ref; 11641 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 11642 /*DirectInit=*/false); 11643 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 11644 11645 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 11646 Vars.push_back((VD || CurContext->isDependentContext()) 11647 ? RefExpr->IgnoreParens() 11648 : Ref); 11649 Privates.push_back(PrivateRef); 11650 Inits.push_back(InitRef); 11651 } 11652 11653 if (Vars.empty()) 11654 return nullptr; 11655 11656 Expr *StepExpr = Step; 11657 Expr *CalcStepExpr = nullptr; 11658 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 11659 !Step->isInstantiationDependent() && 11660 !Step->containsUnexpandedParameterPack()) { 11661 SourceLocation StepLoc = Step->getBeginLoc(); 11662 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 11663 if (Val.isInvalid()) 11664 return nullptr; 11665 StepExpr = Val.get(); 11666 11667 // Build var to save the step value. 11668 VarDecl *SaveVar = 11669 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 11670 ExprResult SaveRef = 11671 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 11672 ExprResult CalcStep = 11673 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 11674 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 11675 11676 // Warn about zero linear step (it would be probably better specified as 11677 // making corresponding variables 'const'). 11678 llvm::APSInt Result; 11679 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 11680 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 11681 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 11682 << (Vars.size() > 1); 11683 if (!IsConstant && CalcStep.isUsable()) { 11684 // Calculate the step beforehand instead of doing this on each iteration. 11685 // (This is not used if the number of iterations may be kfold-ed). 11686 CalcStepExpr = CalcStep.get(); 11687 } 11688 } 11689 11690 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 11691 ColonLoc, EndLoc, Vars, Privates, Inits, 11692 StepExpr, CalcStepExpr, 11693 buildPreInits(Context, ExprCaptures), 11694 buildPostUpdate(*this, ExprPostUpdates)); 11695 } 11696 11697 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 11698 Expr *NumIterations, Sema &SemaRef, 11699 Scope *S, DSAStackTy *Stack) { 11700 // Walk the vars and build update/final expressions for the CodeGen. 11701 SmallVector<Expr *, 8> Updates; 11702 SmallVector<Expr *, 8> Finals; 11703 Expr *Step = Clause.getStep(); 11704 Expr *CalcStep = Clause.getCalcStep(); 11705 // OpenMP [2.14.3.7, linear clause] 11706 // If linear-step is not specified it is assumed to be 1. 11707 if (!Step) 11708 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 11709 else if (CalcStep) 11710 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 11711 bool HasErrors = false; 11712 auto CurInit = Clause.inits().begin(); 11713 auto CurPrivate = Clause.privates().begin(); 11714 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 11715 for (Expr *RefExpr : Clause.varlists()) { 11716 SourceLocation ELoc; 11717 SourceRange ERange; 11718 Expr *SimpleRefExpr = RefExpr; 11719 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 11720 ValueDecl *D = Res.first; 11721 if (Res.second || !D) { 11722 Updates.push_back(nullptr); 11723 Finals.push_back(nullptr); 11724 HasErrors = true; 11725 continue; 11726 } 11727 auto &&Info = Stack->isLoopControlVariable(D); 11728 // OpenMP [2.15.11, distribute simd Construct] 11729 // A list item may not appear in a linear clause, unless it is the loop 11730 // iteration variable. 11731 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 11732 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 11733 SemaRef.Diag(ELoc, 11734 diag::err_omp_linear_distribute_var_non_loop_iteration); 11735 Updates.push_back(nullptr); 11736 Finals.push_back(nullptr); 11737 HasErrors = true; 11738 continue; 11739 } 11740 Expr *InitExpr = *CurInit; 11741 11742 // Build privatized reference to the current linear var. 11743 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 11744 Expr *CapturedRef; 11745 if (LinKind == OMPC_LINEAR_uval) 11746 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 11747 else 11748 CapturedRef = 11749 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 11750 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 11751 /*RefersToCapture=*/true); 11752 11753 // Build update: Var = InitExpr + IV * Step 11754 ExprResult Update; 11755 if (!Info.first) 11756 Update = 11757 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 11758 InitExpr, IV, Step, /* Subtract */ false); 11759 else 11760 Update = *CurPrivate; 11761 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 11762 /*DiscardedValue*/ false); 11763 11764 // Build final: Var = InitExpr + NumIterations * Step 11765 ExprResult Final; 11766 if (!Info.first) 11767 Final = 11768 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 11769 InitExpr, NumIterations, Step, /*Subtract=*/false); 11770 else 11771 Final = *CurPrivate; 11772 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 11773 /*DiscardedValue*/ false); 11774 11775 if (!Update.isUsable() || !Final.isUsable()) { 11776 Updates.push_back(nullptr); 11777 Finals.push_back(nullptr); 11778 HasErrors = true; 11779 } else { 11780 Updates.push_back(Update.get()); 11781 Finals.push_back(Final.get()); 11782 } 11783 ++CurInit; 11784 ++CurPrivate; 11785 } 11786 Clause.setUpdates(Updates); 11787 Clause.setFinals(Finals); 11788 return HasErrors; 11789 } 11790 11791 OMPClause *Sema::ActOnOpenMPAlignedClause( 11792 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 11793 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11794 SmallVector<Expr *, 8> Vars; 11795 for (Expr *RefExpr : VarList) { 11796 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11797 SourceLocation ELoc; 11798 SourceRange ERange; 11799 Expr *SimpleRefExpr = RefExpr; 11800 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11801 if (Res.second) { 11802 // It will be analyzed later. 11803 Vars.push_back(RefExpr); 11804 } 11805 ValueDecl *D = Res.first; 11806 if (!D) 11807 continue; 11808 11809 QualType QType = D->getType(); 11810 auto *VD = dyn_cast<VarDecl>(D); 11811 11812 // OpenMP [2.8.1, simd construct, Restrictions] 11813 // The type of list items appearing in the aligned clause must be 11814 // array, pointer, reference to array, or reference to pointer. 11815 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 11816 const Type *Ty = QType.getTypePtrOrNull(); 11817 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 11818 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 11819 << QType << getLangOpts().CPlusPlus << ERange; 11820 bool IsDecl = 11821 !VD || 11822 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11823 Diag(D->getLocation(), 11824 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11825 << D; 11826 continue; 11827 } 11828 11829 // OpenMP [2.8.1, simd construct, Restrictions] 11830 // A list-item cannot appear in more than one aligned clause. 11831 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 11832 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 11833 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 11834 << getOpenMPClauseName(OMPC_aligned); 11835 continue; 11836 } 11837 11838 DeclRefExpr *Ref = nullptr; 11839 if (!VD && isOpenMPCapturedDecl(D)) 11840 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11841 Vars.push_back(DefaultFunctionArrayConversion( 11842 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 11843 .get()); 11844 } 11845 11846 // OpenMP [2.8.1, simd construct, Description] 11847 // The parameter of the aligned clause, alignment, must be a constant 11848 // positive integer expression. 11849 // If no optional parameter is specified, implementation-defined default 11850 // alignments for SIMD instructions on the target platforms are assumed. 11851 if (Alignment != nullptr) { 11852 ExprResult AlignResult = 11853 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 11854 if (AlignResult.isInvalid()) 11855 return nullptr; 11856 Alignment = AlignResult.get(); 11857 } 11858 if (Vars.empty()) 11859 return nullptr; 11860 11861 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 11862 EndLoc, Vars, Alignment); 11863 } 11864 11865 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 11866 SourceLocation StartLoc, 11867 SourceLocation LParenLoc, 11868 SourceLocation EndLoc) { 11869 SmallVector<Expr *, 8> Vars; 11870 SmallVector<Expr *, 8> SrcExprs; 11871 SmallVector<Expr *, 8> DstExprs; 11872 SmallVector<Expr *, 8> AssignmentOps; 11873 for (Expr *RefExpr : VarList) { 11874 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 11875 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 11876 // It will be analyzed later. 11877 Vars.push_back(RefExpr); 11878 SrcExprs.push_back(nullptr); 11879 DstExprs.push_back(nullptr); 11880 AssignmentOps.push_back(nullptr); 11881 continue; 11882 } 11883 11884 SourceLocation ELoc = RefExpr->getExprLoc(); 11885 // OpenMP [2.1, C/C++] 11886 // A list item is a variable name. 11887 // OpenMP [2.14.4.1, Restrictions, p.1] 11888 // A list item that appears in a copyin clause must be threadprivate. 11889 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 11890 if (!DE || !isa<VarDecl>(DE->getDecl())) { 11891 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 11892 << 0 << RefExpr->getSourceRange(); 11893 continue; 11894 } 11895 11896 Decl *D = DE->getDecl(); 11897 auto *VD = cast<VarDecl>(D); 11898 11899 QualType Type = VD->getType(); 11900 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 11901 // It will be analyzed later. 11902 Vars.push_back(DE); 11903 SrcExprs.push_back(nullptr); 11904 DstExprs.push_back(nullptr); 11905 AssignmentOps.push_back(nullptr); 11906 continue; 11907 } 11908 11909 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 11910 // A list item that appears in a copyin clause must be threadprivate. 11911 if (!DSAStack->isThreadPrivate(VD)) { 11912 Diag(ELoc, diag::err_omp_required_access) 11913 << getOpenMPClauseName(OMPC_copyin) 11914 << getOpenMPDirectiveName(OMPD_threadprivate); 11915 continue; 11916 } 11917 11918 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11919 // A variable of class type (or array thereof) that appears in a 11920 // copyin clause requires an accessible, unambiguous copy assignment 11921 // operator for the class type. 11922 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11923 VarDecl *SrcVD = 11924 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 11925 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11926 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 11927 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 11928 VarDecl *DstVD = 11929 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 11930 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11931 DeclRefExpr *PseudoDstExpr = 11932 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 11933 // For arrays generate assignment operation for single element and replace 11934 // it by the original array element in CodeGen. 11935 ExprResult AssignmentOp = 11936 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 11937 PseudoSrcExpr); 11938 if (AssignmentOp.isInvalid()) 11939 continue; 11940 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 11941 /*DiscardedValue*/ false); 11942 if (AssignmentOp.isInvalid()) 11943 continue; 11944 11945 DSAStack->addDSA(VD, DE, OMPC_copyin); 11946 Vars.push_back(DE); 11947 SrcExprs.push_back(PseudoSrcExpr); 11948 DstExprs.push_back(PseudoDstExpr); 11949 AssignmentOps.push_back(AssignmentOp.get()); 11950 } 11951 11952 if (Vars.empty()) 11953 return nullptr; 11954 11955 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11956 SrcExprs, DstExprs, AssignmentOps); 11957 } 11958 11959 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 11960 SourceLocation StartLoc, 11961 SourceLocation LParenLoc, 11962 SourceLocation EndLoc) { 11963 SmallVector<Expr *, 8> Vars; 11964 SmallVector<Expr *, 8> SrcExprs; 11965 SmallVector<Expr *, 8> DstExprs; 11966 SmallVector<Expr *, 8> AssignmentOps; 11967 for (Expr *RefExpr : VarList) { 11968 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11969 SourceLocation ELoc; 11970 SourceRange ERange; 11971 Expr *SimpleRefExpr = RefExpr; 11972 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11973 if (Res.second) { 11974 // It will be analyzed later. 11975 Vars.push_back(RefExpr); 11976 SrcExprs.push_back(nullptr); 11977 DstExprs.push_back(nullptr); 11978 AssignmentOps.push_back(nullptr); 11979 } 11980 ValueDecl *D = Res.first; 11981 if (!D) 11982 continue; 11983 11984 QualType Type = D->getType(); 11985 auto *VD = dyn_cast<VarDecl>(D); 11986 11987 // OpenMP [2.14.4.2, Restrictions, p.2] 11988 // A list item that appears in a copyprivate clause may not appear in a 11989 // private or firstprivate clause on the single construct. 11990 if (!VD || !DSAStack->isThreadPrivate(VD)) { 11991 DSAStackTy::DSAVarData DVar = 11992 DSAStack->getTopDSA(D, /*FromParent=*/false); 11993 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 11994 DVar.RefExpr) { 11995 Diag(ELoc, diag::err_omp_wrong_dsa) 11996 << getOpenMPClauseName(DVar.CKind) 11997 << getOpenMPClauseName(OMPC_copyprivate); 11998 reportOriginalDsa(*this, DSAStack, D, DVar); 11999 continue; 12000 } 12001 12002 // OpenMP [2.11.4.2, Restrictions, p.1] 12003 // All list items that appear in a copyprivate clause must be either 12004 // threadprivate or private in the enclosing context. 12005 if (DVar.CKind == OMPC_unknown) { 12006 DVar = DSAStack->getImplicitDSA(D, false); 12007 if (DVar.CKind == OMPC_shared) { 12008 Diag(ELoc, diag::err_omp_required_access) 12009 << getOpenMPClauseName(OMPC_copyprivate) 12010 << "threadprivate or private in the enclosing context"; 12011 reportOriginalDsa(*this, DSAStack, D, DVar); 12012 continue; 12013 } 12014 } 12015 } 12016 12017 // Variably modified types are not supported. 12018 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12019 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12020 << getOpenMPClauseName(OMPC_copyprivate) << Type 12021 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12022 bool IsDecl = 12023 !VD || 12024 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12025 Diag(D->getLocation(), 12026 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12027 << D; 12028 continue; 12029 } 12030 12031 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12032 // A variable of class type (or array thereof) that appears in a 12033 // copyin clause requires an accessible, unambiguous copy assignment 12034 // operator for the class type. 12035 Type = Context.getBaseElementType(Type.getNonReferenceType()) 12036 .getUnqualifiedType(); 12037 VarDecl *SrcVD = 12038 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 12039 D->hasAttrs() ? &D->getAttrs() : nullptr); 12040 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 12041 VarDecl *DstVD = 12042 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 12043 D->hasAttrs() ? &D->getAttrs() : nullptr); 12044 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12045 ExprResult AssignmentOp = BuildBinOp( 12046 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 12047 if (AssignmentOp.isInvalid()) 12048 continue; 12049 AssignmentOp = 12050 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12051 if (AssignmentOp.isInvalid()) 12052 continue; 12053 12054 // No need to mark vars as copyprivate, they are already threadprivate or 12055 // implicitly private. 12056 assert(VD || isOpenMPCapturedDecl(D)); 12057 Vars.push_back( 12058 VD ? RefExpr->IgnoreParens() 12059 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 12060 SrcExprs.push_back(PseudoSrcExpr); 12061 DstExprs.push_back(PseudoDstExpr); 12062 AssignmentOps.push_back(AssignmentOp.get()); 12063 } 12064 12065 if (Vars.empty()) 12066 return nullptr; 12067 12068 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12069 Vars, SrcExprs, DstExprs, AssignmentOps); 12070 } 12071 12072 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 12073 SourceLocation StartLoc, 12074 SourceLocation LParenLoc, 12075 SourceLocation EndLoc) { 12076 if (VarList.empty()) 12077 return nullptr; 12078 12079 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 12080 } 12081 12082 OMPClause * 12083 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 12084 SourceLocation DepLoc, SourceLocation ColonLoc, 12085 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12086 SourceLocation LParenLoc, SourceLocation EndLoc) { 12087 if (DSAStack->getCurrentDirective() == OMPD_ordered && 12088 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 12089 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12090 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 12091 return nullptr; 12092 } 12093 if (DSAStack->getCurrentDirective() != OMPD_ordered && 12094 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 12095 DepKind == OMPC_DEPEND_sink)) { 12096 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 12097 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12098 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12099 /*Last=*/OMPC_DEPEND_unknown, Except) 12100 << getOpenMPClauseName(OMPC_depend); 12101 return nullptr; 12102 } 12103 SmallVector<Expr *, 8> Vars; 12104 DSAStackTy::OperatorOffsetTy OpsOffs; 12105 llvm::APSInt DepCounter(/*BitWidth=*/32); 12106 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 12107 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 12108 if (const Expr *OrderedCountExpr = 12109 DSAStack->getParentOrderedRegionParam().first) { 12110 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 12111 TotalDepCount.setIsUnsigned(/*Val=*/true); 12112 } 12113 } 12114 for (Expr *RefExpr : VarList) { 12115 assert(RefExpr && "NULL expr in OpenMP shared clause."); 12116 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12117 // It will be analyzed later. 12118 Vars.push_back(RefExpr); 12119 continue; 12120 } 12121 12122 SourceLocation ELoc = RefExpr->getExprLoc(); 12123 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 12124 if (DepKind == OMPC_DEPEND_sink) { 12125 if (DSAStack->getParentOrderedRegionParam().first && 12126 DepCounter >= TotalDepCount) { 12127 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 12128 continue; 12129 } 12130 ++DepCounter; 12131 // OpenMP [2.13.9, Summary] 12132 // depend(dependence-type : vec), where dependence-type is: 12133 // 'sink' and where vec is the iteration vector, which has the form: 12134 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 12135 // where n is the value specified by the ordered clause in the loop 12136 // directive, xi denotes the loop iteration variable of the i-th nested 12137 // loop associated with the loop directive, and di is a constant 12138 // non-negative integer. 12139 if (CurContext->isDependentContext()) { 12140 // It will be analyzed later. 12141 Vars.push_back(RefExpr); 12142 continue; 12143 } 12144 SimpleExpr = SimpleExpr->IgnoreImplicit(); 12145 OverloadedOperatorKind OOK = OO_None; 12146 SourceLocation OOLoc; 12147 Expr *LHS = SimpleExpr; 12148 Expr *RHS = nullptr; 12149 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 12150 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 12151 OOLoc = BO->getOperatorLoc(); 12152 LHS = BO->getLHS()->IgnoreParenImpCasts(); 12153 RHS = BO->getRHS()->IgnoreParenImpCasts(); 12154 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 12155 OOK = OCE->getOperator(); 12156 OOLoc = OCE->getOperatorLoc(); 12157 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12158 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 12159 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 12160 OOK = MCE->getMethodDecl() 12161 ->getNameInfo() 12162 .getName() 12163 .getCXXOverloadedOperator(); 12164 OOLoc = MCE->getCallee()->getExprLoc(); 12165 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 12166 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12167 } 12168 SourceLocation ELoc; 12169 SourceRange ERange; 12170 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 12171 if (Res.second) { 12172 // It will be analyzed later. 12173 Vars.push_back(RefExpr); 12174 } 12175 ValueDecl *D = Res.first; 12176 if (!D) 12177 continue; 12178 12179 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 12180 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 12181 continue; 12182 } 12183 if (RHS) { 12184 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 12185 RHS, OMPC_depend, /*StrictlyPositive=*/false); 12186 if (RHSRes.isInvalid()) 12187 continue; 12188 } 12189 if (!CurContext->isDependentContext() && 12190 DSAStack->getParentOrderedRegionParam().first && 12191 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 12192 const ValueDecl *VD = 12193 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 12194 if (VD) 12195 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 12196 << 1 << VD; 12197 else 12198 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 12199 continue; 12200 } 12201 OpsOffs.emplace_back(RHS, OOK); 12202 } else { 12203 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 12204 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 12205 (ASE && 12206 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 12207 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 12208 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12209 << RefExpr->getSourceRange(); 12210 continue; 12211 } 12212 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 12213 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 12214 ExprResult Res = 12215 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 12216 getDiagnostics().setSuppressAllDiagnostics(Suppress); 12217 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 12218 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12219 << RefExpr->getSourceRange(); 12220 continue; 12221 } 12222 } 12223 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 12224 } 12225 12226 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 12227 TotalDepCount > VarList.size() && 12228 DSAStack->getParentOrderedRegionParam().first && 12229 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 12230 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 12231 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 12232 } 12233 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 12234 Vars.empty()) 12235 return nullptr; 12236 12237 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12238 DepKind, DepLoc, ColonLoc, Vars, 12239 TotalDepCount.getZExtValue()); 12240 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 12241 DSAStack->isParentOrderedRegion()) 12242 DSAStack->addDoacrossDependClause(C, OpsOffs); 12243 return C; 12244 } 12245 12246 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 12247 SourceLocation LParenLoc, 12248 SourceLocation EndLoc) { 12249 Expr *ValExpr = Device; 12250 Stmt *HelperValStmt = nullptr; 12251 12252 // OpenMP [2.9.1, Restrictions] 12253 // The device expression must evaluate to a non-negative integer value. 12254 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 12255 /*StrictlyPositive=*/false)) 12256 return nullptr; 12257 12258 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12259 OpenMPDirectiveKind CaptureRegion = 12260 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 12261 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12262 ValExpr = MakeFullExpr(ValExpr).get(); 12263 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12264 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12265 HelperValStmt = buildPreInits(Context, Captures); 12266 } 12267 12268 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 12269 StartLoc, LParenLoc, EndLoc); 12270 } 12271 12272 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 12273 DSAStackTy *Stack, QualType QTy, 12274 bool FullCheck = true) { 12275 NamedDecl *ND; 12276 if (QTy->isIncompleteType(&ND)) { 12277 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 12278 return false; 12279 } 12280 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 12281 !QTy.isTrivialType(SemaRef.Context)) 12282 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 12283 return true; 12284 } 12285 12286 /// Return true if it can be proven that the provided array expression 12287 /// (array section or array subscript) does NOT specify the whole size of the 12288 /// array whose base type is \a BaseQTy. 12289 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 12290 const Expr *E, 12291 QualType BaseQTy) { 12292 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12293 12294 // If this is an array subscript, it refers to the whole size if the size of 12295 // the dimension is constant and equals 1. Also, an array section assumes the 12296 // format of an array subscript if no colon is used. 12297 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 12298 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12299 return ATy->getSize().getSExtValue() != 1; 12300 // Size can't be evaluated statically. 12301 return false; 12302 } 12303 12304 assert(OASE && "Expecting array section if not an array subscript."); 12305 const Expr *LowerBound = OASE->getLowerBound(); 12306 const Expr *Length = OASE->getLength(); 12307 12308 // If there is a lower bound that does not evaluates to zero, we are not 12309 // covering the whole dimension. 12310 if (LowerBound) { 12311 Expr::EvalResult Result; 12312 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 12313 return false; // Can't get the integer value as a constant. 12314 12315 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 12316 if (ConstLowerBound.getSExtValue()) 12317 return true; 12318 } 12319 12320 // If we don't have a length we covering the whole dimension. 12321 if (!Length) 12322 return false; 12323 12324 // If the base is a pointer, we don't have a way to get the size of the 12325 // pointee. 12326 if (BaseQTy->isPointerType()) 12327 return false; 12328 12329 // We can only check if the length is the same as the size of the dimension 12330 // if we have a constant array. 12331 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 12332 if (!CATy) 12333 return false; 12334 12335 Expr::EvalResult Result; 12336 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12337 return false; // Can't get the integer value as a constant. 12338 12339 llvm::APSInt ConstLength = Result.Val.getInt(); 12340 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 12341 } 12342 12343 // Return true if it can be proven that the provided array expression (array 12344 // section or array subscript) does NOT specify a single element of the array 12345 // whose base type is \a BaseQTy. 12346 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 12347 const Expr *E, 12348 QualType BaseQTy) { 12349 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12350 12351 // An array subscript always refer to a single element. Also, an array section 12352 // assumes the format of an array subscript if no colon is used. 12353 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 12354 return false; 12355 12356 assert(OASE && "Expecting array section if not an array subscript."); 12357 const Expr *Length = OASE->getLength(); 12358 12359 // If we don't have a length we have to check if the array has unitary size 12360 // for this dimension. Also, we should always expect a length if the base type 12361 // is pointer. 12362 if (!Length) { 12363 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12364 return ATy->getSize().getSExtValue() != 1; 12365 // We cannot assume anything. 12366 return false; 12367 } 12368 12369 // Check if the length evaluates to 1. 12370 Expr::EvalResult Result; 12371 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12372 return false; // Can't get the integer value as a constant. 12373 12374 llvm::APSInt ConstLength = Result.Val.getInt(); 12375 return ConstLength.getSExtValue() != 1; 12376 } 12377 12378 // Return the expression of the base of the mappable expression or null if it 12379 // cannot be determined and do all the necessary checks to see if the expression 12380 // is valid as a standalone mappable expression. In the process, record all the 12381 // components of the expression. 12382 static const Expr *checkMapClauseExpressionBase( 12383 Sema &SemaRef, Expr *E, 12384 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 12385 OpenMPClauseKind CKind, bool NoDiagnose) { 12386 SourceLocation ELoc = E->getExprLoc(); 12387 SourceRange ERange = E->getSourceRange(); 12388 12389 // The base of elements of list in a map clause have to be either: 12390 // - a reference to variable or field. 12391 // - a member expression. 12392 // - an array expression. 12393 // 12394 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 12395 // reference to 'r'. 12396 // 12397 // If we have: 12398 // 12399 // struct SS { 12400 // Bla S; 12401 // foo() { 12402 // #pragma omp target map (S.Arr[:12]); 12403 // } 12404 // } 12405 // 12406 // We want to retrieve the member expression 'this->S'; 12407 12408 const Expr *RelevantExpr = nullptr; 12409 12410 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 12411 // If a list item is an array section, it must specify contiguous storage. 12412 // 12413 // For this restriction it is sufficient that we make sure only references 12414 // to variables or fields and array expressions, and that no array sections 12415 // exist except in the rightmost expression (unless they cover the whole 12416 // dimension of the array). E.g. these would be invalid: 12417 // 12418 // r.ArrS[3:5].Arr[6:7] 12419 // 12420 // r.ArrS[3:5].x 12421 // 12422 // but these would be valid: 12423 // r.ArrS[3].Arr[6:7] 12424 // 12425 // r.ArrS[3].x 12426 12427 bool AllowUnitySizeArraySection = true; 12428 bool AllowWholeSizeArraySection = true; 12429 12430 while (!RelevantExpr) { 12431 E = E->IgnoreParenImpCasts(); 12432 12433 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 12434 if (!isa<VarDecl>(CurE->getDecl())) 12435 return nullptr; 12436 12437 RelevantExpr = CurE; 12438 12439 // If we got a reference to a declaration, we should not expect any array 12440 // section before that. 12441 AllowUnitySizeArraySection = false; 12442 AllowWholeSizeArraySection = false; 12443 12444 // Record the component. 12445 CurComponents.emplace_back(CurE, CurE->getDecl()); 12446 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 12447 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 12448 12449 if (isa<CXXThisExpr>(BaseE)) 12450 // We found a base expression: this->Val. 12451 RelevantExpr = CurE; 12452 else 12453 E = BaseE; 12454 12455 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 12456 if (!NoDiagnose) { 12457 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 12458 << CurE->getSourceRange(); 12459 return nullptr; 12460 } 12461 if (RelevantExpr) 12462 return nullptr; 12463 continue; 12464 } 12465 12466 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 12467 12468 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 12469 // A bit-field cannot appear in a map clause. 12470 // 12471 if (FD->isBitField()) { 12472 if (!NoDiagnose) { 12473 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 12474 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 12475 return nullptr; 12476 } 12477 if (RelevantExpr) 12478 return nullptr; 12479 continue; 12480 } 12481 12482 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12483 // If the type of a list item is a reference to a type T then the type 12484 // will be considered to be T for all purposes of this clause. 12485 QualType CurType = BaseE->getType().getNonReferenceType(); 12486 12487 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 12488 // A list item cannot be a variable that is a member of a structure with 12489 // a union type. 12490 // 12491 if (CurType->isUnionType()) { 12492 if (!NoDiagnose) { 12493 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 12494 << CurE->getSourceRange(); 12495 return nullptr; 12496 } 12497 continue; 12498 } 12499 12500 // If we got a member expression, we should not expect any array section 12501 // before that: 12502 // 12503 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 12504 // If a list item is an element of a structure, only the rightmost symbol 12505 // of the variable reference can be an array section. 12506 // 12507 AllowUnitySizeArraySection = false; 12508 AllowWholeSizeArraySection = false; 12509 12510 // Record the component. 12511 CurComponents.emplace_back(CurE, FD); 12512 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 12513 E = CurE->getBase()->IgnoreParenImpCasts(); 12514 12515 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 12516 if (!NoDiagnose) { 12517 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12518 << 0 << CurE->getSourceRange(); 12519 return nullptr; 12520 } 12521 continue; 12522 } 12523 12524 // If we got an array subscript that express the whole dimension we 12525 // can have any array expressions before. If it only expressing part of 12526 // the dimension, we can only have unitary-size array expressions. 12527 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 12528 E->getType())) 12529 AllowWholeSizeArraySection = false; 12530 12531 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 12532 Expr::EvalResult Result; 12533 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 12534 if (!Result.Val.getInt().isNullValue()) { 12535 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 12536 diag::err_omp_invalid_map_this_expr); 12537 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 12538 diag::note_omp_invalid_subscript_on_this_ptr_map); 12539 } 12540 } 12541 RelevantExpr = TE; 12542 } 12543 12544 // Record the component - we don't have any declaration associated. 12545 CurComponents.emplace_back(CurE, nullptr); 12546 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 12547 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 12548 E = CurE->getBase()->IgnoreParenImpCasts(); 12549 12550 QualType CurType = 12551 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12552 12553 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12554 // If the type of a list item is a reference to a type T then the type 12555 // will be considered to be T for all purposes of this clause. 12556 if (CurType->isReferenceType()) 12557 CurType = CurType->getPointeeType(); 12558 12559 bool IsPointer = CurType->isAnyPointerType(); 12560 12561 if (!IsPointer && !CurType->isArrayType()) { 12562 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12563 << 0 << CurE->getSourceRange(); 12564 return nullptr; 12565 } 12566 12567 bool NotWhole = 12568 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 12569 bool NotUnity = 12570 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 12571 12572 if (AllowWholeSizeArraySection) { 12573 // Any array section is currently allowed. Allowing a whole size array 12574 // section implies allowing a unity array section as well. 12575 // 12576 // If this array section refers to the whole dimension we can still 12577 // accept other array sections before this one, except if the base is a 12578 // pointer. Otherwise, only unitary sections are accepted. 12579 if (NotWhole || IsPointer) 12580 AllowWholeSizeArraySection = false; 12581 } else if (AllowUnitySizeArraySection && NotUnity) { 12582 // A unity or whole array section is not allowed and that is not 12583 // compatible with the properties of the current array section. 12584 SemaRef.Diag( 12585 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 12586 << CurE->getSourceRange(); 12587 return nullptr; 12588 } 12589 12590 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 12591 Expr::EvalResult ResultR; 12592 Expr::EvalResult ResultL; 12593 if (CurE->getLength()->EvaluateAsInt(ResultR, 12594 SemaRef.getASTContext())) { 12595 if (!ResultR.Val.getInt().isOneValue()) { 12596 SemaRef.Diag(CurE->getLength()->getExprLoc(), 12597 diag::err_omp_invalid_map_this_expr); 12598 SemaRef.Diag(CurE->getLength()->getExprLoc(), 12599 diag::note_omp_invalid_length_on_this_ptr_mapping); 12600 } 12601 } 12602 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 12603 ResultL, SemaRef.getASTContext())) { 12604 if (!ResultL.Val.getInt().isNullValue()) { 12605 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 12606 diag::err_omp_invalid_map_this_expr); 12607 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 12608 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 12609 } 12610 } 12611 RelevantExpr = TE; 12612 } 12613 12614 // Record the component - we don't have any declaration associated. 12615 CurComponents.emplace_back(CurE, nullptr); 12616 } else { 12617 if (!NoDiagnose) { 12618 // If nothing else worked, this is not a valid map clause expression. 12619 SemaRef.Diag( 12620 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 12621 << ERange; 12622 } 12623 return nullptr; 12624 } 12625 } 12626 12627 return RelevantExpr; 12628 } 12629 12630 // Return true if expression E associated with value VD has conflicts with other 12631 // map information. 12632 static bool checkMapConflicts( 12633 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 12634 bool CurrentRegionOnly, 12635 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 12636 OpenMPClauseKind CKind) { 12637 assert(VD && E); 12638 SourceLocation ELoc = E->getExprLoc(); 12639 SourceRange ERange = E->getSourceRange(); 12640 12641 // In order to easily check the conflicts we need to match each component of 12642 // the expression under test with the components of the expressions that are 12643 // already in the stack. 12644 12645 assert(!CurComponents.empty() && "Map clause expression with no components!"); 12646 assert(CurComponents.back().getAssociatedDeclaration() == VD && 12647 "Map clause expression with unexpected base!"); 12648 12649 // Variables to help detecting enclosing problems in data environment nests. 12650 bool IsEnclosedByDataEnvironmentExpr = false; 12651 const Expr *EnclosingExpr = nullptr; 12652 12653 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 12654 VD, CurrentRegionOnly, 12655 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 12656 ERange, CKind, &EnclosingExpr, 12657 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 12658 StackComponents, 12659 OpenMPClauseKind) { 12660 assert(!StackComponents.empty() && 12661 "Map clause expression with no components!"); 12662 assert(StackComponents.back().getAssociatedDeclaration() == VD && 12663 "Map clause expression with unexpected base!"); 12664 (void)VD; 12665 12666 // The whole expression in the stack. 12667 const Expr *RE = StackComponents.front().getAssociatedExpression(); 12668 12669 // Expressions must start from the same base. Here we detect at which 12670 // point both expressions diverge from each other and see if we can 12671 // detect if the memory referred to both expressions is contiguous and 12672 // do not overlap. 12673 auto CI = CurComponents.rbegin(); 12674 auto CE = CurComponents.rend(); 12675 auto SI = StackComponents.rbegin(); 12676 auto SE = StackComponents.rend(); 12677 for (; CI != CE && SI != SE; ++CI, ++SI) { 12678 12679 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 12680 // At most one list item can be an array item derived from a given 12681 // variable in map clauses of the same construct. 12682 if (CurrentRegionOnly && 12683 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 12684 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 12685 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 12686 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 12687 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 12688 diag::err_omp_multiple_array_items_in_map_clause) 12689 << CI->getAssociatedExpression()->getSourceRange(); 12690 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 12691 diag::note_used_here) 12692 << SI->getAssociatedExpression()->getSourceRange(); 12693 return true; 12694 } 12695 12696 // Do both expressions have the same kind? 12697 if (CI->getAssociatedExpression()->getStmtClass() != 12698 SI->getAssociatedExpression()->getStmtClass()) 12699 break; 12700 12701 // Are we dealing with different variables/fields? 12702 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 12703 break; 12704 } 12705 // Check if the extra components of the expressions in the enclosing 12706 // data environment are redundant for the current base declaration. 12707 // If they are, the maps completely overlap, which is legal. 12708 for (; SI != SE; ++SI) { 12709 QualType Type; 12710 if (const auto *ASE = 12711 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 12712 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 12713 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 12714 SI->getAssociatedExpression())) { 12715 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 12716 Type = 12717 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12718 } 12719 if (Type.isNull() || Type->isAnyPointerType() || 12720 checkArrayExpressionDoesNotReferToWholeSize( 12721 SemaRef, SI->getAssociatedExpression(), Type)) 12722 break; 12723 } 12724 12725 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 12726 // List items of map clauses in the same construct must not share 12727 // original storage. 12728 // 12729 // If the expressions are exactly the same or one is a subset of the 12730 // other, it means they are sharing storage. 12731 if (CI == CE && SI == SE) { 12732 if (CurrentRegionOnly) { 12733 if (CKind == OMPC_map) { 12734 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 12735 } else { 12736 assert(CKind == OMPC_to || CKind == OMPC_from); 12737 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 12738 << ERange; 12739 } 12740 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12741 << RE->getSourceRange(); 12742 return true; 12743 } 12744 // If we find the same expression in the enclosing data environment, 12745 // that is legal. 12746 IsEnclosedByDataEnvironmentExpr = true; 12747 return false; 12748 } 12749 12750 QualType DerivedType = 12751 std::prev(CI)->getAssociatedDeclaration()->getType(); 12752 SourceLocation DerivedLoc = 12753 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 12754 12755 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12756 // If the type of a list item is a reference to a type T then the type 12757 // will be considered to be T for all purposes of this clause. 12758 DerivedType = DerivedType.getNonReferenceType(); 12759 12760 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 12761 // A variable for which the type is pointer and an array section 12762 // derived from that variable must not appear as list items of map 12763 // clauses of the same construct. 12764 // 12765 // Also, cover one of the cases in: 12766 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 12767 // If any part of the original storage of a list item has corresponding 12768 // storage in the device data environment, all of the original storage 12769 // must have corresponding storage in the device data environment. 12770 // 12771 if (DerivedType->isAnyPointerType()) { 12772 if (CI == CE || SI == SE) { 12773 SemaRef.Diag( 12774 DerivedLoc, 12775 diag::err_omp_pointer_mapped_along_with_derived_section) 12776 << DerivedLoc; 12777 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12778 << RE->getSourceRange(); 12779 return true; 12780 } 12781 if (CI->getAssociatedExpression()->getStmtClass() != 12782 SI->getAssociatedExpression()->getStmtClass() || 12783 CI->getAssociatedDeclaration()->getCanonicalDecl() == 12784 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 12785 assert(CI != CE && SI != SE); 12786 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 12787 << DerivedLoc; 12788 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12789 << RE->getSourceRange(); 12790 return true; 12791 } 12792 } 12793 12794 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 12795 // List items of map clauses in the same construct must not share 12796 // original storage. 12797 // 12798 // An expression is a subset of the other. 12799 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 12800 if (CKind == OMPC_map) { 12801 if (CI != CE || SI != SE) { 12802 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 12803 // a pointer. 12804 auto Begin = 12805 CI != CE ? CurComponents.begin() : StackComponents.begin(); 12806 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 12807 auto It = Begin; 12808 while (It != End && !It->getAssociatedDeclaration()) 12809 std::advance(It, 1); 12810 assert(It != End && 12811 "Expected at least one component with the declaration."); 12812 if (It != Begin && It->getAssociatedDeclaration() 12813 ->getType() 12814 .getCanonicalType() 12815 ->isAnyPointerType()) { 12816 IsEnclosedByDataEnvironmentExpr = false; 12817 EnclosingExpr = nullptr; 12818 return false; 12819 } 12820 } 12821 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 12822 } else { 12823 assert(CKind == OMPC_to || CKind == OMPC_from); 12824 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 12825 << ERange; 12826 } 12827 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 12828 << RE->getSourceRange(); 12829 return true; 12830 } 12831 12832 // The current expression uses the same base as other expression in the 12833 // data environment but does not contain it completely. 12834 if (!CurrentRegionOnly && SI != SE) 12835 EnclosingExpr = RE; 12836 12837 // The current expression is a subset of the expression in the data 12838 // environment. 12839 IsEnclosedByDataEnvironmentExpr |= 12840 (!CurrentRegionOnly && CI != CE && SI == SE); 12841 12842 return false; 12843 }); 12844 12845 if (CurrentRegionOnly) 12846 return FoundError; 12847 12848 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 12849 // If any part of the original storage of a list item has corresponding 12850 // storage in the device data environment, all of the original storage must 12851 // have corresponding storage in the device data environment. 12852 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 12853 // If a list item is an element of a structure, and a different element of 12854 // the structure has a corresponding list item in the device data environment 12855 // prior to a task encountering the construct associated with the map clause, 12856 // then the list item must also have a corresponding list item in the device 12857 // data environment prior to the task encountering the construct. 12858 // 12859 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 12860 SemaRef.Diag(ELoc, 12861 diag::err_omp_original_storage_is_shared_and_does_not_contain) 12862 << ERange; 12863 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 12864 << EnclosingExpr->getSourceRange(); 12865 return true; 12866 } 12867 12868 return FoundError; 12869 } 12870 12871 namespace { 12872 // Utility struct that gathers all the related lists associated with a mappable 12873 // expression. 12874 struct MappableVarListInfo { 12875 // The list of expressions. 12876 ArrayRef<Expr *> VarList; 12877 // The list of processed expressions. 12878 SmallVector<Expr *, 16> ProcessedVarList; 12879 // The mappble components for each expression. 12880 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 12881 // The base declaration of the variable. 12882 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 12883 12884 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 12885 // We have a list of components and base declarations for each entry in the 12886 // variable list. 12887 VarComponents.reserve(VarList.size()); 12888 VarBaseDeclarations.reserve(VarList.size()); 12889 } 12890 }; 12891 } 12892 12893 // Check the validity of the provided variable list for the provided clause kind 12894 // \a CKind. In the check process the valid expressions, and mappable expression 12895 // components and variables are extracted and used to fill \a Vars, 12896 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 12897 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 12898 static void 12899 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 12900 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 12901 SourceLocation StartLoc, 12902 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 12903 bool IsMapTypeImplicit = false) { 12904 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 12905 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 12906 "Unexpected clause kind with mappable expressions!"); 12907 12908 // Keep track of the mappable components and base declarations in this clause. 12909 // Each entry in the list is going to have a list of components associated. We 12910 // record each set of the components so that we can build the clause later on. 12911 // In the end we should have the same amount of declarations and component 12912 // lists. 12913 12914 for (Expr *RE : MVLI.VarList) { 12915 assert(RE && "Null expr in omp to/from/map clause"); 12916 SourceLocation ELoc = RE->getExprLoc(); 12917 12918 const Expr *VE = RE->IgnoreParenLValueCasts(); 12919 12920 if (VE->isValueDependent() || VE->isTypeDependent() || 12921 VE->isInstantiationDependent() || 12922 VE->containsUnexpandedParameterPack()) { 12923 // We can only analyze this information once the missing information is 12924 // resolved. 12925 MVLI.ProcessedVarList.push_back(RE); 12926 continue; 12927 } 12928 12929 Expr *SimpleExpr = RE->IgnoreParenCasts(); 12930 12931 if (!RE->IgnoreParenImpCasts()->isLValue()) { 12932 SemaRef.Diag(ELoc, 12933 diag::err_omp_expected_named_var_member_or_array_expression) 12934 << RE->getSourceRange(); 12935 continue; 12936 } 12937 12938 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 12939 ValueDecl *CurDeclaration = nullptr; 12940 12941 // Obtain the array or member expression bases if required. Also, fill the 12942 // components array with all the components identified in the process. 12943 const Expr *BE = checkMapClauseExpressionBase( 12944 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 12945 if (!BE) 12946 continue; 12947 12948 assert(!CurComponents.empty() && 12949 "Invalid mappable expression information."); 12950 12951 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 12952 // Add store "this" pointer to class in DSAStackTy for future checking 12953 DSAS->addMappedClassesQualTypes(TE->getType()); 12954 // Skip restriction checking for variable or field declarations 12955 MVLI.ProcessedVarList.push_back(RE); 12956 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12957 MVLI.VarComponents.back().append(CurComponents.begin(), 12958 CurComponents.end()); 12959 MVLI.VarBaseDeclarations.push_back(nullptr); 12960 continue; 12961 } 12962 12963 // For the following checks, we rely on the base declaration which is 12964 // expected to be associated with the last component. The declaration is 12965 // expected to be a variable or a field (if 'this' is being mapped). 12966 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 12967 assert(CurDeclaration && "Null decl on map clause."); 12968 assert( 12969 CurDeclaration->isCanonicalDecl() && 12970 "Expecting components to have associated only canonical declarations."); 12971 12972 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 12973 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 12974 12975 assert((VD || FD) && "Only variables or fields are expected here!"); 12976 (void)FD; 12977 12978 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 12979 // threadprivate variables cannot appear in a map clause. 12980 // OpenMP 4.5 [2.10.5, target update Construct] 12981 // threadprivate variables cannot appear in a from clause. 12982 if (VD && DSAS->isThreadPrivate(VD)) { 12983 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 12984 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 12985 << getOpenMPClauseName(CKind); 12986 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 12987 continue; 12988 } 12989 12990 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12991 // A list item cannot appear in both a map clause and a data-sharing 12992 // attribute clause on the same construct. 12993 12994 // Check conflicts with other map clause expressions. We check the conflicts 12995 // with the current construct separately from the enclosing data 12996 // environment, because the restrictions are different. We only have to 12997 // check conflicts across regions for the map clauses. 12998 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12999 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 13000 break; 13001 if (CKind == OMPC_map && 13002 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13003 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 13004 break; 13005 13006 // OpenMP 4.5 [2.10.5, target update Construct] 13007 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13008 // If the type of a list item is a reference to a type T then the type will 13009 // be considered to be T for all purposes of this clause. 13010 auto I = llvm::find_if( 13011 CurComponents, 13012 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 13013 return MC.getAssociatedDeclaration(); 13014 }); 13015 assert(I != CurComponents.end() && "Null decl on map clause."); 13016 QualType Type = 13017 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 13018 13019 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 13020 // A list item in a to or from clause must have a mappable type. 13021 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13022 // A list item must have a mappable type. 13023 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 13024 DSAS, Type)) 13025 continue; 13026 13027 if (CKind == OMPC_map) { 13028 // target enter data 13029 // OpenMP [2.10.2, Restrictions, p. 99] 13030 // A map-type must be specified in all map clauses and must be either 13031 // to or alloc. 13032 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 13033 if (DKind == OMPD_target_enter_data && 13034 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 13035 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13036 << (IsMapTypeImplicit ? 1 : 0) 13037 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13038 << getOpenMPDirectiveName(DKind); 13039 continue; 13040 } 13041 13042 // target exit_data 13043 // OpenMP [2.10.3, Restrictions, p. 102] 13044 // A map-type must be specified in all map clauses and must be either 13045 // from, release, or delete. 13046 if (DKind == OMPD_target_exit_data && 13047 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 13048 MapType == OMPC_MAP_delete)) { 13049 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13050 << (IsMapTypeImplicit ? 1 : 0) 13051 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13052 << getOpenMPDirectiveName(DKind); 13053 continue; 13054 } 13055 13056 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13057 // A list item cannot appear in both a map clause and a data-sharing 13058 // attribute clause on the same construct 13059 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 13060 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13061 if (isOpenMPPrivate(DVar.CKind)) { 13062 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13063 << getOpenMPClauseName(DVar.CKind) 13064 << getOpenMPClauseName(OMPC_map) 13065 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 13066 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 13067 continue; 13068 } 13069 } 13070 } 13071 13072 // Save the current expression. 13073 MVLI.ProcessedVarList.push_back(RE); 13074 13075 // Store the components in the stack so that they can be used to check 13076 // against other clauses later on. 13077 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 13078 /*WhereFoundClauseKind=*/OMPC_map); 13079 13080 // Save the components and declaration to create the clause. For purposes of 13081 // the clause creation, any component list that has has base 'this' uses 13082 // null as base declaration. 13083 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13084 MVLI.VarComponents.back().append(CurComponents.begin(), 13085 CurComponents.end()); 13086 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 13087 : CurDeclaration); 13088 } 13089 } 13090 13091 OMPClause * 13092 Sema::ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13093 ArrayRef<SourceLocation> MapTypeModifiersLoc, 13094 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 13095 SourceLocation MapLoc, SourceLocation ColonLoc, 13096 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13097 SourceLocation LParenLoc, SourceLocation EndLoc) { 13098 MappableVarListInfo MVLI(VarList); 13099 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 13100 MapType, IsMapTypeImplicit); 13101 13102 OpenMPMapModifierKind Modifiers[] = { OMPC_MAP_MODIFIER_unknown, 13103 OMPC_MAP_MODIFIER_unknown }; 13104 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 13105 13106 // Process map-type-modifiers, flag errors for duplicate modifiers. 13107 unsigned Count = 0; 13108 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 13109 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 13110 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 13111 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 13112 continue; 13113 } 13114 assert(Count < OMPMapClause::NumberOfModifiers && 13115 "Modifiers exceed the allowed number of map type modifiers"); 13116 Modifiers[Count] = MapTypeModifiers[I]; 13117 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 13118 ++Count; 13119 } 13120 13121 // We need to produce a map clause even if we don't have variables so that 13122 // other diagnostics related with non-existing map clauses are accurate. 13123 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13124 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13125 MVLI.VarComponents, Modifiers, ModifiersLoc, 13126 MapType, IsMapTypeImplicit, MapLoc); 13127 } 13128 13129 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 13130 TypeResult ParsedType) { 13131 assert(ParsedType.isUsable()); 13132 13133 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 13134 if (ReductionType.isNull()) 13135 return QualType(); 13136 13137 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 13138 // A type name in a declare reduction directive cannot be a function type, an 13139 // array type, a reference type, or a type qualified with const, volatile or 13140 // restrict. 13141 if (ReductionType.hasQualifiers()) { 13142 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 13143 return QualType(); 13144 } 13145 13146 if (ReductionType->isFunctionType()) { 13147 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 13148 return QualType(); 13149 } 13150 if (ReductionType->isReferenceType()) { 13151 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 13152 return QualType(); 13153 } 13154 if (ReductionType->isArrayType()) { 13155 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 13156 return QualType(); 13157 } 13158 return ReductionType; 13159 } 13160 13161 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 13162 Scope *S, DeclContext *DC, DeclarationName Name, 13163 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 13164 AccessSpecifier AS, Decl *PrevDeclInScope) { 13165 SmallVector<Decl *, 8> Decls; 13166 Decls.reserve(ReductionTypes.size()); 13167 13168 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 13169 forRedeclarationInCurContext()); 13170 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 13171 // A reduction-identifier may not be re-declared in the current scope for the 13172 // same type or for a type that is compatible according to the base language 13173 // rules. 13174 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 13175 OMPDeclareReductionDecl *PrevDRD = nullptr; 13176 bool InCompoundScope = true; 13177 if (S != nullptr) { 13178 // Find previous declaration with the same name not referenced in other 13179 // declarations. 13180 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 13181 InCompoundScope = 13182 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 13183 LookupName(Lookup, S); 13184 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 13185 /*AllowInlineNamespace=*/false); 13186 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 13187 LookupResult::Filter Filter = Lookup.makeFilter(); 13188 while (Filter.hasNext()) { 13189 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 13190 if (InCompoundScope) { 13191 auto I = UsedAsPrevious.find(PrevDecl); 13192 if (I == UsedAsPrevious.end()) 13193 UsedAsPrevious[PrevDecl] = false; 13194 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 13195 UsedAsPrevious[D] = true; 13196 } 13197 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 13198 PrevDecl->getLocation(); 13199 } 13200 Filter.done(); 13201 if (InCompoundScope) { 13202 for (const auto &PrevData : UsedAsPrevious) { 13203 if (!PrevData.second) { 13204 PrevDRD = PrevData.first; 13205 break; 13206 } 13207 } 13208 } 13209 } else if (PrevDeclInScope != nullptr) { 13210 auto *PrevDRDInScope = PrevDRD = 13211 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 13212 do { 13213 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 13214 PrevDRDInScope->getLocation(); 13215 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 13216 } while (PrevDRDInScope != nullptr); 13217 } 13218 for (const auto &TyData : ReductionTypes) { 13219 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 13220 bool Invalid = false; 13221 if (I != PreviousRedeclTypes.end()) { 13222 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 13223 << TyData.first; 13224 Diag(I->second, diag::note_previous_definition); 13225 Invalid = true; 13226 } 13227 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 13228 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 13229 Name, TyData.first, PrevDRD); 13230 DC->addDecl(DRD); 13231 DRD->setAccess(AS); 13232 Decls.push_back(DRD); 13233 if (Invalid) 13234 DRD->setInvalidDecl(); 13235 else 13236 PrevDRD = DRD; 13237 } 13238 13239 return DeclGroupPtrTy::make( 13240 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 13241 } 13242 13243 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 13244 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13245 13246 // Enter new function scope. 13247 PushFunctionScope(); 13248 setFunctionHasBranchProtectedScope(); 13249 getCurFunction()->setHasOMPDeclareReductionCombiner(); 13250 13251 if (S != nullptr) 13252 PushDeclContext(S, DRD); 13253 else 13254 CurContext = DRD; 13255 13256 PushExpressionEvaluationContext( 13257 ExpressionEvaluationContext::PotentiallyEvaluated); 13258 13259 QualType ReductionType = DRD->getType(); 13260 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 13261 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 13262 // uses semantics of argument handles by value, but it should be passed by 13263 // reference. C lang does not support references, so pass all parameters as 13264 // pointers. 13265 // Create 'T omp_in;' variable. 13266 VarDecl *OmpInParm = 13267 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 13268 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 13269 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 13270 // uses semantics of argument handles by value, but it should be passed by 13271 // reference. C lang does not support references, so pass all parameters as 13272 // pointers. 13273 // Create 'T omp_out;' variable. 13274 VarDecl *OmpOutParm = 13275 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 13276 if (S != nullptr) { 13277 PushOnScopeChains(OmpInParm, S); 13278 PushOnScopeChains(OmpOutParm, S); 13279 } else { 13280 DRD->addDecl(OmpInParm); 13281 DRD->addDecl(OmpOutParm); 13282 } 13283 Expr *InE = 13284 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 13285 Expr *OutE = 13286 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 13287 DRD->setCombinerData(InE, OutE); 13288 } 13289 13290 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 13291 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13292 DiscardCleanupsInEvaluationContext(); 13293 PopExpressionEvaluationContext(); 13294 13295 PopDeclContext(); 13296 PopFunctionScopeInfo(); 13297 13298 if (Combiner != nullptr) 13299 DRD->setCombiner(Combiner); 13300 else 13301 DRD->setInvalidDecl(); 13302 } 13303 13304 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 13305 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13306 13307 // Enter new function scope. 13308 PushFunctionScope(); 13309 setFunctionHasBranchProtectedScope(); 13310 13311 if (S != nullptr) 13312 PushDeclContext(S, DRD); 13313 else 13314 CurContext = DRD; 13315 13316 PushExpressionEvaluationContext( 13317 ExpressionEvaluationContext::PotentiallyEvaluated); 13318 13319 QualType ReductionType = DRD->getType(); 13320 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 13321 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 13322 // uses semantics of argument handles by value, but it should be passed by 13323 // reference. C lang does not support references, so pass all parameters as 13324 // pointers. 13325 // Create 'T omp_priv;' variable. 13326 VarDecl *OmpPrivParm = 13327 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 13328 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 13329 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 13330 // uses semantics of argument handles by value, but it should be passed by 13331 // reference. C lang does not support references, so pass all parameters as 13332 // pointers. 13333 // Create 'T omp_orig;' variable. 13334 VarDecl *OmpOrigParm = 13335 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 13336 if (S != nullptr) { 13337 PushOnScopeChains(OmpPrivParm, S); 13338 PushOnScopeChains(OmpOrigParm, S); 13339 } else { 13340 DRD->addDecl(OmpPrivParm); 13341 DRD->addDecl(OmpOrigParm); 13342 } 13343 Expr *OrigE = 13344 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 13345 Expr *PrivE = 13346 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 13347 DRD->setInitializerData(OrigE, PrivE); 13348 return OmpPrivParm; 13349 } 13350 13351 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 13352 VarDecl *OmpPrivParm) { 13353 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13354 DiscardCleanupsInEvaluationContext(); 13355 PopExpressionEvaluationContext(); 13356 13357 PopDeclContext(); 13358 PopFunctionScopeInfo(); 13359 13360 if (Initializer != nullptr) { 13361 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 13362 } else if (OmpPrivParm->hasInit()) { 13363 DRD->setInitializer(OmpPrivParm->getInit(), 13364 OmpPrivParm->isDirectInit() 13365 ? OMPDeclareReductionDecl::DirectInit 13366 : OMPDeclareReductionDecl::CopyInit); 13367 } else { 13368 DRD->setInvalidDecl(); 13369 } 13370 } 13371 13372 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 13373 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 13374 for (Decl *D : DeclReductions.get()) { 13375 if (IsValid) { 13376 if (S) 13377 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 13378 /*AddToContext=*/false); 13379 } else { 13380 D->setInvalidDecl(); 13381 } 13382 } 13383 return DeclReductions; 13384 } 13385 13386 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 13387 SourceLocation StartLoc, 13388 SourceLocation LParenLoc, 13389 SourceLocation EndLoc) { 13390 Expr *ValExpr = NumTeams; 13391 Stmt *HelperValStmt = nullptr; 13392 13393 // OpenMP [teams Constrcut, Restrictions] 13394 // The num_teams expression must evaluate to a positive integer value. 13395 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 13396 /*StrictlyPositive=*/true)) 13397 return nullptr; 13398 13399 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13400 OpenMPDirectiveKind CaptureRegion = 13401 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 13402 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13403 ValExpr = MakeFullExpr(ValExpr).get(); 13404 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13405 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13406 HelperValStmt = buildPreInits(Context, Captures); 13407 } 13408 13409 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 13410 StartLoc, LParenLoc, EndLoc); 13411 } 13412 13413 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 13414 SourceLocation StartLoc, 13415 SourceLocation LParenLoc, 13416 SourceLocation EndLoc) { 13417 Expr *ValExpr = ThreadLimit; 13418 Stmt *HelperValStmt = nullptr; 13419 13420 // OpenMP [teams Constrcut, Restrictions] 13421 // The thread_limit expression must evaluate to a positive integer value. 13422 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 13423 /*StrictlyPositive=*/true)) 13424 return nullptr; 13425 13426 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13427 OpenMPDirectiveKind CaptureRegion = 13428 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 13429 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13430 ValExpr = MakeFullExpr(ValExpr).get(); 13431 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13432 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13433 HelperValStmt = buildPreInits(Context, Captures); 13434 } 13435 13436 return new (Context) OMPThreadLimitClause( 13437 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 13438 } 13439 13440 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 13441 SourceLocation StartLoc, 13442 SourceLocation LParenLoc, 13443 SourceLocation EndLoc) { 13444 Expr *ValExpr = Priority; 13445 13446 // OpenMP [2.9.1, task Constrcut] 13447 // The priority-value is a non-negative numerical scalar expression. 13448 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 13449 /*StrictlyPositive=*/false)) 13450 return nullptr; 13451 13452 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 13453 } 13454 13455 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 13456 SourceLocation StartLoc, 13457 SourceLocation LParenLoc, 13458 SourceLocation EndLoc) { 13459 Expr *ValExpr = Grainsize; 13460 13461 // OpenMP [2.9.2, taskloop Constrcut] 13462 // The parameter of the grainsize clause must be a positive integer 13463 // expression. 13464 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 13465 /*StrictlyPositive=*/true)) 13466 return nullptr; 13467 13468 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 13469 } 13470 13471 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 13472 SourceLocation StartLoc, 13473 SourceLocation LParenLoc, 13474 SourceLocation EndLoc) { 13475 Expr *ValExpr = NumTasks; 13476 13477 // OpenMP [2.9.2, taskloop Constrcut] 13478 // The parameter of the num_tasks clause must be a positive integer 13479 // expression. 13480 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 13481 /*StrictlyPositive=*/true)) 13482 return nullptr; 13483 13484 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 13485 } 13486 13487 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 13488 SourceLocation LParenLoc, 13489 SourceLocation EndLoc) { 13490 // OpenMP [2.13.2, critical construct, Description] 13491 // ... where hint-expression is an integer constant expression that evaluates 13492 // to a valid lock hint. 13493 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 13494 if (HintExpr.isInvalid()) 13495 return nullptr; 13496 return new (Context) 13497 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 13498 } 13499 13500 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 13501 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 13502 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 13503 SourceLocation EndLoc) { 13504 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 13505 std::string Values; 13506 Values += "'"; 13507 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 13508 Values += "'"; 13509 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 13510 << Values << getOpenMPClauseName(OMPC_dist_schedule); 13511 return nullptr; 13512 } 13513 Expr *ValExpr = ChunkSize; 13514 Stmt *HelperValStmt = nullptr; 13515 if (ChunkSize) { 13516 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13517 !ChunkSize->isInstantiationDependent() && 13518 !ChunkSize->containsUnexpandedParameterPack()) { 13519 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13520 ExprResult Val = 13521 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13522 if (Val.isInvalid()) 13523 return nullptr; 13524 13525 ValExpr = Val.get(); 13526 13527 // OpenMP [2.7.1, Restrictions] 13528 // chunk_size must be a loop invariant integer expression with a positive 13529 // value. 13530 llvm::APSInt Result; 13531 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 13532 if (Result.isSigned() && !Result.isStrictlyPositive()) { 13533 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13534 << "dist_schedule" << ChunkSize->getSourceRange(); 13535 return nullptr; 13536 } 13537 } else if (getOpenMPCaptureRegionForClause( 13538 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 13539 OMPD_unknown && 13540 !CurContext->isDependentContext()) { 13541 ValExpr = MakeFullExpr(ValExpr).get(); 13542 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13543 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13544 HelperValStmt = buildPreInits(Context, Captures); 13545 } 13546 } 13547 } 13548 13549 return new (Context) 13550 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 13551 Kind, ValExpr, HelperValStmt); 13552 } 13553 13554 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 13555 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 13556 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 13557 SourceLocation KindLoc, SourceLocation EndLoc) { 13558 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 13559 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 13560 std::string Value; 13561 SourceLocation Loc; 13562 Value += "'"; 13563 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 13564 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 13565 OMPC_DEFAULTMAP_MODIFIER_tofrom); 13566 Loc = MLoc; 13567 } else { 13568 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 13569 OMPC_DEFAULTMAP_scalar); 13570 Loc = KindLoc; 13571 } 13572 Value += "'"; 13573 Diag(Loc, diag::err_omp_unexpected_clause_value) 13574 << Value << getOpenMPClauseName(OMPC_defaultmap); 13575 return nullptr; 13576 } 13577 DSAStack->setDefaultDMAToFromScalar(StartLoc); 13578 13579 return new (Context) 13580 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 13581 } 13582 13583 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 13584 DeclContext *CurLexicalContext = getCurLexicalContext(); 13585 if (!CurLexicalContext->isFileContext() && 13586 !CurLexicalContext->isExternCContext() && 13587 !CurLexicalContext->isExternCXXContext() && 13588 !isa<CXXRecordDecl>(CurLexicalContext) && 13589 !isa<ClassTemplateDecl>(CurLexicalContext) && 13590 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 13591 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 13592 Diag(Loc, diag::err_omp_region_not_file_context); 13593 return false; 13594 } 13595 ++DeclareTargetNestingLevel; 13596 return true; 13597 } 13598 13599 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 13600 assert(DeclareTargetNestingLevel > 0 && 13601 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 13602 --DeclareTargetNestingLevel; 13603 } 13604 13605 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 13606 CXXScopeSpec &ScopeSpec, 13607 const DeclarationNameInfo &Id, 13608 OMPDeclareTargetDeclAttr::MapTypeTy MT, 13609 NamedDeclSetType &SameDirectiveDecls) { 13610 LookupResult Lookup(*this, Id, LookupOrdinaryName); 13611 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 13612 13613 if (Lookup.isAmbiguous()) 13614 return; 13615 Lookup.suppressDiagnostics(); 13616 13617 if (!Lookup.isSingleResult()) { 13618 if (TypoCorrection Corrected = 13619 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 13620 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 13621 CTK_ErrorRecovery)) { 13622 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 13623 << Id.getName()); 13624 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 13625 return; 13626 } 13627 13628 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 13629 return; 13630 } 13631 13632 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 13633 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 13634 isa<FunctionTemplateDecl>(ND)) { 13635 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 13636 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 13637 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 13638 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 13639 cast<ValueDecl>(ND)); 13640 if (!Res) { 13641 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 13642 ND->addAttr(A); 13643 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13644 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 13645 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 13646 } else if (*Res != MT) { 13647 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 13648 << Id.getName(); 13649 } 13650 } else { 13651 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 13652 } 13653 } 13654 13655 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 13656 Sema &SemaRef, Decl *D) { 13657 if (!D || !isa<VarDecl>(D)) 13658 return; 13659 auto *VD = cast<VarDecl>(D); 13660 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 13661 return; 13662 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 13663 SemaRef.Diag(SL, diag::note_used_here) << SR; 13664 } 13665 13666 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 13667 Sema &SemaRef, DSAStackTy *Stack, 13668 ValueDecl *VD) { 13669 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 13670 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 13671 /*FullCheck=*/false); 13672 } 13673 13674 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 13675 SourceLocation IdLoc) { 13676 if (!D || D->isInvalidDecl()) 13677 return; 13678 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 13679 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 13680 if (auto *VD = dyn_cast<VarDecl>(D)) { 13681 // Only global variables can be marked as declare target. 13682 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 13683 !VD->isStaticDataMember()) 13684 return; 13685 // 2.10.6: threadprivate variable cannot appear in a declare target 13686 // directive. 13687 if (DSAStack->isThreadPrivate(VD)) { 13688 Diag(SL, diag::err_omp_threadprivate_in_target); 13689 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 13690 return; 13691 } 13692 } 13693 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 13694 D = FTD->getTemplatedDecl(); 13695 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 13696 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 13697 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 13698 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 13699 assert(IdLoc.isValid() && "Source location is expected"); 13700 Diag(IdLoc, diag::err_omp_function_in_link_clause); 13701 Diag(FD->getLocation(), diag::note_defined_here) << FD; 13702 return; 13703 } 13704 } 13705 if (auto *VD = dyn_cast<ValueDecl>(D)) { 13706 // Problem if any with var declared with incomplete type will be reported 13707 // as normal, so no need to check it here. 13708 if ((E || !VD->getType()->isIncompleteType()) && 13709 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 13710 return; 13711 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 13712 // Checking declaration inside declare target region. 13713 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 13714 isa<FunctionTemplateDecl>(D)) { 13715 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 13716 Context, OMPDeclareTargetDeclAttr::MT_To); 13717 D->addAttr(A); 13718 if (ASTMutationListener *ML = Context.getASTMutationListener()) 13719 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 13720 } 13721 return; 13722 } 13723 } 13724 if (!E) 13725 return; 13726 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 13727 } 13728 13729 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 13730 SourceLocation StartLoc, 13731 SourceLocation LParenLoc, 13732 SourceLocation EndLoc) { 13733 MappableVarListInfo MVLI(VarList); 13734 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 13735 if (MVLI.ProcessedVarList.empty()) 13736 return nullptr; 13737 13738 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13739 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13740 MVLI.VarComponents); 13741 } 13742 13743 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 13744 SourceLocation StartLoc, 13745 SourceLocation LParenLoc, 13746 SourceLocation EndLoc) { 13747 MappableVarListInfo MVLI(VarList); 13748 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 13749 if (MVLI.ProcessedVarList.empty()) 13750 return nullptr; 13751 13752 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13753 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 13754 MVLI.VarComponents); 13755 } 13756 13757 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 13758 SourceLocation StartLoc, 13759 SourceLocation LParenLoc, 13760 SourceLocation EndLoc) { 13761 MappableVarListInfo MVLI(VarList); 13762 SmallVector<Expr *, 8> PrivateCopies; 13763 SmallVector<Expr *, 8> Inits; 13764 13765 for (Expr *RefExpr : VarList) { 13766 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 13767 SourceLocation ELoc; 13768 SourceRange ERange; 13769 Expr *SimpleRefExpr = RefExpr; 13770 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13771 if (Res.second) { 13772 // It will be analyzed later. 13773 MVLI.ProcessedVarList.push_back(RefExpr); 13774 PrivateCopies.push_back(nullptr); 13775 Inits.push_back(nullptr); 13776 } 13777 ValueDecl *D = Res.first; 13778 if (!D) 13779 continue; 13780 13781 QualType Type = D->getType(); 13782 Type = Type.getNonReferenceType().getUnqualifiedType(); 13783 13784 auto *VD = dyn_cast<VarDecl>(D); 13785 13786 // Item should be a pointer or reference to pointer. 13787 if (!Type->isPointerType()) { 13788 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 13789 << 0 << RefExpr->getSourceRange(); 13790 continue; 13791 } 13792 13793 // Build the private variable and the expression that refers to it. 13794 auto VDPrivate = 13795 buildVarDecl(*this, ELoc, Type, D->getName(), 13796 D->hasAttrs() ? &D->getAttrs() : nullptr, 13797 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13798 if (VDPrivate->isInvalidDecl()) 13799 continue; 13800 13801 CurContext->addDecl(VDPrivate); 13802 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13803 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13804 13805 // Add temporary variable to initialize the private copy of the pointer. 13806 VarDecl *VDInit = 13807 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 13808 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 13809 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 13810 AddInitializerToDecl(VDPrivate, 13811 DefaultLvalueConversion(VDInitRefExpr).get(), 13812 /*DirectInit=*/false); 13813 13814 // If required, build a capture to implement the privatization initialized 13815 // with the current list item value. 13816 DeclRefExpr *Ref = nullptr; 13817 if (!VD) 13818 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13819 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 13820 PrivateCopies.push_back(VDPrivateRefExpr); 13821 Inits.push_back(VDInitRefExpr); 13822 13823 // We need to add a data sharing attribute for this variable to make sure it 13824 // is correctly captured. A variable that shows up in a use_device_ptr has 13825 // similar properties of a first private variable. 13826 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13827 13828 // Create a mappable component for the list item. List items in this clause 13829 // only need a component. 13830 MVLI.VarBaseDeclarations.push_back(D); 13831 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13832 MVLI.VarComponents.back().push_back( 13833 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 13834 } 13835 13836 if (MVLI.ProcessedVarList.empty()) 13837 return nullptr; 13838 13839 return OMPUseDevicePtrClause::Create( 13840 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 13841 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 13842 } 13843 13844 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 13845 SourceLocation StartLoc, 13846 SourceLocation LParenLoc, 13847 SourceLocation EndLoc) { 13848 MappableVarListInfo MVLI(VarList); 13849 for (Expr *RefExpr : VarList) { 13850 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 13851 SourceLocation ELoc; 13852 SourceRange ERange; 13853 Expr *SimpleRefExpr = RefExpr; 13854 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13855 if (Res.second) { 13856 // It will be analyzed later. 13857 MVLI.ProcessedVarList.push_back(RefExpr); 13858 } 13859 ValueDecl *D = Res.first; 13860 if (!D) 13861 continue; 13862 13863 QualType Type = D->getType(); 13864 // item should be a pointer or array or reference to pointer or array 13865 if (!Type.getNonReferenceType()->isPointerType() && 13866 !Type.getNonReferenceType()->isArrayType()) { 13867 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 13868 << 0 << RefExpr->getSourceRange(); 13869 continue; 13870 } 13871 13872 // Check if the declaration in the clause does not show up in any data 13873 // sharing attribute. 13874 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13875 if (isOpenMPPrivate(DVar.CKind)) { 13876 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13877 << getOpenMPClauseName(DVar.CKind) 13878 << getOpenMPClauseName(OMPC_is_device_ptr) 13879 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13880 reportOriginalDsa(*this, DSAStack, D, DVar); 13881 continue; 13882 } 13883 13884 const Expr *ConflictExpr; 13885 if (DSAStack->checkMappableExprComponentListsForDecl( 13886 D, /*CurrentRegionOnly=*/true, 13887 [&ConflictExpr]( 13888 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 13889 OpenMPClauseKind) -> bool { 13890 ConflictExpr = R.front().getAssociatedExpression(); 13891 return true; 13892 })) { 13893 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 13894 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 13895 << ConflictExpr->getSourceRange(); 13896 continue; 13897 } 13898 13899 // Store the components in the stack so that they can be used to check 13900 // against other clauses later on. 13901 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 13902 DSAStack->addMappableExpressionComponents( 13903 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 13904 13905 // Record the expression we've just processed. 13906 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 13907 13908 // Create a mappable component for the list item. List items in this clause 13909 // only need a component. We use a null declaration to signal fields in 13910 // 'this'. 13911 assert((isa<DeclRefExpr>(SimpleRefExpr) || 13912 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 13913 "Unexpected device pointer expression!"); 13914 MVLI.VarBaseDeclarations.push_back( 13915 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 13916 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13917 MVLI.VarComponents.back().push_back(MC); 13918 } 13919 13920 if (MVLI.ProcessedVarList.empty()) 13921 return nullptr; 13922 13923 return OMPIsDevicePtrClause::Create( 13924 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 13925 MVLI.VarBaseDeclarations, MVLI.VarComponents); 13926 } 13927