1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 const Decl *PossiblyLoopCounter = nullptr; 143 bool NowaitRegion = false; 144 bool CancelRegion = false; 145 bool LoopStart = false; 146 SourceLocation InnerTeamsRegionLoc; 147 /// Reference to the taskgroup task_reduction reference expression. 148 Expr *TaskgroupReductionRef = nullptr; 149 llvm::DenseSet<QualType> MappedClassesQualTypes; 150 /// List of globals marked as declare target link in this target region 151 /// (isOpenMPTargetExecutionDirective(Directive) == true). 152 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 153 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 154 Scope *CurScope, SourceLocation Loc) 155 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 156 ConstructLoc(Loc) {} 157 SharingMapTy() = default; 158 }; 159 160 using StackTy = SmallVector<SharingMapTy, 4>; 161 162 /// Stack of used declaration and their data-sharing attributes. 163 DeclSAMapTy Threadprivates; 164 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 165 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 166 /// true, if check for DSA must be from parent directive, false, if 167 /// from current directive. 168 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 169 Sema &SemaRef; 170 bool ForceCapturing = false; 171 /// true if all the vaiables in the target executable directives must be 172 /// captured by reference. 173 bool ForceCaptureByReferenceInTargetExecutable = false; 174 CriticalsWithHintsTy Criticals; 175 176 using iterator = StackTy::const_reverse_iterator; 177 178 DSAVarData getDSA(iterator &Iter, ValueDecl *D) const; 179 180 /// Checks if the variable is a local for OpenMP region. 181 bool isOpenMPLocal(VarDecl *D, iterator Iter) const; 182 183 bool isStackEmpty() const { 184 return Stack.empty() || 185 Stack.back().second != CurrentNonCapturingFunctionScope || 186 Stack.back().first.empty(); 187 } 188 189 /// Vector of previously declared requires directives 190 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 191 /// omp_allocator_handle_t type. 192 QualType OMPAllocatorHandleT; 193 /// Expression for the predefined allocators. 194 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 195 nullptr}; 196 /// Vector of previously encountered target directives 197 SmallVector<SourceLocation, 2> TargetLocations; 198 199 public: 200 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 201 202 /// Sets omp_allocator_handle_t type. 203 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 204 /// Gets omp_allocator_handle_t type. 205 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 206 /// Sets the given default allocator. 207 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 208 Expr *Allocator) { 209 OMPPredefinedAllocators[AllocatorKind] = Allocator; 210 } 211 /// Returns the specified default allocator. 212 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 213 return OMPPredefinedAllocators[AllocatorKind]; 214 } 215 216 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 217 OpenMPClauseKind getClauseParsingMode() const { 218 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 219 return ClauseKindMode; 220 } 221 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 222 223 bool isForceVarCapturing() const { return ForceCapturing; } 224 void setForceVarCapturing(bool V) { ForceCapturing = V; } 225 226 void setForceCaptureByReferenceInTargetExecutable(bool V) { 227 ForceCaptureByReferenceInTargetExecutable = V; 228 } 229 bool isForceCaptureByReferenceInTargetExecutable() const { 230 return ForceCaptureByReferenceInTargetExecutable; 231 } 232 233 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 234 Scope *CurScope, SourceLocation Loc) { 235 if (Stack.empty() || 236 Stack.back().second != CurrentNonCapturingFunctionScope) 237 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 238 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 239 Stack.back().first.back().DefaultAttrLoc = Loc; 240 } 241 242 void pop() { 243 assert(!Stack.back().first.empty() && 244 "Data-sharing attributes stack is empty!"); 245 Stack.back().first.pop_back(); 246 } 247 248 /// Marks that we're started loop parsing. 249 void loopInit() { 250 assert(isOpenMPLoopDirective(getCurrentDirective()) && 251 "Expected loop-based directive."); 252 Stack.back().first.back().LoopStart = true; 253 } 254 /// Start capturing of the variables in the loop context. 255 void loopStart() { 256 assert(isOpenMPLoopDirective(getCurrentDirective()) && 257 "Expected loop-based directive."); 258 Stack.back().first.back().LoopStart = false; 259 } 260 /// true, if variables are captured, false otherwise. 261 bool isLoopStarted() const { 262 assert(isOpenMPLoopDirective(getCurrentDirective()) && 263 "Expected loop-based directive."); 264 return !Stack.back().first.back().LoopStart; 265 } 266 /// Marks (or clears) declaration as possibly loop counter. 267 void resetPossibleLoopCounter(const Decl *D = nullptr) { 268 Stack.back().first.back().PossiblyLoopCounter = 269 D ? D->getCanonicalDecl() : D; 270 } 271 /// Gets the possible loop counter decl. 272 const Decl *getPossiblyLoopCunter() const { 273 return Stack.back().first.back().PossiblyLoopCounter; 274 } 275 /// Start new OpenMP region stack in new non-capturing function. 276 void pushFunction() { 277 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 278 assert(!isa<CapturingScopeInfo>(CurFnScope)); 279 CurrentNonCapturingFunctionScope = CurFnScope; 280 } 281 /// Pop region stack for non-capturing function. 282 void popFunction(const FunctionScopeInfo *OldFSI) { 283 if (!Stack.empty() && Stack.back().second == OldFSI) { 284 assert(Stack.back().first.empty()); 285 Stack.pop_back(); 286 } 287 CurrentNonCapturingFunctionScope = nullptr; 288 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 289 if (!isa<CapturingScopeInfo>(FSI)) { 290 CurrentNonCapturingFunctionScope = FSI; 291 break; 292 } 293 } 294 } 295 296 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 297 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 298 } 299 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 300 getCriticalWithHint(const DeclarationNameInfo &Name) const { 301 auto I = Criticals.find(Name.getAsString()); 302 if (I != Criticals.end()) 303 return I->second; 304 return std::make_pair(nullptr, llvm::APSInt()); 305 } 306 /// If 'aligned' declaration for given variable \a D was not seen yet, 307 /// add it and return NULL; otherwise return previous occurrence's expression 308 /// for diagnostics. 309 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 310 311 /// Register specified variable as loop control variable. 312 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 313 /// Check if the specified variable is a loop control variable for 314 /// current region. 315 /// \return The index of the loop control variable in the list of associated 316 /// for-loops (from outer to inner). 317 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 318 /// Check if the specified variable is a loop control variable for 319 /// parent region. 320 /// \return The index of the loop control variable in the list of associated 321 /// for-loops (from outer to inner). 322 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 323 /// Get the loop control variable for the I-th loop (or nullptr) in 324 /// parent directive. 325 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 326 327 /// Adds explicit data sharing attribute to the specified declaration. 328 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 329 DeclRefExpr *PrivateCopy = nullptr); 330 331 /// Adds additional information for the reduction items with the reduction id 332 /// represented as an operator. 333 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 334 BinaryOperatorKind BOK); 335 /// Adds additional information for the reduction items with the reduction id 336 /// represented as reduction identifier. 337 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 338 const Expr *ReductionRef); 339 /// Returns the location and reduction operation from the innermost parent 340 /// region for the given \p D. 341 const DSAVarData 342 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 343 BinaryOperatorKind &BOK, 344 Expr *&TaskgroupDescriptor) const; 345 /// Returns the location and reduction operation from the innermost parent 346 /// region for the given \p D. 347 const DSAVarData 348 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 349 const Expr *&ReductionRef, 350 Expr *&TaskgroupDescriptor) const; 351 /// Return reduction reference expression for the current taskgroup. 352 Expr *getTaskgroupReductionRef() const { 353 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 354 "taskgroup reference expression requested for non taskgroup " 355 "directive."); 356 return Stack.back().first.back().TaskgroupReductionRef; 357 } 358 /// Checks if the given \p VD declaration is actually a taskgroup reduction 359 /// descriptor variable at the \p Level of OpenMP regions. 360 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 361 return Stack.back().first[Level].TaskgroupReductionRef && 362 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 363 ->getDecl() == VD; 364 } 365 366 /// Returns data sharing attributes from top of the stack for the 367 /// specified declaration. 368 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 369 /// Returns data-sharing attributes for the specified declaration. 370 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 371 /// Checks if the specified variables has data-sharing attributes which 372 /// match specified \a CPred predicate in any directive which matches \a DPred 373 /// predicate. 374 const DSAVarData 375 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 376 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 377 bool FromParent) const; 378 /// Checks if the specified variables has data-sharing attributes which 379 /// match specified \a CPred predicate in any innermost directive which 380 /// matches \a DPred predicate. 381 const DSAVarData 382 hasInnermostDSA(ValueDecl *D, 383 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 384 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 385 bool FromParent) const; 386 /// Checks if the specified variables has explicit data-sharing 387 /// attributes which match specified \a CPred predicate at the specified 388 /// OpenMP region. 389 bool hasExplicitDSA(const ValueDecl *D, 390 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 391 unsigned Level, bool NotLastprivate = false) const; 392 393 /// Returns true if the directive at level \Level matches in the 394 /// specified \a DPred predicate. 395 bool hasExplicitDirective( 396 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 397 unsigned Level) const; 398 399 /// Finds a directive which matches specified \a DPred predicate. 400 bool hasDirective( 401 const llvm::function_ref<bool( 402 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 403 DPred, 404 bool FromParent) const; 405 406 /// Returns currently analyzed directive. 407 OpenMPDirectiveKind getCurrentDirective() const { 408 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 409 } 410 /// Returns directive kind at specified level. 411 OpenMPDirectiveKind getDirective(unsigned Level) const { 412 assert(!isStackEmpty() && "No directive at specified level."); 413 return Stack.back().first[Level].Directive; 414 } 415 /// Returns parent directive. 416 OpenMPDirectiveKind getParentDirective() const { 417 if (isStackEmpty() || Stack.back().first.size() == 1) 418 return OMPD_unknown; 419 return std::next(Stack.back().first.rbegin())->Directive; 420 } 421 422 /// Add requires decl to internal vector 423 void addRequiresDecl(OMPRequiresDecl *RD) { 424 RequiresDecls.push_back(RD); 425 } 426 427 /// Checks if the defined 'requires' directive has specified type of clause. 428 template <typename ClauseType> 429 bool hasRequiresDeclWithClause() { 430 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 431 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 432 return isa<ClauseType>(C); 433 }); 434 }); 435 } 436 437 /// Checks for a duplicate clause amongst previously declared requires 438 /// directives 439 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 440 bool IsDuplicate = false; 441 for (OMPClause *CNew : ClauseList) { 442 for (const OMPRequiresDecl *D : RequiresDecls) { 443 for (const OMPClause *CPrev : D->clauselists()) { 444 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 445 SemaRef.Diag(CNew->getBeginLoc(), 446 diag::err_omp_requires_clause_redeclaration) 447 << getOpenMPClauseName(CNew->getClauseKind()); 448 SemaRef.Diag(CPrev->getBeginLoc(), 449 diag::note_omp_requires_previous_clause) 450 << getOpenMPClauseName(CPrev->getClauseKind()); 451 IsDuplicate = true; 452 } 453 } 454 } 455 } 456 return IsDuplicate; 457 } 458 459 /// Add location of previously encountered target to internal vector 460 void addTargetDirLocation(SourceLocation LocStart) { 461 TargetLocations.push_back(LocStart); 462 } 463 464 // Return previously encountered target region locations. 465 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 466 return TargetLocations; 467 } 468 469 /// Set default data sharing attribute to none. 470 void setDefaultDSANone(SourceLocation Loc) { 471 assert(!isStackEmpty()); 472 Stack.back().first.back().DefaultAttr = DSA_none; 473 Stack.back().first.back().DefaultAttrLoc = Loc; 474 } 475 /// Set default data sharing attribute to shared. 476 void setDefaultDSAShared(SourceLocation Loc) { 477 assert(!isStackEmpty()); 478 Stack.back().first.back().DefaultAttr = DSA_shared; 479 Stack.back().first.back().DefaultAttrLoc = Loc; 480 } 481 /// Set default data mapping attribute to 'tofrom:scalar'. 482 void setDefaultDMAToFromScalar(SourceLocation Loc) { 483 assert(!isStackEmpty()); 484 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 485 Stack.back().first.back().DefaultMapAttrLoc = Loc; 486 } 487 488 DefaultDataSharingAttributes getDefaultDSA() const { 489 return isStackEmpty() ? DSA_unspecified 490 : Stack.back().first.back().DefaultAttr; 491 } 492 SourceLocation getDefaultDSALocation() const { 493 return isStackEmpty() ? SourceLocation() 494 : Stack.back().first.back().DefaultAttrLoc; 495 } 496 DefaultMapAttributes getDefaultDMA() const { 497 return isStackEmpty() ? DMA_unspecified 498 : Stack.back().first.back().DefaultMapAttr; 499 } 500 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 501 return Stack.back().first[Level].DefaultMapAttr; 502 } 503 SourceLocation getDefaultDMALocation() const { 504 return isStackEmpty() ? SourceLocation() 505 : Stack.back().first.back().DefaultMapAttrLoc; 506 } 507 508 /// Checks if the specified variable is a threadprivate. 509 bool isThreadPrivate(VarDecl *D) { 510 const DSAVarData DVar = getTopDSA(D, false); 511 return isOpenMPThreadPrivate(DVar.CKind); 512 } 513 514 /// Marks current region as ordered (it has an 'ordered' clause). 515 void setOrderedRegion(bool IsOrdered, const Expr *Param, 516 OMPOrderedClause *Clause) { 517 assert(!isStackEmpty()); 518 if (IsOrdered) 519 Stack.back().first.back().OrderedRegion.emplace(Param, Clause); 520 else 521 Stack.back().first.back().OrderedRegion.reset(); 522 } 523 /// Returns true, if region is ordered (has associated 'ordered' clause), 524 /// false - otherwise. 525 bool isOrderedRegion() const { 526 if (isStackEmpty()) 527 return false; 528 return Stack.back().first.rbegin()->OrderedRegion.hasValue(); 529 } 530 /// Returns optional parameter for the ordered region. 531 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 532 if (isStackEmpty() || 533 !Stack.back().first.rbegin()->OrderedRegion.hasValue()) 534 return std::make_pair(nullptr, nullptr); 535 return Stack.back().first.rbegin()->OrderedRegion.getValue(); 536 } 537 /// Returns true, if parent region is ordered (has associated 538 /// 'ordered' clause), false - otherwise. 539 bool isParentOrderedRegion() const { 540 if (isStackEmpty() || Stack.back().first.size() == 1) 541 return false; 542 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); 543 } 544 /// Returns optional parameter for the ordered region. 545 std::pair<const Expr *, OMPOrderedClause *> 546 getParentOrderedRegionParam() const { 547 if (isStackEmpty() || Stack.back().first.size() == 1 || 548 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) 549 return std::make_pair(nullptr, nullptr); 550 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); 551 } 552 /// Marks current region as nowait (it has a 'nowait' clause). 553 void setNowaitRegion(bool IsNowait = true) { 554 assert(!isStackEmpty()); 555 Stack.back().first.back().NowaitRegion = IsNowait; 556 } 557 /// Returns true, if parent region is nowait (has associated 558 /// 'nowait' clause), false - otherwise. 559 bool isParentNowaitRegion() const { 560 if (isStackEmpty() || Stack.back().first.size() == 1) 561 return false; 562 return std::next(Stack.back().first.rbegin())->NowaitRegion; 563 } 564 /// Marks parent region as cancel region. 565 void setParentCancelRegion(bool Cancel = true) { 566 if (!isStackEmpty() && Stack.back().first.size() > 1) { 567 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 568 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 569 } 570 } 571 /// Return true if current region has inner cancel construct. 572 bool isCancelRegion() const { 573 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 574 } 575 576 /// Set collapse value for the region. 577 void setAssociatedLoops(unsigned Val) { 578 assert(!isStackEmpty()); 579 Stack.back().first.back().AssociatedLoops = Val; 580 } 581 /// Return collapse value for region. 582 unsigned getAssociatedLoops() const { 583 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 584 } 585 586 /// Marks current target region as one with closely nested teams 587 /// region. 588 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 589 if (!isStackEmpty() && Stack.back().first.size() > 1) { 590 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 591 TeamsRegionLoc; 592 } 593 } 594 /// Returns true, if current region has closely nested teams region. 595 bool hasInnerTeamsRegion() const { 596 return getInnerTeamsRegionLoc().isValid(); 597 } 598 /// Returns location of the nested teams region (if any). 599 SourceLocation getInnerTeamsRegionLoc() const { 600 return isStackEmpty() ? SourceLocation() 601 : Stack.back().first.back().InnerTeamsRegionLoc; 602 } 603 604 Scope *getCurScope() const { 605 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 606 } 607 SourceLocation getConstructLoc() const { 608 return isStackEmpty() ? SourceLocation() 609 : Stack.back().first.back().ConstructLoc; 610 } 611 612 /// Do the check specified in \a Check to all component lists and return true 613 /// if any issue is found. 614 bool checkMappableExprComponentListsForDecl( 615 const ValueDecl *VD, bool CurrentRegionOnly, 616 const llvm::function_ref< 617 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 618 OpenMPClauseKind)> 619 Check) const { 620 if (isStackEmpty()) 621 return false; 622 auto SI = Stack.back().first.rbegin(); 623 auto SE = Stack.back().first.rend(); 624 625 if (SI == SE) 626 return false; 627 628 if (CurrentRegionOnly) 629 SE = std::next(SI); 630 else 631 std::advance(SI, 1); 632 633 for (; SI != SE; ++SI) { 634 auto MI = SI->MappedExprComponents.find(VD); 635 if (MI != SI->MappedExprComponents.end()) 636 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 637 MI->second.Components) 638 if (Check(L, MI->second.Kind)) 639 return true; 640 } 641 return false; 642 } 643 644 /// Do the check specified in \a Check to all component lists at a given level 645 /// and return true if any issue is found. 646 bool checkMappableExprComponentListsForDeclAtLevel( 647 const ValueDecl *VD, unsigned Level, 648 const llvm::function_ref< 649 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 650 OpenMPClauseKind)> 651 Check) const { 652 if (isStackEmpty()) 653 return false; 654 655 auto StartI = Stack.back().first.begin(); 656 auto EndI = Stack.back().first.end(); 657 if (std::distance(StartI, EndI) <= (int)Level) 658 return false; 659 std::advance(StartI, Level); 660 661 auto MI = StartI->MappedExprComponents.find(VD); 662 if (MI != StartI->MappedExprComponents.end()) 663 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 664 MI->second.Components) 665 if (Check(L, MI->second.Kind)) 666 return true; 667 return false; 668 } 669 670 /// Create a new mappable expression component list associated with a given 671 /// declaration and initialize it with the provided list of components. 672 void addMappableExpressionComponents( 673 const ValueDecl *VD, 674 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 675 OpenMPClauseKind WhereFoundClauseKind) { 676 assert(!isStackEmpty() && 677 "Not expecting to retrieve components from a empty stack!"); 678 MappedExprComponentTy &MEC = 679 Stack.back().first.back().MappedExprComponents[VD]; 680 // Create new entry and append the new components there. 681 MEC.Components.resize(MEC.Components.size() + 1); 682 MEC.Components.back().append(Components.begin(), Components.end()); 683 MEC.Kind = WhereFoundClauseKind; 684 } 685 686 unsigned getNestingLevel() const { 687 assert(!isStackEmpty()); 688 return Stack.back().first.size() - 1; 689 } 690 void addDoacrossDependClause(OMPDependClause *C, 691 const OperatorOffsetTy &OpsOffs) { 692 assert(!isStackEmpty() && Stack.back().first.size() > 1); 693 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 694 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 695 StackElem.DoacrossDepends.try_emplace(C, OpsOffs); 696 } 697 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 698 getDoacrossDependClauses() const { 699 assert(!isStackEmpty()); 700 const SharingMapTy &StackElem = Stack.back().first.back(); 701 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 702 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 703 return llvm::make_range(Ref.begin(), Ref.end()); 704 } 705 return llvm::make_range(StackElem.DoacrossDepends.end(), 706 StackElem.DoacrossDepends.end()); 707 } 708 709 // Store types of classes which have been explicitly mapped 710 void addMappedClassesQualTypes(QualType QT) { 711 SharingMapTy &StackElem = Stack.back().first.back(); 712 StackElem.MappedClassesQualTypes.insert(QT); 713 } 714 715 // Return set of mapped classes types 716 bool isClassPreviouslyMapped(QualType QT) const { 717 const SharingMapTy &StackElem = Stack.back().first.back(); 718 return StackElem.MappedClassesQualTypes.count(QT) != 0; 719 } 720 721 /// Adds global declare target to the parent target region. 722 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 723 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 724 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 725 "Expected declare target link global."); 726 if (isStackEmpty()) 727 return; 728 auto It = Stack.back().first.rbegin(); 729 while (It != Stack.back().first.rend() && 730 !isOpenMPTargetExecutionDirective(It->Directive)) 731 ++It; 732 if (It != Stack.back().first.rend()) { 733 assert(isOpenMPTargetExecutionDirective(It->Directive) && 734 "Expected target executable directive."); 735 It->DeclareTargetLinkVarDecls.push_back(E); 736 } 737 } 738 739 /// Returns the list of globals with declare target link if current directive 740 /// is target. 741 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 742 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 743 "Expected target executable directive."); 744 return Stack.back().first.back().DeclareTargetLinkVarDecls; 745 } 746 }; 747 748 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 749 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 750 } 751 752 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 753 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown; 754 } 755 756 } // namespace 757 758 static const Expr *getExprAsWritten(const Expr *E) { 759 if (const auto *FE = dyn_cast<FullExpr>(E)) 760 E = FE->getSubExpr(); 761 762 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 763 E = MTE->GetTemporaryExpr(); 764 765 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 766 E = Binder->getSubExpr(); 767 768 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 769 E = ICE->getSubExprAsWritten(); 770 return E->IgnoreParens(); 771 } 772 773 static Expr *getExprAsWritten(Expr *E) { 774 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 775 } 776 777 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 778 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 779 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 780 D = ME->getMemberDecl(); 781 const auto *VD = dyn_cast<VarDecl>(D); 782 const auto *FD = dyn_cast<FieldDecl>(D); 783 if (VD != nullptr) { 784 VD = VD->getCanonicalDecl(); 785 D = VD; 786 } else { 787 assert(FD); 788 FD = FD->getCanonicalDecl(); 789 D = FD; 790 } 791 return D; 792 } 793 794 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 795 return const_cast<ValueDecl *>( 796 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 797 } 798 799 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 800 ValueDecl *D) const { 801 D = getCanonicalDecl(D); 802 auto *VD = dyn_cast<VarDecl>(D); 803 const auto *FD = dyn_cast<FieldDecl>(D); 804 DSAVarData DVar; 805 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 806 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 807 // in a region but not in construct] 808 // File-scope or namespace-scope variables referenced in called routines 809 // in the region are shared unless they appear in a threadprivate 810 // directive. 811 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 812 DVar.CKind = OMPC_shared; 813 814 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 815 // in a region but not in construct] 816 // Variables with static storage duration that are declared in called 817 // routines in the region are shared. 818 if (VD && VD->hasGlobalStorage()) 819 DVar.CKind = OMPC_shared; 820 821 // Non-static data members are shared by default. 822 if (FD) 823 DVar.CKind = OMPC_shared; 824 825 return DVar; 826 } 827 828 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 829 // in a Construct, C/C++, predetermined, p.1] 830 // Variables with automatic storage duration that are declared in a scope 831 // inside the construct are private. 832 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 833 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 834 DVar.CKind = OMPC_private; 835 return DVar; 836 } 837 838 DVar.DKind = Iter->Directive; 839 // Explicitly specified attributes and local variables with predetermined 840 // attributes. 841 if (Iter->SharingMap.count(D)) { 842 const DSAInfo &Data = Iter->SharingMap.lookup(D); 843 DVar.RefExpr = Data.RefExpr.getPointer(); 844 DVar.PrivateCopy = Data.PrivateCopy; 845 DVar.CKind = Data.Attributes; 846 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 847 return DVar; 848 } 849 850 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 851 // in a Construct, C/C++, implicitly determined, p.1] 852 // In a parallel or task construct, the data-sharing attributes of these 853 // variables are determined by the default clause, if present. 854 switch (Iter->DefaultAttr) { 855 case DSA_shared: 856 DVar.CKind = OMPC_shared; 857 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 858 return DVar; 859 case DSA_none: 860 return DVar; 861 case DSA_unspecified: 862 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 863 // in a Construct, implicitly determined, p.2] 864 // In a parallel construct, if no default clause is present, these 865 // variables are shared. 866 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 867 if (isOpenMPParallelDirective(DVar.DKind) || 868 isOpenMPTeamsDirective(DVar.DKind)) { 869 DVar.CKind = OMPC_shared; 870 return DVar; 871 } 872 873 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 874 // in a Construct, implicitly determined, p.4] 875 // In a task construct, if no default clause is present, a variable that in 876 // the enclosing context is determined to be shared by all implicit tasks 877 // bound to the current team is shared. 878 if (isOpenMPTaskingDirective(DVar.DKind)) { 879 DSAVarData DVarTemp; 880 iterator I = Iter, E = Stack.back().first.rend(); 881 do { 882 ++I; 883 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 884 // Referenced in a Construct, implicitly determined, p.6] 885 // In a task construct, if no default clause is present, a variable 886 // whose data-sharing attribute is not determined by the rules above is 887 // firstprivate. 888 DVarTemp = getDSA(I, D); 889 if (DVarTemp.CKind != OMPC_shared) { 890 DVar.RefExpr = nullptr; 891 DVar.CKind = OMPC_firstprivate; 892 return DVar; 893 } 894 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 895 DVar.CKind = 896 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 897 return DVar; 898 } 899 } 900 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 901 // in a Construct, implicitly determined, p.3] 902 // For constructs other than task, if no default clause is present, these 903 // variables inherit their data-sharing attributes from the enclosing 904 // context. 905 return getDSA(++Iter, D); 906 } 907 908 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 909 const Expr *NewDE) { 910 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 911 D = getCanonicalDecl(D); 912 SharingMapTy &StackElem = Stack.back().first.back(); 913 auto It = StackElem.AlignedMap.find(D); 914 if (It == StackElem.AlignedMap.end()) { 915 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 916 StackElem.AlignedMap[D] = NewDE; 917 return nullptr; 918 } 919 assert(It->second && "Unexpected nullptr expr in the aligned map"); 920 return It->second; 921 } 922 923 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 924 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 925 D = getCanonicalDecl(D); 926 SharingMapTy &StackElem = Stack.back().first.back(); 927 StackElem.LCVMap.try_emplace( 928 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 929 } 930 931 const DSAStackTy::LCDeclInfo 932 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 933 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 934 D = getCanonicalDecl(D); 935 const SharingMapTy &StackElem = Stack.back().first.back(); 936 auto It = StackElem.LCVMap.find(D); 937 if (It != StackElem.LCVMap.end()) 938 return It->second; 939 return {0, nullptr}; 940 } 941 942 const DSAStackTy::LCDeclInfo 943 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 944 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 945 "Data-sharing attributes stack is empty"); 946 D = getCanonicalDecl(D); 947 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 948 auto It = StackElem.LCVMap.find(D); 949 if (It != StackElem.LCVMap.end()) 950 return It->second; 951 return {0, nullptr}; 952 } 953 954 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 955 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 956 "Data-sharing attributes stack is empty"); 957 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 958 if (StackElem.LCVMap.size() < I) 959 return nullptr; 960 for (const auto &Pair : StackElem.LCVMap) 961 if (Pair.second.first == I) 962 return Pair.first; 963 return nullptr; 964 } 965 966 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 967 DeclRefExpr *PrivateCopy) { 968 D = getCanonicalDecl(D); 969 if (A == OMPC_threadprivate) { 970 DSAInfo &Data = Threadprivates[D]; 971 Data.Attributes = A; 972 Data.RefExpr.setPointer(E); 973 Data.PrivateCopy = nullptr; 974 } else { 975 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 976 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 977 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 978 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 979 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 980 (isLoopControlVariable(D).first && A == OMPC_private)); 981 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 982 Data.RefExpr.setInt(/*IntVal=*/true); 983 return; 984 } 985 const bool IsLastprivate = 986 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 987 Data.Attributes = A; 988 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 989 Data.PrivateCopy = PrivateCopy; 990 if (PrivateCopy) { 991 DSAInfo &Data = 992 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 993 Data.Attributes = A; 994 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 995 Data.PrivateCopy = nullptr; 996 } 997 } 998 } 999 1000 /// Build a variable declaration for OpenMP loop iteration variable. 1001 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1002 StringRef Name, const AttrVec *Attrs = nullptr, 1003 DeclRefExpr *OrigRef = nullptr) { 1004 DeclContext *DC = SemaRef.CurContext; 1005 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1006 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1007 auto *Decl = 1008 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1009 if (Attrs) { 1010 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1011 I != E; ++I) 1012 Decl->addAttr(*I); 1013 } 1014 Decl->setImplicit(); 1015 if (OrigRef) { 1016 Decl->addAttr( 1017 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1018 } 1019 return Decl; 1020 } 1021 1022 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1023 SourceLocation Loc, 1024 bool RefersToCapture = false) { 1025 D->setReferenced(); 1026 D->markUsed(S.Context); 1027 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1028 SourceLocation(), D, RefersToCapture, Loc, Ty, 1029 VK_LValue); 1030 } 1031 1032 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1033 BinaryOperatorKind BOK) { 1034 D = getCanonicalDecl(D); 1035 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1036 assert( 1037 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1038 "Additional reduction info may be specified only for reduction items."); 1039 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1040 assert(ReductionData.ReductionRange.isInvalid() && 1041 Stack.back().first.back().Directive == OMPD_taskgroup && 1042 "Additional reduction info may be specified only once for reduction " 1043 "items."); 1044 ReductionData.set(BOK, SR); 1045 Expr *&TaskgroupReductionRef = 1046 Stack.back().first.back().TaskgroupReductionRef; 1047 if (!TaskgroupReductionRef) { 1048 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1049 SemaRef.Context.VoidPtrTy, ".task_red."); 1050 TaskgroupReductionRef = 1051 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1052 } 1053 } 1054 1055 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1056 const Expr *ReductionRef) { 1057 D = getCanonicalDecl(D); 1058 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1059 assert( 1060 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1061 "Additional reduction info may be specified only for reduction items."); 1062 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1063 assert(ReductionData.ReductionRange.isInvalid() && 1064 Stack.back().first.back().Directive == OMPD_taskgroup && 1065 "Additional reduction info may be specified only once for reduction " 1066 "items."); 1067 ReductionData.set(ReductionRef, SR); 1068 Expr *&TaskgroupReductionRef = 1069 Stack.back().first.back().TaskgroupReductionRef; 1070 if (!TaskgroupReductionRef) { 1071 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1072 SemaRef.Context.VoidPtrTy, ".task_red."); 1073 TaskgroupReductionRef = 1074 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1075 } 1076 } 1077 1078 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1079 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1080 Expr *&TaskgroupDescriptor) const { 1081 D = getCanonicalDecl(D); 1082 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1083 if (Stack.back().first.empty()) 1084 return DSAVarData(); 1085 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1086 E = Stack.back().first.rend(); 1087 I != E; std::advance(I, 1)) { 1088 const DSAInfo &Data = I->SharingMap.lookup(D); 1089 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1090 continue; 1091 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1092 if (!ReductionData.ReductionOp || 1093 ReductionData.ReductionOp.is<const Expr *>()) 1094 return DSAVarData(); 1095 SR = ReductionData.ReductionRange; 1096 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1097 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1098 "expression for the descriptor is not " 1099 "set."); 1100 TaskgroupDescriptor = I->TaskgroupReductionRef; 1101 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1102 Data.PrivateCopy, I->DefaultAttrLoc); 1103 } 1104 return DSAVarData(); 1105 } 1106 1107 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1108 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1109 Expr *&TaskgroupDescriptor) const { 1110 D = getCanonicalDecl(D); 1111 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1112 if (Stack.back().first.empty()) 1113 return DSAVarData(); 1114 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1115 E = Stack.back().first.rend(); 1116 I != E; std::advance(I, 1)) { 1117 const DSAInfo &Data = I->SharingMap.lookup(D); 1118 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1119 continue; 1120 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1121 if (!ReductionData.ReductionOp || 1122 !ReductionData.ReductionOp.is<const Expr *>()) 1123 return DSAVarData(); 1124 SR = ReductionData.ReductionRange; 1125 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1126 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1127 "expression for the descriptor is not " 1128 "set."); 1129 TaskgroupDescriptor = I->TaskgroupReductionRef; 1130 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1131 Data.PrivateCopy, I->DefaultAttrLoc); 1132 } 1133 return DSAVarData(); 1134 } 1135 1136 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 1137 D = D->getCanonicalDecl(); 1138 if (!isStackEmpty()) { 1139 iterator I = Iter, E = Stack.back().first.rend(); 1140 Scope *TopScope = nullptr; 1141 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) && 1142 !isOpenMPTargetExecutionDirective(I->Directive)) 1143 ++I; 1144 if (I == E) 1145 return false; 1146 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1147 Scope *CurScope = getCurScope(); 1148 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1149 CurScope = CurScope->getParent(); 1150 return CurScope != TopScope; 1151 } 1152 return false; 1153 } 1154 1155 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1156 bool AcceptIfMutable = true, 1157 bool *IsClassType = nullptr) { 1158 ASTContext &Context = SemaRef.getASTContext(); 1159 Type = Type.getNonReferenceType().getCanonicalType(); 1160 bool IsConstant = Type.isConstant(Context); 1161 Type = Context.getBaseElementType(Type); 1162 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1163 ? Type->getAsCXXRecordDecl() 1164 : nullptr; 1165 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1166 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1167 RD = CTD->getTemplatedDecl(); 1168 if (IsClassType) 1169 *IsClassType = RD; 1170 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1171 RD->hasDefinition() && RD->hasMutableFields()); 1172 } 1173 1174 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1175 QualType Type, OpenMPClauseKind CKind, 1176 SourceLocation ELoc, 1177 bool AcceptIfMutable = true, 1178 bool ListItemNotVar = false) { 1179 ASTContext &Context = SemaRef.getASTContext(); 1180 bool IsClassType; 1181 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1182 unsigned Diag = ListItemNotVar 1183 ? diag::err_omp_const_list_item 1184 : IsClassType ? diag::err_omp_const_not_mutable_variable 1185 : diag::err_omp_const_variable; 1186 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1187 if (!ListItemNotVar && D) { 1188 const VarDecl *VD = dyn_cast<VarDecl>(D); 1189 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1190 VarDecl::DeclarationOnly; 1191 SemaRef.Diag(D->getLocation(), 1192 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1193 << D; 1194 } 1195 return true; 1196 } 1197 return false; 1198 } 1199 1200 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1201 bool FromParent) { 1202 D = getCanonicalDecl(D); 1203 DSAVarData DVar; 1204 1205 auto *VD = dyn_cast<VarDecl>(D); 1206 auto TI = Threadprivates.find(D); 1207 if (TI != Threadprivates.end()) { 1208 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1209 DVar.CKind = OMPC_threadprivate; 1210 return DVar; 1211 } 1212 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1213 DVar.RefExpr = buildDeclRefExpr( 1214 SemaRef, VD, D->getType().getNonReferenceType(), 1215 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1216 DVar.CKind = OMPC_threadprivate; 1217 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1218 return DVar; 1219 } 1220 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1221 // in a Construct, C/C++, predetermined, p.1] 1222 // Variables appearing in threadprivate directives are threadprivate. 1223 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1224 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1225 SemaRef.getLangOpts().OpenMPUseTLS && 1226 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1227 (VD && VD->getStorageClass() == SC_Register && 1228 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1229 DVar.RefExpr = buildDeclRefExpr( 1230 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1231 DVar.CKind = OMPC_threadprivate; 1232 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1233 return DVar; 1234 } 1235 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1236 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1237 !isLoopControlVariable(D).first) { 1238 iterator IterTarget = 1239 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1240 [](const SharingMapTy &Data) { 1241 return isOpenMPTargetExecutionDirective(Data.Directive); 1242 }); 1243 if (IterTarget != Stack.back().first.rend()) { 1244 iterator ParentIterTarget = std::next(IterTarget, 1); 1245 for (iterator Iter = Stack.back().first.rbegin(); 1246 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1247 if (isOpenMPLocal(VD, Iter)) { 1248 DVar.RefExpr = 1249 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1250 D->getLocation()); 1251 DVar.CKind = OMPC_threadprivate; 1252 return DVar; 1253 } 1254 } 1255 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1256 auto DSAIter = IterTarget->SharingMap.find(D); 1257 if (DSAIter != IterTarget->SharingMap.end() && 1258 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1259 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1260 DVar.CKind = OMPC_threadprivate; 1261 return DVar; 1262 } 1263 iterator End = Stack.back().first.rend(); 1264 if (!SemaRef.isOpenMPCapturedByRef( 1265 D, std::distance(ParentIterTarget, End))) { 1266 DVar.RefExpr = 1267 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1268 IterTarget->ConstructLoc); 1269 DVar.CKind = OMPC_threadprivate; 1270 return DVar; 1271 } 1272 } 1273 } 1274 } 1275 1276 if (isStackEmpty()) 1277 // Not in OpenMP execution region and top scope was already checked. 1278 return DVar; 1279 1280 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1281 // in a Construct, C/C++, predetermined, p.4] 1282 // Static data members are shared. 1283 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1284 // in a Construct, C/C++, predetermined, p.7] 1285 // Variables with static storage duration that are declared in a scope 1286 // inside the construct are shared. 1287 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1288 if (VD && VD->isStaticDataMember()) { 1289 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1290 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1291 return DVar; 1292 1293 DVar.CKind = OMPC_shared; 1294 return DVar; 1295 } 1296 1297 // The predetermined shared attribute for const-qualified types having no 1298 // mutable members was removed after OpenMP 3.1. 1299 if (SemaRef.LangOpts.OpenMP <= 31) { 1300 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1301 // in a Construct, C/C++, predetermined, p.6] 1302 // Variables with const qualified type having no mutable member are 1303 // shared. 1304 if (isConstNotMutableType(SemaRef, D->getType())) { 1305 // Variables with const-qualified type having no mutable member may be 1306 // listed in a firstprivate clause, even if they are static data members. 1307 DSAVarData DVarTemp = hasInnermostDSA( 1308 D, 1309 [](OpenMPClauseKind C) { 1310 return C == OMPC_firstprivate || C == OMPC_shared; 1311 }, 1312 MatchesAlways, FromParent); 1313 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1314 return DVarTemp; 1315 1316 DVar.CKind = OMPC_shared; 1317 return DVar; 1318 } 1319 } 1320 1321 // Explicitly specified attributes and local variables with predetermined 1322 // attributes. 1323 iterator I = Stack.back().first.rbegin(); 1324 iterator EndI = Stack.back().first.rend(); 1325 if (FromParent && I != EndI) 1326 std::advance(I, 1); 1327 auto It = I->SharingMap.find(D); 1328 if (It != I->SharingMap.end()) { 1329 const DSAInfo &Data = It->getSecond(); 1330 DVar.RefExpr = Data.RefExpr.getPointer(); 1331 DVar.PrivateCopy = Data.PrivateCopy; 1332 DVar.CKind = Data.Attributes; 1333 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1334 DVar.DKind = I->Directive; 1335 } 1336 1337 return DVar; 1338 } 1339 1340 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1341 bool FromParent) const { 1342 if (isStackEmpty()) { 1343 iterator I; 1344 return getDSA(I, D); 1345 } 1346 D = getCanonicalDecl(D); 1347 iterator StartI = Stack.back().first.rbegin(); 1348 iterator EndI = Stack.back().first.rend(); 1349 if (FromParent && StartI != EndI) 1350 std::advance(StartI, 1); 1351 return getDSA(StartI, D); 1352 } 1353 1354 const DSAStackTy::DSAVarData 1355 DSAStackTy::hasDSA(ValueDecl *D, 1356 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1357 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1358 bool FromParent) const { 1359 if (isStackEmpty()) 1360 return {}; 1361 D = getCanonicalDecl(D); 1362 iterator I = Stack.back().first.rbegin(); 1363 iterator EndI = Stack.back().first.rend(); 1364 if (FromParent && I != EndI) 1365 std::advance(I, 1); 1366 for (; I != EndI; std::advance(I, 1)) { 1367 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive)) 1368 continue; 1369 iterator NewI = I; 1370 DSAVarData DVar = getDSA(NewI, D); 1371 if (I == NewI && CPred(DVar.CKind)) 1372 return DVar; 1373 } 1374 return {}; 1375 } 1376 1377 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1378 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1379 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1380 bool FromParent) const { 1381 if (isStackEmpty()) 1382 return {}; 1383 D = getCanonicalDecl(D); 1384 iterator StartI = Stack.back().first.rbegin(); 1385 iterator EndI = Stack.back().first.rend(); 1386 if (FromParent && StartI != EndI) 1387 std::advance(StartI, 1); 1388 if (StartI == EndI || !DPred(StartI->Directive)) 1389 return {}; 1390 iterator NewI = StartI; 1391 DSAVarData DVar = getDSA(NewI, D); 1392 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1393 } 1394 1395 bool DSAStackTy::hasExplicitDSA( 1396 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1397 unsigned Level, bool NotLastprivate) const { 1398 if (isStackEmpty()) 1399 return false; 1400 D = getCanonicalDecl(D); 1401 auto StartI = Stack.back().first.begin(); 1402 auto EndI = Stack.back().first.end(); 1403 if (std::distance(StartI, EndI) <= (int)Level) 1404 return false; 1405 std::advance(StartI, Level); 1406 auto I = StartI->SharingMap.find(D); 1407 if ((I != StartI->SharingMap.end()) && 1408 I->getSecond().RefExpr.getPointer() && 1409 CPred(I->getSecond().Attributes) && 1410 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1411 return true; 1412 // Check predetermined rules for the loop control variables. 1413 auto LI = StartI->LCVMap.find(D); 1414 if (LI != StartI->LCVMap.end()) 1415 return CPred(OMPC_private); 1416 return false; 1417 } 1418 1419 bool DSAStackTy::hasExplicitDirective( 1420 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1421 unsigned Level) const { 1422 if (isStackEmpty()) 1423 return false; 1424 auto StartI = Stack.back().first.begin(); 1425 auto EndI = Stack.back().first.end(); 1426 if (std::distance(StartI, EndI) <= (int)Level) 1427 return false; 1428 std::advance(StartI, Level); 1429 return DPred(StartI->Directive); 1430 } 1431 1432 bool DSAStackTy::hasDirective( 1433 const llvm::function_ref<bool(OpenMPDirectiveKind, 1434 const DeclarationNameInfo &, SourceLocation)> 1435 DPred, 1436 bool FromParent) const { 1437 // We look only in the enclosing region. 1438 if (isStackEmpty()) 1439 return false; 1440 auto StartI = std::next(Stack.back().first.rbegin()); 1441 auto EndI = Stack.back().first.rend(); 1442 if (FromParent && StartI != EndI) 1443 StartI = std::next(StartI); 1444 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1445 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1446 return true; 1447 } 1448 return false; 1449 } 1450 1451 void Sema::InitDataSharingAttributesStack() { 1452 VarDataSharingAttributesStack = new DSAStackTy(*this); 1453 } 1454 1455 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1456 1457 void Sema::pushOpenMPFunctionRegion() { 1458 DSAStack->pushFunction(); 1459 } 1460 1461 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1462 DSAStack->popFunction(OldFSI); 1463 } 1464 1465 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1466 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1467 "Expected OpenMP device compilation."); 1468 return !S.isInOpenMPTargetExecutionDirective() && 1469 !S.isInOpenMPDeclareTargetContext(); 1470 } 1471 1472 /// Do we know that we will eventually codegen the given function? 1473 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1474 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1475 "Expected OpenMP device compilation."); 1476 // Templates are emitted when they're instantiated. 1477 if (FD->isDependentContext()) 1478 return false; 1479 1480 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1481 FD->getCanonicalDecl())) 1482 return true; 1483 1484 // Otherwise, the function is known-emitted if it's in our set of 1485 // known-emitted functions. 1486 return S.DeviceKnownEmittedFns.count(FD) > 0; 1487 } 1488 1489 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1490 unsigned DiagID) { 1491 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1492 "Expected OpenMP device compilation."); 1493 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1494 !isKnownEmitted(*this, getCurFunctionDecl())) 1495 ? DeviceDiagBuilder::K_Deferred 1496 : DeviceDiagBuilder::K_Immediate, 1497 Loc, DiagID, getCurFunctionDecl(), *this); 1498 } 1499 1500 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1501 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1502 "Expected OpenMP device compilation."); 1503 assert(Callee && "Callee may not be null."); 1504 FunctionDecl *Caller = getCurFunctionDecl(); 1505 1506 // If the caller is known-emitted, mark the callee as known-emitted. 1507 // Otherwise, mark the call in our call graph so we can traverse it later. 1508 if (!isOpenMPDeviceDelayedContext(*this) || 1509 (Caller && isKnownEmitted(*this, Caller))) 1510 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1511 else if (Caller) 1512 DeviceCallGraph[Caller].insert({Callee, Loc}); 1513 } 1514 1515 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1516 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1517 "OpenMP device compilation mode is expected."); 1518 QualType Ty = E->getType(); 1519 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1520 (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) || 1521 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1522 !Context.getTargetInfo().hasInt128Type())) 1523 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1524 << Ty << E->getSourceRange(); 1525 } 1526 1527 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1528 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1529 1530 ASTContext &Ctx = getASTContext(); 1531 bool IsByRef = true; 1532 1533 // Find the directive that is associated with the provided scope. 1534 D = cast<ValueDecl>(D->getCanonicalDecl()); 1535 QualType Ty = D->getType(); 1536 1537 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1538 // This table summarizes how a given variable should be passed to the device 1539 // given its type and the clauses where it appears. This table is based on 1540 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1541 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1542 // 1543 // ========================================================================= 1544 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1545 // | |(tofrom:scalar)| | pvt | | | | 1546 // ========================================================================= 1547 // | scl | | | | - | | bycopy| 1548 // | scl | | - | x | - | - | bycopy| 1549 // | scl | | x | - | - | - | null | 1550 // | scl | x | | | - | | byref | 1551 // | scl | x | - | x | - | - | bycopy| 1552 // | scl | x | x | - | - | - | null | 1553 // | scl | | - | - | - | x | byref | 1554 // | scl | x | - | - | - | x | byref | 1555 // 1556 // | agg | n.a. | | | - | | byref | 1557 // | agg | n.a. | - | x | - | - | byref | 1558 // | agg | n.a. | x | - | - | - | null | 1559 // | agg | n.a. | - | - | - | x | byref | 1560 // | agg | n.a. | - | - | - | x[] | byref | 1561 // 1562 // | ptr | n.a. | | | - | | bycopy| 1563 // | ptr | n.a. | - | x | - | - | bycopy| 1564 // | ptr | n.a. | x | - | - | - | null | 1565 // | ptr | n.a. | - | - | - | x | byref | 1566 // | ptr | n.a. | - | - | - | x[] | bycopy| 1567 // | ptr | n.a. | - | - | x | | bycopy| 1568 // | ptr | n.a. | - | - | x | x | bycopy| 1569 // | ptr | n.a. | - | - | x | x[] | bycopy| 1570 // ========================================================================= 1571 // Legend: 1572 // scl - scalar 1573 // ptr - pointer 1574 // agg - aggregate 1575 // x - applies 1576 // - - invalid in this combination 1577 // [] - mapped with an array section 1578 // byref - should be mapped by reference 1579 // byval - should be mapped by value 1580 // null - initialize a local variable to null on the device 1581 // 1582 // Observations: 1583 // - All scalar declarations that show up in a map clause have to be passed 1584 // by reference, because they may have been mapped in the enclosing data 1585 // environment. 1586 // - If the scalar value does not fit the size of uintptr, it has to be 1587 // passed by reference, regardless the result in the table above. 1588 // - For pointers mapped by value that have either an implicit map or an 1589 // array section, the runtime library may pass the NULL value to the 1590 // device instead of the value passed to it by the compiler. 1591 1592 if (Ty->isReferenceType()) 1593 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1594 1595 // Locate map clauses and see if the variable being captured is referred to 1596 // in any of those clauses. Here we only care about variables, not fields, 1597 // because fields are part of aggregates. 1598 bool IsVariableUsedInMapClause = false; 1599 bool IsVariableAssociatedWithSection = false; 1600 1601 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1602 D, Level, 1603 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1604 OMPClauseMappableExprCommon::MappableExprComponentListRef 1605 MapExprComponents, 1606 OpenMPClauseKind WhereFoundClauseKind) { 1607 // Only the map clause information influences how a variable is 1608 // captured. E.g. is_device_ptr does not require changing the default 1609 // behavior. 1610 if (WhereFoundClauseKind != OMPC_map) 1611 return false; 1612 1613 auto EI = MapExprComponents.rbegin(); 1614 auto EE = MapExprComponents.rend(); 1615 1616 assert(EI != EE && "Invalid map expression!"); 1617 1618 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1619 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1620 1621 ++EI; 1622 if (EI == EE) 1623 return false; 1624 1625 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1626 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1627 isa<MemberExpr>(EI->getAssociatedExpression())) { 1628 IsVariableAssociatedWithSection = true; 1629 // There is nothing more we need to know about this variable. 1630 return true; 1631 } 1632 1633 // Keep looking for more map info. 1634 return false; 1635 }); 1636 1637 if (IsVariableUsedInMapClause) { 1638 // If variable is identified in a map clause it is always captured by 1639 // reference except if it is a pointer that is dereferenced somehow. 1640 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1641 } else { 1642 // By default, all the data that has a scalar type is mapped by copy 1643 // (except for reduction variables). 1644 IsByRef = 1645 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1646 !Ty->isAnyPointerType()) || 1647 !Ty->isScalarType() || 1648 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1649 DSAStack->hasExplicitDSA( 1650 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1651 } 1652 } 1653 1654 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1655 IsByRef = 1656 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1657 !Ty->isAnyPointerType()) || 1658 !DSAStack->hasExplicitDSA( 1659 D, 1660 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1661 Level, /*NotLastprivate=*/true)) && 1662 // If the variable is artificial and must be captured by value - try to 1663 // capture by value. 1664 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1665 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1666 } 1667 1668 // When passing data by copy, we need to make sure it fits the uintptr size 1669 // and alignment, because the runtime library only deals with uintptr types. 1670 // If it does not fit the uintptr size, we need to pass the data by reference 1671 // instead. 1672 if (!IsByRef && 1673 (Ctx.getTypeSizeInChars(Ty) > 1674 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1675 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1676 IsByRef = true; 1677 } 1678 1679 return IsByRef; 1680 } 1681 1682 unsigned Sema::getOpenMPNestingLevel() const { 1683 assert(getLangOpts().OpenMP); 1684 return DSAStack->getNestingLevel(); 1685 } 1686 1687 bool Sema::isInOpenMPTargetExecutionDirective() const { 1688 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1689 !DSAStack->isClauseParsingMode()) || 1690 DSAStack->hasDirective( 1691 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1692 SourceLocation) -> bool { 1693 return isOpenMPTargetExecutionDirective(K); 1694 }, 1695 false); 1696 } 1697 1698 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { 1699 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1700 D = getCanonicalDecl(D); 1701 1702 // If we are attempting to capture a global variable in a directive with 1703 // 'target' we return true so that this global is also mapped to the device. 1704 // 1705 auto *VD = dyn_cast<VarDecl>(D); 1706 if (VD && !VD->hasLocalStorage()) { 1707 if (isInOpenMPDeclareTargetContext() && 1708 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1709 // Try to mark variable as declare target if it is used in capturing 1710 // regions. 1711 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1712 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1713 return nullptr; 1714 } else if (isInOpenMPTargetExecutionDirective()) { 1715 // If the declaration is enclosed in a 'declare target' directive, 1716 // then it should not be captured. 1717 // 1718 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1719 return nullptr; 1720 return VD; 1721 } 1722 } 1723 // Capture variables captured by reference in lambdas for target-based 1724 // directives. 1725 if (VD && !DSAStack->isClauseParsingMode()) { 1726 if (const auto *RD = VD->getType() 1727 .getCanonicalType() 1728 .getNonReferenceType() 1729 ->getAsCXXRecordDecl()) { 1730 bool SavedForceCaptureByReferenceInTargetExecutable = 1731 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1732 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1733 if (RD->isLambda()) { 1734 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1735 FieldDecl *ThisCapture; 1736 RD->getCaptureFields(Captures, ThisCapture); 1737 for (const LambdaCapture &LC : RD->captures()) { 1738 if (LC.getCaptureKind() == LCK_ByRef) { 1739 VarDecl *VD = LC.getCapturedVar(); 1740 DeclContext *VDC = VD->getDeclContext(); 1741 if (!VDC->Encloses(CurContext)) 1742 continue; 1743 DSAStackTy::DSAVarData DVarPrivate = 1744 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1745 // Do not capture already captured variables. 1746 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1747 DVarPrivate.CKind == OMPC_unknown && 1748 !DSAStack->checkMappableExprComponentListsForDecl( 1749 D, /*CurrentRegionOnly=*/true, 1750 [](OMPClauseMappableExprCommon:: 1751 MappableExprComponentListRef, 1752 OpenMPClauseKind) { return true; })) 1753 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1754 } else if (LC.getCaptureKind() == LCK_This) { 1755 QualType ThisTy = getCurrentThisType(); 1756 if (!ThisTy.isNull() && 1757 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1758 CheckCXXThisCapture(LC.getLocation()); 1759 } 1760 } 1761 } 1762 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1763 SavedForceCaptureByReferenceInTargetExecutable); 1764 } 1765 } 1766 1767 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1768 (!DSAStack->isClauseParsingMode() || 1769 DSAStack->getParentDirective() != OMPD_unknown)) { 1770 auto &&Info = DSAStack->isLoopControlVariable(D); 1771 if (Info.first || 1772 (VD && VD->hasLocalStorage() && 1773 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1774 (VD && DSAStack->isForceVarCapturing())) 1775 return VD ? VD : Info.second; 1776 DSAStackTy::DSAVarData DVarPrivate = 1777 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1778 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1779 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1780 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1781 [](OpenMPDirectiveKind) { return true; }, 1782 DSAStack->isClauseParsingMode()); 1783 if (DVarPrivate.CKind != OMPC_unknown) 1784 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1785 } 1786 return nullptr; 1787 } 1788 1789 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1790 unsigned Level) const { 1791 SmallVector<OpenMPDirectiveKind, 4> Regions; 1792 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1793 FunctionScopesIndex -= Regions.size(); 1794 } 1795 1796 void Sema::startOpenMPLoop() { 1797 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1798 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1799 DSAStack->loopInit(); 1800 } 1801 1802 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1803 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1804 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1805 if (DSAStack->getAssociatedLoops() > 0 && 1806 !DSAStack->isLoopStarted()) { 1807 DSAStack->resetPossibleLoopCounter(D); 1808 DSAStack->loopStart(); 1809 return true; 1810 } 1811 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1812 DSAStack->isLoopControlVariable(D).first) && 1813 !DSAStack->hasExplicitDSA( 1814 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1815 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1816 return true; 1817 } 1818 return DSAStack->hasExplicitDSA( 1819 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1820 (DSAStack->isClauseParsingMode() && 1821 DSAStack->getClauseParsingMode() == OMPC_private) || 1822 // Consider taskgroup reduction descriptor variable a private to avoid 1823 // possible capture in the region. 1824 (DSAStack->hasExplicitDirective( 1825 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1826 Level) && 1827 DSAStack->isTaskgroupReductionRef(D, Level)); 1828 } 1829 1830 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1831 unsigned Level) { 1832 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1833 D = getCanonicalDecl(D); 1834 OpenMPClauseKind OMPC = OMPC_unknown; 1835 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1836 const unsigned NewLevel = I - 1; 1837 if (DSAStack->hasExplicitDSA(D, 1838 [&OMPC](const OpenMPClauseKind K) { 1839 if (isOpenMPPrivate(K)) { 1840 OMPC = K; 1841 return true; 1842 } 1843 return false; 1844 }, 1845 NewLevel)) 1846 break; 1847 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1848 D, NewLevel, 1849 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1850 OpenMPClauseKind) { return true; })) { 1851 OMPC = OMPC_map; 1852 break; 1853 } 1854 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1855 NewLevel)) { 1856 OMPC = OMPC_map; 1857 if (D->getType()->isScalarType() && 1858 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1859 DefaultMapAttributes::DMA_tofrom_scalar) 1860 OMPC = OMPC_firstprivate; 1861 break; 1862 } 1863 } 1864 if (OMPC != OMPC_unknown) 1865 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1866 } 1867 1868 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1869 unsigned Level) const { 1870 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1871 // Return true if the current level is no longer enclosed in a target region. 1872 1873 const auto *VD = dyn_cast<VarDecl>(D); 1874 return VD && !VD->hasLocalStorage() && 1875 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1876 Level); 1877 } 1878 1879 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1880 1881 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1882 const DeclarationNameInfo &DirName, 1883 Scope *CurScope, SourceLocation Loc) { 1884 DSAStack->push(DKind, DirName, CurScope, Loc); 1885 PushExpressionEvaluationContext( 1886 ExpressionEvaluationContext::PotentiallyEvaluated); 1887 } 1888 1889 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1890 DSAStack->setClauseParsingMode(K); 1891 } 1892 1893 void Sema::EndOpenMPClause() { 1894 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1895 } 1896 1897 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1898 ArrayRef<OMPClause *> Clauses); 1899 1900 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1901 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1902 // A variable of class type (or array thereof) that appears in a lastprivate 1903 // clause requires an accessible, unambiguous default constructor for the 1904 // class type, unless the list item is also specified in a firstprivate 1905 // clause. 1906 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1907 for (OMPClause *C : D->clauses()) { 1908 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1909 SmallVector<Expr *, 8> PrivateCopies; 1910 for (Expr *DE : Clause->varlists()) { 1911 if (DE->isValueDependent() || DE->isTypeDependent()) { 1912 PrivateCopies.push_back(nullptr); 1913 continue; 1914 } 1915 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1916 auto *VD = cast<VarDecl>(DRE->getDecl()); 1917 QualType Type = VD->getType().getNonReferenceType(); 1918 const DSAStackTy::DSAVarData DVar = 1919 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1920 if (DVar.CKind == OMPC_lastprivate) { 1921 // Generate helper private variable and initialize it with the 1922 // default value. The address of the original variable is replaced 1923 // by the address of the new private variable in CodeGen. This new 1924 // variable is not added to IdResolver, so the code in the OpenMP 1925 // region uses original variable for proper diagnostics. 1926 VarDecl *VDPrivate = buildVarDecl( 1927 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1928 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1929 ActOnUninitializedDecl(VDPrivate); 1930 if (VDPrivate->isInvalidDecl()) { 1931 PrivateCopies.push_back(nullptr); 1932 continue; 1933 } 1934 PrivateCopies.push_back(buildDeclRefExpr( 1935 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1936 } else { 1937 // The variable is also a firstprivate, so initialization sequence 1938 // for private copy is generated already. 1939 PrivateCopies.push_back(nullptr); 1940 } 1941 } 1942 Clause->setPrivateCopies(PrivateCopies); 1943 } 1944 } 1945 // Check allocate clauses. 1946 if (!CurContext->isDependentContext()) 1947 checkAllocateClauses(*this, DSAStack, D->clauses()); 1948 } 1949 1950 DSAStack->pop(); 1951 DiscardCleanupsInEvaluationContext(); 1952 PopExpressionEvaluationContext(); 1953 } 1954 1955 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1956 Expr *NumIterations, Sema &SemaRef, 1957 Scope *S, DSAStackTy *Stack); 1958 1959 namespace { 1960 1961 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1962 private: 1963 Sema &SemaRef; 1964 1965 public: 1966 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1967 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1968 NamedDecl *ND = Candidate.getCorrectionDecl(); 1969 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1970 return VD->hasGlobalStorage() && 1971 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1972 SemaRef.getCurScope()); 1973 } 1974 return false; 1975 } 1976 1977 std::unique_ptr<CorrectionCandidateCallback> clone() override { 1978 return llvm::make_unique<VarDeclFilterCCC>(*this); 1979 } 1980 1981 }; 1982 1983 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 1984 private: 1985 Sema &SemaRef; 1986 1987 public: 1988 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1989 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1990 NamedDecl *ND = Candidate.getCorrectionDecl(); 1991 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 1992 isa<FunctionDecl>(ND))) { 1993 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1994 SemaRef.getCurScope()); 1995 } 1996 return false; 1997 } 1998 1999 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2000 return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this); 2001 } 2002 }; 2003 2004 } // namespace 2005 2006 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2007 CXXScopeSpec &ScopeSpec, 2008 const DeclarationNameInfo &Id, 2009 OpenMPDirectiveKind Kind) { 2010 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2011 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2012 2013 if (Lookup.isAmbiguous()) 2014 return ExprError(); 2015 2016 VarDecl *VD; 2017 if (!Lookup.isSingleResult()) { 2018 VarDeclFilterCCC CCC(*this); 2019 if (TypoCorrection Corrected = 2020 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2021 CTK_ErrorRecovery)) { 2022 diagnoseTypo(Corrected, 2023 PDiag(Lookup.empty() 2024 ? diag::err_undeclared_var_use_suggest 2025 : diag::err_omp_expected_var_arg_suggest) 2026 << Id.getName()); 2027 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2028 } else { 2029 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2030 : diag::err_omp_expected_var_arg) 2031 << Id.getName(); 2032 return ExprError(); 2033 } 2034 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2035 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2036 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2037 return ExprError(); 2038 } 2039 Lookup.suppressDiagnostics(); 2040 2041 // OpenMP [2.9.2, Syntax, C/C++] 2042 // Variables must be file-scope, namespace-scope, or static block-scope. 2043 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2044 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2045 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2046 bool IsDecl = 2047 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2048 Diag(VD->getLocation(), 2049 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2050 << VD; 2051 return ExprError(); 2052 } 2053 2054 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2055 NamedDecl *ND = CanonicalVD; 2056 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2057 // A threadprivate directive for file-scope variables must appear outside 2058 // any definition or declaration. 2059 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2060 !getCurLexicalContext()->isTranslationUnit()) { 2061 Diag(Id.getLoc(), diag::err_omp_var_scope) 2062 << getOpenMPDirectiveName(Kind) << VD; 2063 bool IsDecl = 2064 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2065 Diag(VD->getLocation(), 2066 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2067 << VD; 2068 return ExprError(); 2069 } 2070 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2071 // A threadprivate directive for static class member variables must appear 2072 // in the class definition, in the same scope in which the member 2073 // variables are declared. 2074 if (CanonicalVD->isStaticDataMember() && 2075 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2076 Diag(Id.getLoc(), diag::err_omp_var_scope) 2077 << getOpenMPDirectiveName(Kind) << VD; 2078 bool IsDecl = 2079 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2080 Diag(VD->getLocation(), 2081 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2082 << VD; 2083 return ExprError(); 2084 } 2085 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2086 // A threadprivate directive for namespace-scope variables must appear 2087 // outside any definition or declaration other than the namespace 2088 // definition itself. 2089 if (CanonicalVD->getDeclContext()->isNamespace() && 2090 (!getCurLexicalContext()->isFileContext() || 2091 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2092 Diag(Id.getLoc(), diag::err_omp_var_scope) 2093 << getOpenMPDirectiveName(Kind) << VD; 2094 bool IsDecl = 2095 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2096 Diag(VD->getLocation(), 2097 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2098 << VD; 2099 return ExprError(); 2100 } 2101 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2102 // A threadprivate directive for static block-scope variables must appear 2103 // in the scope of the variable and not in a nested scope. 2104 if (CanonicalVD->isLocalVarDecl() && CurScope && 2105 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2106 Diag(Id.getLoc(), diag::err_omp_var_scope) 2107 << getOpenMPDirectiveName(Kind) << VD; 2108 bool IsDecl = 2109 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2110 Diag(VD->getLocation(), 2111 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2112 << VD; 2113 return ExprError(); 2114 } 2115 2116 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2117 // A threadprivate directive must lexically precede all references to any 2118 // of the variables in its list. 2119 if (Kind == OMPD_threadprivate && VD->isUsed() && 2120 !DSAStack->isThreadPrivate(VD)) { 2121 Diag(Id.getLoc(), diag::err_omp_var_used) 2122 << getOpenMPDirectiveName(Kind) << VD; 2123 return ExprError(); 2124 } 2125 2126 QualType ExprType = VD->getType().getNonReferenceType(); 2127 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2128 SourceLocation(), VD, 2129 /*RefersToEnclosingVariableOrCapture=*/false, 2130 Id.getLoc(), ExprType, VK_LValue); 2131 } 2132 2133 Sema::DeclGroupPtrTy 2134 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2135 ArrayRef<Expr *> VarList) { 2136 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2137 CurContext->addDecl(D); 2138 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2139 } 2140 return nullptr; 2141 } 2142 2143 namespace { 2144 class LocalVarRefChecker final 2145 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2146 Sema &SemaRef; 2147 2148 public: 2149 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2150 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2151 if (VD->hasLocalStorage()) { 2152 SemaRef.Diag(E->getBeginLoc(), 2153 diag::err_omp_local_var_in_threadprivate_init) 2154 << E->getSourceRange(); 2155 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2156 << VD << VD->getSourceRange(); 2157 return true; 2158 } 2159 } 2160 return false; 2161 } 2162 bool VisitStmt(const Stmt *S) { 2163 for (const Stmt *Child : S->children()) { 2164 if (Child && Visit(Child)) 2165 return true; 2166 } 2167 return false; 2168 } 2169 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2170 }; 2171 } // namespace 2172 2173 OMPThreadPrivateDecl * 2174 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2175 SmallVector<Expr *, 8> Vars; 2176 for (Expr *RefExpr : VarList) { 2177 auto *DE = cast<DeclRefExpr>(RefExpr); 2178 auto *VD = cast<VarDecl>(DE->getDecl()); 2179 SourceLocation ILoc = DE->getExprLoc(); 2180 2181 // Mark variable as used. 2182 VD->setReferenced(); 2183 VD->markUsed(Context); 2184 2185 QualType QType = VD->getType(); 2186 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2187 // It will be analyzed later. 2188 Vars.push_back(DE); 2189 continue; 2190 } 2191 2192 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2193 // A threadprivate variable must not have an incomplete type. 2194 if (RequireCompleteType(ILoc, VD->getType(), 2195 diag::err_omp_threadprivate_incomplete_type)) { 2196 continue; 2197 } 2198 2199 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2200 // A threadprivate variable must not have a reference type. 2201 if (VD->getType()->isReferenceType()) { 2202 Diag(ILoc, diag::err_omp_ref_type_arg) 2203 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2204 bool IsDecl = 2205 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2206 Diag(VD->getLocation(), 2207 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2208 << VD; 2209 continue; 2210 } 2211 2212 // Check if this is a TLS variable. If TLS is not being supported, produce 2213 // the corresponding diagnostic. 2214 if ((VD->getTLSKind() != VarDecl::TLS_None && 2215 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2216 getLangOpts().OpenMPUseTLS && 2217 getASTContext().getTargetInfo().isTLSSupported())) || 2218 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2219 !VD->isLocalVarDecl())) { 2220 Diag(ILoc, diag::err_omp_var_thread_local) 2221 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2222 bool IsDecl = 2223 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2224 Diag(VD->getLocation(), 2225 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2226 << VD; 2227 continue; 2228 } 2229 2230 // Check if initial value of threadprivate variable reference variable with 2231 // local storage (it is not supported by runtime). 2232 if (const Expr *Init = VD->getAnyInitializer()) { 2233 LocalVarRefChecker Checker(*this); 2234 if (Checker.Visit(Init)) 2235 continue; 2236 } 2237 2238 Vars.push_back(RefExpr); 2239 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2240 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2241 Context, SourceRange(Loc, Loc))); 2242 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2243 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2244 } 2245 OMPThreadPrivateDecl *D = nullptr; 2246 if (!Vars.empty()) { 2247 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2248 Vars); 2249 D->setAccess(AS_public); 2250 } 2251 return D; 2252 } 2253 2254 static OMPAllocateDeclAttr::AllocatorTypeTy 2255 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2256 if (!Allocator) 2257 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2258 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2259 Allocator->isInstantiationDependent() || 2260 Allocator->containsUnexpandedParameterPack()) 2261 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2262 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2263 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2264 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2265 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2266 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2267 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2268 llvm::FoldingSetNodeID AEId, DAEId; 2269 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2270 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2271 if (AEId == DAEId) { 2272 AllocatorKindRes = AllocatorKind; 2273 break; 2274 } 2275 } 2276 return AllocatorKindRes; 2277 } 2278 2279 static bool checkPreviousOMPAllocateAttribute( 2280 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2281 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2282 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2283 return false; 2284 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2285 Expr *PrevAllocator = A->getAllocator(); 2286 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2287 getAllocatorKind(S, Stack, PrevAllocator); 2288 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2289 if (AllocatorsMatch && 2290 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2291 Allocator && PrevAllocator) { 2292 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2293 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2294 llvm::FoldingSetNodeID AEId, PAEId; 2295 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2296 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2297 AllocatorsMatch = AEId == PAEId; 2298 } 2299 if (!AllocatorsMatch) { 2300 SmallString<256> AllocatorBuffer; 2301 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2302 if (Allocator) 2303 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2304 SmallString<256> PrevAllocatorBuffer; 2305 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2306 if (PrevAllocator) 2307 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2308 S.getPrintingPolicy()); 2309 2310 SourceLocation AllocatorLoc = 2311 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2312 SourceRange AllocatorRange = 2313 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2314 SourceLocation PrevAllocatorLoc = 2315 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2316 SourceRange PrevAllocatorRange = 2317 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2318 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2319 << (Allocator ? 1 : 0) << AllocatorStream.str() 2320 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2321 << AllocatorRange; 2322 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2323 << PrevAllocatorRange; 2324 return true; 2325 } 2326 return false; 2327 } 2328 2329 static void 2330 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2331 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2332 Expr *Allocator, SourceRange SR) { 2333 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2334 return; 2335 if (Allocator && 2336 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2337 Allocator->isInstantiationDependent() || 2338 Allocator->containsUnexpandedParameterPack())) 2339 return; 2340 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2341 Allocator, SR); 2342 VD->addAttr(A); 2343 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2344 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2345 } 2346 2347 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2348 SourceLocation Loc, ArrayRef<Expr *> VarList, 2349 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2350 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2351 Expr *Allocator = nullptr; 2352 if (Clauses.empty()) { 2353 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2354 // allocate directives that appear in a target region must specify an 2355 // allocator clause unless a requires directive with the dynamic_allocators 2356 // clause is present in the same compilation unit. 2357 if (LangOpts.OpenMPIsDevice && 2358 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2359 targetDiag(Loc, diag::err_expected_allocator_clause); 2360 } else { 2361 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2362 } 2363 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2364 getAllocatorKind(*this, DSAStack, Allocator); 2365 SmallVector<Expr *, 8> Vars; 2366 for (Expr *RefExpr : VarList) { 2367 auto *DE = cast<DeclRefExpr>(RefExpr); 2368 auto *VD = cast<VarDecl>(DE->getDecl()); 2369 2370 // Check if this is a TLS variable or global register. 2371 if (VD->getTLSKind() != VarDecl::TLS_None || 2372 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2373 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2374 !VD->isLocalVarDecl())) 2375 continue; 2376 2377 // If the used several times in the allocate directive, the same allocator 2378 // must be used. 2379 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2380 AllocatorKind, Allocator)) 2381 continue; 2382 2383 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2384 // If a list item has a static storage type, the allocator expression in the 2385 // allocator clause must be a constant expression that evaluates to one of 2386 // the predefined memory allocator values. 2387 if (Allocator && VD->hasGlobalStorage()) { 2388 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2389 Diag(Allocator->getExprLoc(), 2390 diag::err_omp_expected_predefined_allocator) 2391 << Allocator->getSourceRange(); 2392 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2393 VarDecl::DeclarationOnly; 2394 Diag(VD->getLocation(), 2395 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2396 << VD; 2397 continue; 2398 } 2399 } 2400 2401 Vars.push_back(RefExpr); 2402 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2403 DE->getSourceRange()); 2404 } 2405 if (Vars.empty()) 2406 return nullptr; 2407 if (!Owner) 2408 Owner = getCurLexicalContext(); 2409 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2410 D->setAccess(AS_public); 2411 Owner->addDecl(D); 2412 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2413 } 2414 2415 Sema::DeclGroupPtrTy 2416 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2417 ArrayRef<OMPClause *> ClauseList) { 2418 OMPRequiresDecl *D = nullptr; 2419 if (!CurContext->isFileContext()) { 2420 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2421 } else { 2422 D = CheckOMPRequiresDecl(Loc, ClauseList); 2423 if (D) { 2424 CurContext->addDecl(D); 2425 DSAStack->addRequiresDecl(D); 2426 } 2427 } 2428 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2429 } 2430 2431 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2432 ArrayRef<OMPClause *> ClauseList) { 2433 /// For target specific clauses, the requires directive cannot be 2434 /// specified after the handling of any of the target regions in the 2435 /// current compilation unit. 2436 ArrayRef<SourceLocation> TargetLocations = 2437 DSAStack->getEncounteredTargetLocs(); 2438 if (!TargetLocations.empty()) { 2439 for (const OMPClause *CNew : ClauseList) { 2440 // Check if any of the requires clauses affect target regions. 2441 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2442 isa<OMPUnifiedAddressClause>(CNew) || 2443 isa<OMPReverseOffloadClause>(CNew) || 2444 isa<OMPDynamicAllocatorsClause>(CNew)) { 2445 Diag(Loc, diag::err_omp_target_before_requires) 2446 << getOpenMPClauseName(CNew->getClauseKind()); 2447 for (SourceLocation TargetLoc : TargetLocations) { 2448 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2449 } 2450 } 2451 } 2452 } 2453 2454 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2455 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2456 ClauseList); 2457 return nullptr; 2458 } 2459 2460 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2461 const ValueDecl *D, 2462 const DSAStackTy::DSAVarData &DVar, 2463 bool IsLoopIterVar = false) { 2464 if (DVar.RefExpr) { 2465 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2466 << getOpenMPClauseName(DVar.CKind); 2467 return; 2468 } 2469 enum { 2470 PDSA_StaticMemberShared, 2471 PDSA_StaticLocalVarShared, 2472 PDSA_LoopIterVarPrivate, 2473 PDSA_LoopIterVarLinear, 2474 PDSA_LoopIterVarLastprivate, 2475 PDSA_ConstVarShared, 2476 PDSA_GlobalVarShared, 2477 PDSA_TaskVarFirstprivate, 2478 PDSA_LocalVarPrivate, 2479 PDSA_Implicit 2480 } Reason = PDSA_Implicit; 2481 bool ReportHint = false; 2482 auto ReportLoc = D->getLocation(); 2483 auto *VD = dyn_cast<VarDecl>(D); 2484 if (IsLoopIterVar) { 2485 if (DVar.CKind == OMPC_private) 2486 Reason = PDSA_LoopIterVarPrivate; 2487 else if (DVar.CKind == OMPC_lastprivate) 2488 Reason = PDSA_LoopIterVarLastprivate; 2489 else 2490 Reason = PDSA_LoopIterVarLinear; 2491 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2492 DVar.CKind == OMPC_firstprivate) { 2493 Reason = PDSA_TaskVarFirstprivate; 2494 ReportLoc = DVar.ImplicitDSALoc; 2495 } else if (VD && VD->isStaticLocal()) 2496 Reason = PDSA_StaticLocalVarShared; 2497 else if (VD && VD->isStaticDataMember()) 2498 Reason = PDSA_StaticMemberShared; 2499 else if (VD && VD->isFileVarDecl()) 2500 Reason = PDSA_GlobalVarShared; 2501 else if (D->getType().isConstant(SemaRef.getASTContext())) 2502 Reason = PDSA_ConstVarShared; 2503 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2504 ReportHint = true; 2505 Reason = PDSA_LocalVarPrivate; 2506 } 2507 if (Reason != PDSA_Implicit) { 2508 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2509 << Reason << ReportHint 2510 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2511 } else if (DVar.ImplicitDSALoc.isValid()) { 2512 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2513 << getOpenMPClauseName(DVar.CKind); 2514 } 2515 } 2516 2517 namespace { 2518 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2519 DSAStackTy *Stack; 2520 Sema &SemaRef; 2521 bool ErrorFound = false; 2522 CapturedStmt *CS = nullptr; 2523 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2524 llvm::SmallVector<Expr *, 4> ImplicitMap; 2525 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2526 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2527 2528 void VisitSubCaptures(OMPExecutableDirective *S) { 2529 // Check implicitly captured variables. 2530 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2531 return; 2532 for (const CapturedStmt::Capture &Cap : 2533 S->getInnermostCapturedStmt()->captures()) { 2534 if (!Cap.capturesVariable()) 2535 continue; 2536 VarDecl *VD = Cap.getCapturedVar(); 2537 // Do not try to map the variable if it or its sub-component was mapped 2538 // already. 2539 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2540 Stack->checkMappableExprComponentListsForDecl( 2541 VD, /*CurrentRegionOnly=*/true, 2542 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2543 OpenMPClauseKind) { return true; })) 2544 continue; 2545 DeclRefExpr *DRE = buildDeclRefExpr( 2546 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2547 Cap.getLocation(), /*RefersToCapture=*/true); 2548 Visit(DRE); 2549 } 2550 } 2551 2552 public: 2553 void VisitDeclRefExpr(DeclRefExpr *E) { 2554 if (E->isTypeDependent() || E->isValueDependent() || 2555 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2556 return; 2557 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2558 VD = VD->getCanonicalDecl(); 2559 // Skip internally declared variables. 2560 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 2561 return; 2562 2563 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2564 // Check if the variable has explicit DSA set and stop analysis if it so. 2565 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2566 return; 2567 2568 // Skip internally declared static variables. 2569 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2570 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2571 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && 2572 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2573 return; 2574 2575 SourceLocation ELoc = E->getExprLoc(); 2576 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2577 // The default(none) clause requires that each variable that is referenced 2578 // in the construct, and does not have a predetermined data-sharing 2579 // attribute, must have its data-sharing attribute explicitly determined 2580 // by being listed in a data-sharing attribute clause. 2581 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2582 isImplicitOrExplicitTaskingRegion(DKind) && 2583 VarsWithInheritedDSA.count(VD) == 0) { 2584 VarsWithInheritedDSA[VD] = E; 2585 return; 2586 } 2587 2588 if (isOpenMPTargetExecutionDirective(DKind) && 2589 !Stack->isLoopControlVariable(VD).first) { 2590 if (!Stack->checkMappableExprComponentListsForDecl( 2591 VD, /*CurrentRegionOnly=*/true, 2592 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2593 StackComponents, 2594 OpenMPClauseKind) { 2595 // Variable is used if it has been marked as an array, array 2596 // section or the variable iself. 2597 return StackComponents.size() == 1 || 2598 std::all_of( 2599 std::next(StackComponents.rbegin()), 2600 StackComponents.rend(), 2601 [](const OMPClauseMappableExprCommon:: 2602 MappableComponent &MC) { 2603 return MC.getAssociatedDeclaration() == 2604 nullptr && 2605 (isa<OMPArraySectionExpr>( 2606 MC.getAssociatedExpression()) || 2607 isa<ArraySubscriptExpr>( 2608 MC.getAssociatedExpression())); 2609 }); 2610 })) { 2611 bool IsFirstprivate = false; 2612 // By default lambdas are captured as firstprivates. 2613 if (const auto *RD = 2614 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2615 IsFirstprivate = RD->isLambda(); 2616 IsFirstprivate = 2617 IsFirstprivate || 2618 (VD->getType().getNonReferenceType()->isScalarType() && 2619 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2620 if (IsFirstprivate) 2621 ImplicitFirstprivate.emplace_back(E); 2622 else 2623 ImplicitMap.emplace_back(E); 2624 return; 2625 } 2626 } 2627 2628 // OpenMP [2.9.3.6, Restrictions, p.2] 2629 // A list item that appears in a reduction clause of the innermost 2630 // enclosing worksharing or parallel construct may not be accessed in an 2631 // explicit task. 2632 DVar = Stack->hasInnermostDSA( 2633 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2634 [](OpenMPDirectiveKind K) { 2635 return isOpenMPParallelDirective(K) || 2636 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2637 }, 2638 /*FromParent=*/true); 2639 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2640 ErrorFound = true; 2641 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2642 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2643 return; 2644 } 2645 2646 // Define implicit data-sharing attributes for task. 2647 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2648 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2649 !Stack->isLoopControlVariable(VD).first) { 2650 ImplicitFirstprivate.push_back(E); 2651 return; 2652 } 2653 2654 // Store implicitly used globals with declare target link for parent 2655 // target. 2656 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2657 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2658 Stack->addToParentTargetRegionLinkGlobals(E); 2659 return; 2660 } 2661 } 2662 } 2663 void VisitMemberExpr(MemberExpr *E) { 2664 if (E->isTypeDependent() || E->isValueDependent() || 2665 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2666 return; 2667 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2668 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2669 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2670 if (!FD) 2671 return; 2672 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2673 // Check if the variable has explicit DSA set and stop analysis if it 2674 // so. 2675 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2676 return; 2677 2678 if (isOpenMPTargetExecutionDirective(DKind) && 2679 !Stack->isLoopControlVariable(FD).first && 2680 !Stack->checkMappableExprComponentListsForDecl( 2681 FD, /*CurrentRegionOnly=*/true, 2682 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2683 StackComponents, 2684 OpenMPClauseKind) { 2685 return isa<CXXThisExpr>( 2686 cast<MemberExpr>( 2687 StackComponents.back().getAssociatedExpression()) 2688 ->getBase() 2689 ->IgnoreParens()); 2690 })) { 2691 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2692 // A bit-field cannot appear in a map clause. 2693 // 2694 if (FD->isBitField()) 2695 return; 2696 2697 // Check to see if the member expression is referencing a class that 2698 // has already been explicitly mapped 2699 if (Stack->isClassPreviouslyMapped(TE->getType())) 2700 return; 2701 2702 ImplicitMap.emplace_back(E); 2703 return; 2704 } 2705 2706 SourceLocation ELoc = E->getExprLoc(); 2707 // OpenMP [2.9.3.6, Restrictions, p.2] 2708 // A list item that appears in a reduction clause of the innermost 2709 // enclosing worksharing or parallel construct may not be accessed in 2710 // an explicit task. 2711 DVar = Stack->hasInnermostDSA( 2712 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2713 [](OpenMPDirectiveKind K) { 2714 return isOpenMPParallelDirective(K) || 2715 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2716 }, 2717 /*FromParent=*/true); 2718 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2719 ErrorFound = true; 2720 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2721 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2722 return; 2723 } 2724 2725 // Define implicit data-sharing attributes for task. 2726 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2727 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2728 !Stack->isLoopControlVariable(FD).first) { 2729 // Check if there is a captured expression for the current field in the 2730 // region. Do not mark it as firstprivate unless there is no captured 2731 // expression. 2732 // TODO: try to make it firstprivate. 2733 if (DVar.CKind != OMPC_unknown) 2734 ImplicitFirstprivate.push_back(E); 2735 } 2736 return; 2737 } 2738 if (isOpenMPTargetExecutionDirective(DKind)) { 2739 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2740 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2741 /*NoDiagnose=*/true)) 2742 return; 2743 const auto *VD = cast<ValueDecl>( 2744 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2745 if (!Stack->checkMappableExprComponentListsForDecl( 2746 VD, /*CurrentRegionOnly=*/true, 2747 [&CurComponents]( 2748 OMPClauseMappableExprCommon::MappableExprComponentListRef 2749 StackComponents, 2750 OpenMPClauseKind) { 2751 auto CCI = CurComponents.rbegin(); 2752 auto CCE = CurComponents.rend(); 2753 for (const auto &SC : llvm::reverse(StackComponents)) { 2754 // Do both expressions have the same kind? 2755 if (CCI->getAssociatedExpression()->getStmtClass() != 2756 SC.getAssociatedExpression()->getStmtClass()) 2757 if (!(isa<OMPArraySectionExpr>( 2758 SC.getAssociatedExpression()) && 2759 isa<ArraySubscriptExpr>( 2760 CCI->getAssociatedExpression()))) 2761 return false; 2762 2763 const Decl *CCD = CCI->getAssociatedDeclaration(); 2764 const Decl *SCD = SC.getAssociatedDeclaration(); 2765 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2766 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2767 if (SCD != CCD) 2768 return false; 2769 std::advance(CCI, 1); 2770 if (CCI == CCE) 2771 break; 2772 } 2773 return true; 2774 })) { 2775 Visit(E->getBase()); 2776 } 2777 } else { 2778 Visit(E->getBase()); 2779 } 2780 } 2781 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2782 for (OMPClause *C : S->clauses()) { 2783 // Skip analysis of arguments of implicitly defined firstprivate clause 2784 // for task|target directives. 2785 // Skip analysis of arguments of implicitly defined map clause for target 2786 // directives. 2787 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2788 C->isImplicit())) { 2789 for (Stmt *CC : C->children()) { 2790 if (CC) 2791 Visit(CC); 2792 } 2793 } 2794 } 2795 // Check implicitly captured variables. 2796 VisitSubCaptures(S); 2797 } 2798 void VisitStmt(Stmt *S) { 2799 for (Stmt *C : S->children()) { 2800 if (C) { 2801 // Check implicitly captured variables in the task-based directives to 2802 // check if they must be firstprivatized. 2803 Visit(C); 2804 } 2805 } 2806 } 2807 2808 bool isErrorFound() const { return ErrorFound; } 2809 ArrayRef<Expr *> getImplicitFirstprivate() const { 2810 return ImplicitFirstprivate; 2811 } 2812 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2813 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2814 return VarsWithInheritedDSA; 2815 } 2816 2817 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2818 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2819 // Process declare target link variables for the target directives. 2820 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2821 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2822 Visit(E); 2823 } 2824 } 2825 }; 2826 } // namespace 2827 2828 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2829 switch (DKind) { 2830 case OMPD_parallel: 2831 case OMPD_parallel_for: 2832 case OMPD_parallel_for_simd: 2833 case OMPD_parallel_sections: 2834 case OMPD_teams: 2835 case OMPD_teams_distribute: 2836 case OMPD_teams_distribute_simd: { 2837 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2838 QualType KmpInt32PtrTy = 2839 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2840 Sema::CapturedParamNameType Params[] = { 2841 std::make_pair(".global_tid.", KmpInt32PtrTy), 2842 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2843 std::make_pair(StringRef(), QualType()) // __context with shared vars 2844 }; 2845 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2846 Params); 2847 break; 2848 } 2849 case OMPD_target_teams: 2850 case OMPD_target_parallel: 2851 case OMPD_target_parallel_for: 2852 case OMPD_target_parallel_for_simd: 2853 case OMPD_target_teams_distribute: 2854 case OMPD_target_teams_distribute_simd: { 2855 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2856 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2857 QualType KmpInt32PtrTy = 2858 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2859 QualType Args[] = {VoidPtrTy}; 2860 FunctionProtoType::ExtProtoInfo EPI; 2861 EPI.Variadic = true; 2862 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2863 Sema::CapturedParamNameType Params[] = { 2864 std::make_pair(".global_tid.", KmpInt32Ty), 2865 std::make_pair(".part_id.", KmpInt32PtrTy), 2866 std::make_pair(".privates.", VoidPtrTy), 2867 std::make_pair( 2868 ".copy_fn.", 2869 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2870 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2871 std::make_pair(StringRef(), QualType()) // __context with shared vars 2872 }; 2873 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2874 Params); 2875 // Mark this captured region as inlined, because we don't use outlined 2876 // function directly. 2877 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2878 AlwaysInlineAttr::CreateImplicit( 2879 Context, AlwaysInlineAttr::Keyword_forceinline)); 2880 Sema::CapturedParamNameType ParamsTarget[] = { 2881 std::make_pair(StringRef(), QualType()) // __context with shared vars 2882 }; 2883 // Start a captured region for 'target' with no implicit parameters. 2884 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2885 ParamsTarget); 2886 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2887 std::make_pair(".global_tid.", KmpInt32PtrTy), 2888 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2889 std::make_pair(StringRef(), QualType()) // __context with shared vars 2890 }; 2891 // Start a captured region for 'teams' or 'parallel'. Both regions have 2892 // the same implicit parameters. 2893 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2894 ParamsTeamsOrParallel); 2895 break; 2896 } 2897 case OMPD_target: 2898 case OMPD_target_simd: { 2899 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2900 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2901 QualType KmpInt32PtrTy = 2902 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2903 QualType Args[] = {VoidPtrTy}; 2904 FunctionProtoType::ExtProtoInfo EPI; 2905 EPI.Variadic = true; 2906 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2907 Sema::CapturedParamNameType Params[] = { 2908 std::make_pair(".global_tid.", KmpInt32Ty), 2909 std::make_pair(".part_id.", KmpInt32PtrTy), 2910 std::make_pair(".privates.", VoidPtrTy), 2911 std::make_pair( 2912 ".copy_fn.", 2913 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2914 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2915 std::make_pair(StringRef(), QualType()) // __context with shared vars 2916 }; 2917 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2918 Params); 2919 // Mark this captured region as inlined, because we don't use outlined 2920 // function directly. 2921 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2922 AlwaysInlineAttr::CreateImplicit( 2923 Context, AlwaysInlineAttr::Keyword_forceinline)); 2924 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2925 std::make_pair(StringRef(), QualType())); 2926 break; 2927 } 2928 case OMPD_simd: 2929 case OMPD_for: 2930 case OMPD_for_simd: 2931 case OMPD_sections: 2932 case OMPD_section: 2933 case OMPD_single: 2934 case OMPD_master: 2935 case OMPD_critical: 2936 case OMPD_taskgroup: 2937 case OMPD_distribute: 2938 case OMPD_distribute_simd: 2939 case OMPD_ordered: 2940 case OMPD_atomic: 2941 case OMPD_target_data: { 2942 Sema::CapturedParamNameType Params[] = { 2943 std::make_pair(StringRef(), QualType()) // __context with shared vars 2944 }; 2945 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2946 Params); 2947 break; 2948 } 2949 case OMPD_task: { 2950 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2951 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2952 QualType KmpInt32PtrTy = 2953 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2954 QualType Args[] = {VoidPtrTy}; 2955 FunctionProtoType::ExtProtoInfo EPI; 2956 EPI.Variadic = true; 2957 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2958 Sema::CapturedParamNameType Params[] = { 2959 std::make_pair(".global_tid.", KmpInt32Ty), 2960 std::make_pair(".part_id.", KmpInt32PtrTy), 2961 std::make_pair(".privates.", VoidPtrTy), 2962 std::make_pair( 2963 ".copy_fn.", 2964 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2965 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2966 std::make_pair(StringRef(), QualType()) // __context with shared vars 2967 }; 2968 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2969 Params); 2970 // Mark this captured region as inlined, because we don't use outlined 2971 // function directly. 2972 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2973 AlwaysInlineAttr::CreateImplicit( 2974 Context, AlwaysInlineAttr::Keyword_forceinline)); 2975 break; 2976 } 2977 case OMPD_taskloop: 2978 case OMPD_taskloop_simd: { 2979 QualType KmpInt32Ty = 2980 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 2981 .withConst(); 2982 QualType KmpUInt64Ty = 2983 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 2984 .withConst(); 2985 QualType KmpInt64Ty = 2986 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 2987 .withConst(); 2988 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2989 QualType KmpInt32PtrTy = 2990 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2991 QualType Args[] = {VoidPtrTy}; 2992 FunctionProtoType::ExtProtoInfo EPI; 2993 EPI.Variadic = true; 2994 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2995 Sema::CapturedParamNameType Params[] = { 2996 std::make_pair(".global_tid.", KmpInt32Ty), 2997 std::make_pair(".part_id.", KmpInt32PtrTy), 2998 std::make_pair(".privates.", VoidPtrTy), 2999 std::make_pair( 3000 ".copy_fn.", 3001 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3002 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3003 std::make_pair(".lb.", KmpUInt64Ty), 3004 std::make_pair(".ub.", KmpUInt64Ty), 3005 std::make_pair(".st.", KmpInt64Ty), 3006 std::make_pair(".liter.", KmpInt32Ty), 3007 std::make_pair(".reductions.", VoidPtrTy), 3008 std::make_pair(StringRef(), QualType()) // __context with shared vars 3009 }; 3010 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3011 Params); 3012 // Mark this captured region as inlined, because we don't use outlined 3013 // function directly. 3014 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3015 AlwaysInlineAttr::CreateImplicit( 3016 Context, AlwaysInlineAttr::Keyword_forceinline)); 3017 break; 3018 } 3019 case OMPD_distribute_parallel_for_simd: 3020 case OMPD_distribute_parallel_for: { 3021 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3022 QualType KmpInt32PtrTy = 3023 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3024 Sema::CapturedParamNameType Params[] = { 3025 std::make_pair(".global_tid.", KmpInt32PtrTy), 3026 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3027 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3028 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3029 std::make_pair(StringRef(), QualType()) // __context with shared vars 3030 }; 3031 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3032 Params); 3033 break; 3034 } 3035 case OMPD_target_teams_distribute_parallel_for: 3036 case OMPD_target_teams_distribute_parallel_for_simd: { 3037 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3038 QualType KmpInt32PtrTy = 3039 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3040 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3041 3042 QualType Args[] = {VoidPtrTy}; 3043 FunctionProtoType::ExtProtoInfo EPI; 3044 EPI.Variadic = true; 3045 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3046 Sema::CapturedParamNameType Params[] = { 3047 std::make_pair(".global_tid.", KmpInt32Ty), 3048 std::make_pair(".part_id.", KmpInt32PtrTy), 3049 std::make_pair(".privates.", VoidPtrTy), 3050 std::make_pair( 3051 ".copy_fn.", 3052 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3053 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3054 std::make_pair(StringRef(), QualType()) // __context with shared vars 3055 }; 3056 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3057 Params); 3058 // Mark this captured region as inlined, because we don't use outlined 3059 // function directly. 3060 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3061 AlwaysInlineAttr::CreateImplicit( 3062 Context, AlwaysInlineAttr::Keyword_forceinline)); 3063 Sema::CapturedParamNameType ParamsTarget[] = { 3064 std::make_pair(StringRef(), QualType()) // __context with shared vars 3065 }; 3066 // Start a captured region for 'target' with no implicit parameters. 3067 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3068 ParamsTarget); 3069 3070 Sema::CapturedParamNameType ParamsTeams[] = { 3071 std::make_pair(".global_tid.", KmpInt32PtrTy), 3072 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3073 std::make_pair(StringRef(), QualType()) // __context with shared vars 3074 }; 3075 // Start a captured region for 'target' with no implicit parameters. 3076 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3077 ParamsTeams); 3078 3079 Sema::CapturedParamNameType ParamsParallel[] = { 3080 std::make_pair(".global_tid.", KmpInt32PtrTy), 3081 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3082 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3083 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3084 std::make_pair(StringRef(), QualType()) // __context with shared vars 3085 }; 3086 // Start a captured region for 'teams' or 'parallel'. Both regions have 3087 // the same implicit parameters. 3088 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3089 ParamsParallel); 3090 break; 3091 } 3092 3093 case OMPD_teams_distribute_parallel_for: 3094 case OMPD_teams_distribute_parallel_for_simd: { 3095 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3096 QualType KmpInt32PtrTy = 3097 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3098 3099 Sema::CapturedParamNameType ParamsTeams[] = { 3100 std::make_pair(".global_tid.", KmpInt32PtrTy), 3101 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3102 std::make_pair(StringRef(), QualType()) // __context with shared vars 3103 }; 3104 // Start a captured region for 'target' with no implicit parameters. 3105 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3106 ParamsTeams); 3107 3108 Sema::CapturedParamNameType ParamsParallel[] = { 3109 std::make_pair(".global_tid.", KmpInt32PtrTy), 3110 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3111 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3112 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3113 std::make_pair(StringRef(), QualType()) // __context with shared vars 3114 }; 3115 // Start a captured region for 'teams' or 'parallel'. Both regions have 3116 // the same implicit parameters. 3117 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3118 ParamsParallel); 3119 break; 3120 } 3121 case OMPD_target_update: 3122 case OMPD_target_enter_data: 3123 case OMPD_target_exit_data: { 3124 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3125 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3126 QualType KmpInt32PtrTy = 3127 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3128 QualType Args[] = {VoidPtrTy}; 3129 FunctionProtoType::ExtProtoInfo EPI; 3130 EPI.Variadic = true; 3131 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3132 Sema::CapturedParamNameType Params[] = { 3133 std::make_pair(".global_tid.", KmpInt32Ty), 3134 std::make_pair(".part_id.", KmpInt32PtrTy), 3135 std::make_pair(".privates.", VoidPtrTy), 3136 std::make_pair( 3137 ".copy_fn.", 3138 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3139 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3140 std::make_pair(StringRef(), QualType()) // __context with shared vars 3141 }; 3142 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3143 Params); 3144 // Mark this captured region as inlined, because we don't use outlined 3145 // function directly. 3146 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3147 AlwaysInlineAttr::CreateImplicit( 3148 Context, AlwaysInlineAttr::Keyword_forceinline)); 3149 break; 3150 } 3151 case OMPD_threadprivate: 3152 case OMPD_allocate: 3153 case OMPD_taskyield: 3154 case OMPD_barrier: 3155 case OMPD_taskwait: 3156 case OMPD_cancellation_point: 3157 case OMPD_cancel: 3158 case OMPD_flush: 3159 case OMPD_declare_reduction: 3160 case OMPD_declare_mapper: 3161 case OMPD_declare_simd: 3162 case OMPD_declare_target: 3163 case OMPD_end_declare_target: 3164 case OMPD_requires: 3165 llvm_unreachable("OpenMP Directive is not allowed"); 3166 case OMPD_unknown: 3167 llvm_unreachable("Unknown OpenMP directive"); 3168 } 3169 } 3170 3171 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3172 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3173 getOpenMPCaptureRegions(CaptureRegions, DKind); 3174 return CaptureRegions.size(); 3175 } 3176 3177 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3178 Expr *CaptureExpr, bool WithInit, 3179 bool AsExpression) { 3180 assert(CaptureExpr); 3181 ASTContext &C = S.getASTContext(); 3182 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3183 QualType Ty = Init->getType(); 3184 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3185 if (S.getLangOpts().CPlusPlus) { 3186 Ty = C.getLValueReferenceType(Ty); 3187 } else { 3188 Ty = C.getPointerType(Ty); 3189 ExprResult Res = 3190 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3191 if (!Res.isUsable()) 3192 return nullptr; 3193 Init = Res.get(); 3194 } 3195 WithInit = true; 3196 } 3197 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3198 CaptureExpr->getBeginLoc()); 3199 if (!WithInit) 3200 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3201 S.CurContext->addHiddenDecl(CED); 3202 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3203 return CED; 3204 } 3205 3206 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3207 bool WithInit) { 3208 OMPCapturedExprDecl *CD; 3209 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3210 CD = cast<OMPCapturedExprDecl>(VD); 3211 else 3212 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3213 /*AsExpression=*/false); 3214 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3215 CaptureExpr->getExprLoc()); 3216 } 3217 3218 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3219 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3220 if (!Ref) { 3221 OMPCapturedExprDecl *CD = buildCaptureDecl( 3222 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3223 /*WithInit=*/true, /*AsExpression=*/true); 3224 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3225 CaptureExpr->getExprLoc()); 3226 } 3227 ExprResult Res = Ref; 3228 if (!S.getLangOpts().CPlusPlus && 3229 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3230 Ref->getType()->isPointerType()) { 3231 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3232 if (!Res.isUsable()) 3233 return ExprError(); 3234 } 3235 return S.DefaultLvalueConversion(Res.get()); 3236 } 3237 3238 namespace { 3239 // OpenMP directives parsed in this section are represented as a 3240 // CapturedStatement with an associated statement. If a syntax error 3241 // is detected during the parsing of the associated statement, the 3242 // compiler must abort processing and close the CapturedStatement. 3243 // 3244 // Combined directives such as 'target parallel' have more than one 3245 // nested CapturedStatements. This RAII ensures that we unwind out 3246 // of all the nested CapturedStatements when an error is found. 3247 class CaptureRegionUnwinderRAII { 3248 private: 3249 Sema &S; 3250 bool &ErrorFound; 3251 OpenMPDirectiveKind DKind = OMPD_unknown; 3252 3253 public: 3254 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3255 OpenMPDirectiveKind DKind) 3256 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3257 ~CaptureRegionUnwinderRAII() { 3258 if (ErrorFound) { 3259 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3260 while (--ThisCaptureLevel >= 0) 3261 S.ActOnCapturedRegionError(); 3262 } 3263 } 3264 }; 3265 } // namespace 3266 3267 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3268 ArrayRef<OMPClause *> Clauses) { 3269 bool ErrorFound = false; 3270 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3271 *this, ErrorFound, DSAStack->getCurrentDirective()); 3272 if (!S.isUsable()) { 3273 ErrorFound = true; 3274 return StmtError(); 3275 } 3276 3277 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3278 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3279 OMPOrderedClause *OC = nullptr; 3280 OMPScheduleClause *SC = nullptr; 3281 SmallVector<const OMPLinearClause *, 4> LCs; 3282 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3283 // This is required for proper codegen. 3284 for (OMPClause *Clause : Clauses) { 3285 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3286 Clause->getClauseKind() == OMPC_in_reduction) { 3287 // Capture taskgroup task_reduction descriptors inside the tasking regions 3288 // with the corresponding in_reduction items. 3289 auto *IRC = cast<OMPInReductionClause>(Clause); 3290 for (Expr *E : IRC->taskgroup_descriptors()) 3291 if (E) 3292 MarkDeclarationsReferencedInExpr(E); 3293 } 3294 if (isOpenMPPrivate(Clause->getClauseKind()) || 3295 Clause->getClauseKind() == OMPC_copyprivate || 3296 (getLangOpts().OpenMPUseTLS && 3297 getASTContext().getTargetInfo().isTLSSupported() && 3298 Clause->getClauseKind() == OMPC_copyin)) { 3299 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3300 // Mark all variables in private list clauses as used in inner region. 3301 for (Stmt *VarRef : Clause->children()) { 3302 if (auto *E = cast_or_null<Expr>(VarRef)) { 3303 MarkDeclarationsReferencedInExpr(E); 3304 } 3305 } 3306 DSAStack->setForceVarCapturing(/*V=*/false); 3307 } else if (CaptureRegions.size() > 1 || 3308 CaptureRegions.back() != OMPD_unknown) { 3309 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3310 PICs.push_back(C); 3311 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3312 if (Expr *E = C->getPostUpdateExpr()) 3313 MarkDeclarationsReferencedInExpr(E); 3314 } 3315 } 3316 if (Clause->getClauseKind() == OMPC_schedule) 3317 SC = cast<OMPScheduleClause>(Clause); 3318 else if (Clause->getClauseKind() == OMPC_ordered) 3319 OC = cast<OMPOrderedClause>(Clause); 3320 else if (Clause->getClauseKind() == OMPC_linear) 3321 LCs.push_back(cast<OMPLinearClause>(Clause)); 3322 } 3323 // OpenMP, 2.7.1 Loop Construct, Restrictions 3324 // The nonmonotonic modifier cannot be specified if an ordered clause is 3325 // specified. 3326 if (SC && 3327 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3328 SC->getSecondScheduleModifier() == 3329 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3330 OC) { 3331 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3332 ? SC->getFirstScheduleModifierLoc() 3333 : SC->getSecondScheduleModifierLoc(), 3334 diag::err_omp_schedule_nonmonotonic_ordered) 3335 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3336 ErrorFound = true; 3337 } 3338 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3339 for (const OMPLinearClause *C : LCs) { 3340 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3341 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3342 } 3343 ErrorFound = true; 3344 } 3345 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3346 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3347 OC->getNumForLoops()) { 3348 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3349 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3350 ErrorFound = true; 3351 } 3352 if (ErrorFound) { 3353 return StmtError(); 3354 } 3355 StmtResult SR = S; 3356 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3357 // Mark all variables in private list clauses as used in inner region. 3358 // Required for proper codegen of combined directives. 3359 // TODO: add processing for other clauses. 3360 if (ThisCaptureRegion != OMPD_unknown) { 3361 for (const clang::OMPClauseWithPreInit *C : PICs) { 3362 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3363 // Find the particular capture region for the clause if the 3364 // directive is a combined one with multiple capture regions. 3365 // If the directive is not a combined one, the capture region 3366 // associated with the clause is OMPD_unknown and is generated 3367 // only once. 3368 if (CaptureRegion == ThisCaptureRegion || 3369 CaptureRegion == OMPD_unknown) { 3370 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3371 for (Decl *D : DS->decls()) 3372 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3373 } 3374 } 3375 } 3376 } 3377 SR = ActOnCapturedRegionEnd(SR.get()); 3378 } 3379 return SR; 3380 } 3381 3382 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3383 OpenMPDirectiveKind CancelRegion, 3384 SourceLocation StartLoc) { 3385 // CancelRegion is only needed for cancel and cancellation_point. 3386 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3387 return false; 3388 3389 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3390 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3391 return false; 3392 3393 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3394 << getOpenMPDirectiveName(CancelRegion); 3395 return true; 3396 } 3397 3398 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3399 OpenMPDirectiveKind CurrentRegion, 3400 const DeclarationNameInfo &CurrentName, 3401 OpenMPDirectiveKind CancelRegion, 3402 SourceLocation StartLoc) { 3403 if (Stack->getCurScope()) { 3404 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3405 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3406 bool NestingProhibited = false; 3407 bool CloseNesting = true; 3408 bool OrphanSeen = false; 3409 enum { 3410 NoRecommend, 3411 ShouldBeInParallelRegion, 3412 ShouldBeInOrderedRegion, 3413 ShouldBeInTargetRegion, 3414 ShouldBeInTeamsRegion 3415 } Recommend = NoRecommend; 3416 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3417 // OpenMP [2.16, Nesting of Regions] 3418 // OpenMP constructs may not be nested inside a simd region. 3419 // OpenMP [2.8.1,simd Construct, Restrictions] 3420 // An ordered construct with the simd clause is the only OpenMP 3421 // construct that can appear in the simd region. 3422 // Allowing a SIMD construct nested in another SIMD construct is an 3423 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3424 // message. 3425 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3426 ? diag::err_omp_prohibited_region_simd 3427 : diag::warn_omp_nesting_simd); 3428 return CurrentRegion != OMPD_simd; 3429 } 3430 if (ParentRegion == OMPD_atomic) { 3431 // OpenMP [2.16, Nesting of Regions] 3432 // OpenMP constructs may not be nested inside an atomic region. 3433 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3434 return true; 3435 } 3436 if (CurrentRegion == OMPD_section) { 3437 // OpenMP [2.7.2, sections Construct, Restrictions] 3438 // Orphaned section directives are prohibited. That is, the section 3439 // directives must appear within the sections construct and must not be 3440 // encountered elsewhere in the sections region. 3441 if (ParentRegion != OMPD_sections && 3442 ParentRegion != OMPD_parallel_sections) { 3443 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3444 << (ParentRegion != OMPD_unknown) 3445 << getOpenMPDirectiveName(ParentRegion); 3446 return true; 3447 } 3448 return false; 3449 } 3450 // Allow some constructs (except teams and cancellation constructs) to be 3451 // orphaned (they could be used in functions, called from OpenMP regions 3452 // with the required preconditions). 3453 if (ParentRegion == OMPD_unknown && 3454 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3455 CurrentRegion != OMPD_cancellation_point && 3456 CurrentRegion != OMPD_cancel) 3457 return false; 3458 if (CurrentRegion == OMPD_cancellation_point || 3459 CurrentRegion == OMPD_cancel) { 3460 // OpenMP [2.16, Nesting of Regions] 3461 // A cancellation point construct for which construct-type-clause is 3462 // taskgroup must be nested inside a task construct. A cancellation 3463 // point construct for which construct-type-clause is not taskgroup must 3464 // be closely nested inside an OpenMP construct that matches the type 3465 // specified in construct-type-clause. 3466 // A cancel construct for which construct-type-clause is taskgroup must be 3467 // nested inside a task construct. A cancel construct for which 3468 // construct-type-clause is not taskgroup must be closely nested inside an 3469 // OpenMP construct that matches the type specified in 3470 // construct-type-clause. 3471 NestingProhibited = 3472 !((CancelRegion == OMPD_parallel && 3473 (ParentRegion == OMPD_parallel || 3474 ParentRegion == OMPD_target_parallel)) || 3475 (CancelRegion == OMPD_for && 3476 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3477 ParentRegion == OMPD_target_parallel_for || 3478 ParentRegion == OMPD_distribute_parallel_for || 3479 ParentRegion == OMPD_teams_distribute_parallel_for || 3480 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3481 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3482 (CancelRegion == OMPD_sections && 3483 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3484 ParentRegion == OMPD_parallel_sections))); 3485 OrphanSeen = ParentRegion == OMPD_unknown; 3486 } else if (CurrentRegion == OMPD_master) { 3487 // OpenMP [2.16, Nesting of Regions] 3488 // A master region may not be closely nested inside a worksharing, 3489 // atomic, or explicit task region. 3490 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3491 isOpenMPTaskingDirective(ParentRegion); 3492 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3493 // OpenMP [2.16, Nesting of Regions] 3494 // A critical region may not be nested (closely or otherwise) inside a 3495 // critical region with the same name. Note that this restriction is not 3496 // sufficient to prevent deadlock. 3497 SourceLocation PreviousCriticalLoc; 3498 bool DeadLock = Stack->hasDirective( 3499 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3500 const DeclarationNameInfo &DNI, 3501 SourceLocation Loc) { 3502 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3503 PreviousCriticalLoc = Loc; 3504 return true; 3505 } 3506 return false; 3507 }, 3508 false /* skip top directive */); 3509 if (DeadLock) { 3510 SemaRef.Diag(StartLoc, 3511 diag::err_omp_prohibited_region_critical_same_name) 3512 << CurrentName.getName(); 3513 if (PreviousCriticalLoc.isValid()) 3514 SemaRef.Diag(PreviousCriticalLoc, 3515 diag::note_omp_previous_critical_region); 3516 return true; 3517 } 3518 } else if (CurrentRegion == OMPD_barrier) { 3519 // OpenMP [2.16, Nesting of Regions] 3520 // A barrier region may not be closely nested inside a worksharing, 3521 // explicit task, critical, ordered, atomic, or master region. 3522 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3523 isOpenMPTaskingDirective(ParentRegion) || 3524 ParentRegion == OMPD_master || 3525 ParentRegion == OMPD_critical || 3526 ParentRegion == OMPD_ordered; 3527 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3528 !isOpenMPParallelDirective(CurrentRegion) && 3529 !isOpenMPTeamsDirective(CurrentRegion)) { 3530 // OpenMP [2.16, Nesting of Regions] 3531 // A worksharing region may not be closely nested inside a worksharing, 3532 // explicit task, critical, ordered, atomic, or master region. 3533 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3534 isOpenMPTaskingDirective(ParentRegion) || 3535 ParentRegion == OMPD_master || 3536 ParentRegion == OMPD_critical || 3537 ParentRegion == OMPD_ordered; 3538 Recommend = ShouldBeInParallelRegion; 3539 } else if (CurrentRegion == OMPD_ordered) { 3540 // OpenMP [2.16, Nesting of Regions] 3541 // An ordered region may not be closely nested inside a critical, 3542 // atomic, or explicit task region. 3543 // An ordered region must be closely nested inside a loop region (or 3544 // parallel loop region) with an ordered clause. 3545 // OpenMP [2.8.1,simd Construct, Restrictions] 3546 // An ordered construct with the simd clause is the only OpenMP construct 3547 // that can appear in the simd region. 3548 NestingProhibited = ParentRegion == OMPD_critical || 3549 isOpenMPTaskingDirective(ParentRegion) || 3550 !(isOpenMPSimdDirective(ParentRegion) || 3551 Stack->isParentOrderedRegion()); 3552 Recommend = ShouldBeInOrderedRegion; 3553 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3554 // OpenMP [2.16, Nesting of Regions] 3555 // If specified, a teams construct must be contained within a target 3556 // construct. 3557 NestingProhibited = ParentRegion != OMPD_target; 3558 OrphanSeen = ParentRegion == OMPD_unknown; 3559 Recommend = ShouldBeInTargetRegion; 3560 } 3561 if (!NestingProhibited && 3562 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3563 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3564 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3565 // OpenMP [2.16, Nesting of Regions] 3566 // distribute, parallel, parallel sections, parallel workshare, and the 3567 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3568 // constructs that can be closely nested in the teams region. 3569 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3570 !isOpenMPDistributeDirective(CurrentRegion); 3571 Recommend = ShouldBeInParallelRegion; 3572 } 3573 if (!NestingProhibited && 3574 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3575 // OpenMP 4.5 [2.17 Nesting of Regions] 3576 // The region associated with the distribute construct must be strictly 3577 // nested inside a teams region 3578 NestingProhibited = 3579 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3580 Recommend = ShouldBeInTeamsRegion; 3581 } 3582 if (!NestingProhibited && 3583 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3584 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3585 // OpenMP 4.5 [2.17 Nesting of Regions] 3586 // If a target, target update, target data, target enter data, or 3587 // target exit data construct is encountered during execution of a 3588 // target region, the behavior is unspecified. 3589 NestingProhibited = Stack->hasDirective( 3590 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3591 SourceLocation) { 3592 if (isOpenMPTargetExecutionDirective(K)) { 3593 OffendingRegion = K; 3594 return true; 3595 } 3596 return false; 3597 }, 3598 false /* don't skip top directive */); 3599 CloseNesting = false; 3600 } 3601 if (NestingProhibited) { 3602 if (OrphanSeen) { 3603 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3604 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3605 } else { 3606 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3607 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3608 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3609 } 3610 return true; 3611 } 3612 } 3613 return false; 3614 } 3615 3616 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3617 ArrayRef<OMPClause *> Clauses, 3618 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3619 bool ErrorFound = false; 3620 unsigned NamedModifiersNumber = 0; 3621 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3622 OMPD_unknown + 1); 3623 SmallVector<SourceLocation, 4> NameModifierLoc; 3624 for (const OMPClause *C : Clauses) { 3625 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3626 // At most one if clause without a directive-name-modifier can appear on 3627 // the directive. 3628 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3629 if (FoundNameModifiers[CurNM]) { 3630 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3631 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3632 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3633 ErrorFound = true; 3634 } else if (CurNM != OMPD_unknown) { 3635 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3636 ++NamedModifiersNumber; 3637 } 3638 FoundNameModifiers[CurNM] = IC; 3639 if (CurNM == OMPD_unknown) 3640 continue; 3641 // Check if the specified name modifier is allowed for the current 3642 // directive. 3643 // At most one if clause with the particular directive-name-modifier can 3644 // appear on the directive. 3645 bool MatchFound = false; 3646 for (auto NM : AllowedNameModifiers) { 3647 if (CurNM == NM) { 3648 MatchFound = true; 3649 break; 3650 } 3651 } 3652 if (!MatchFound) { 3653 S.Diag(IC->getNameModifierLoc(), 3654 diag::err_omp_wrong_if_directive_name_modifier) 3655 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3656 ErrorFound = true; 3657 } 3658 } 3659 } 3660 // If any if clause on the directive includes a directive-name-modifier then 3661 // all if clauses on the directive must include a directive-name-modifier. 3662 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3663 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3664 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3665 diag::err_omp_no_more_if_clause); 3666 } else { 3667 std::string Values; 3668 std::string Sep(", "); 3669 unsigned AllowedCnt = 0; 3670 unsigned TotalAllowedNum = 3671 AllowedNameModifiers.size() - NamedModifiersNumber; 3672 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3673 ++Cnt) { 3674 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3675 if (!FoundNameModifiers[NM]) { 3676 Values += "'"; 3677 Values += getOpenMPDirectiveName(NM); 3678 Values += "'"; 3679 if (AllowedCnt + 2 == TotalAllowedNum) 3680 Values += " or "; 3681 else if (AllowedCnt + 1 != TotalAllowedNum) 3682 Values += Sep; 3683 ++AllowedCnt; 3684 } 3685 } 3686 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3687 diag::err_omp_unnamed_if_clause) 3688 << (TotalAllowedNum > 1) << Values; 3689 } 3690 for (SourceLocation Loc : NameModifierLoc) { 3691 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3692 } 3693 ErrorFound = true; 3694 } 3695 return ErrorFound; 3696 } 3697 3698 static std::pair<ValueDecl *, bool> 3699 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3700 SourceRange &ERange, bool AllowArraySection = false) { 3701 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3702 RefExpr->containsUnexpandedParameterPack()) 3703 return std::make_pair(nullptr, true); 3704 3705 // OpenMP [3.1, C/C++] 3706 // A list item is a variable name. 3707 // OpenMP [2.9.3.3, Restrictions, p.1] 3708 // A variable that is part of another variable (as an array or 3709 // structure element) cannot appear in a private clause. 3710 RefExpr = RefExpr->IgnoreParens(); 3711 enum { 3712 NoArrayExpr = -1, 3713 ArraySubscript = 0, 3714 OMPArraySection = 1 3715 } IsArrayExpr = NoArrayExpr; 3716 if (AllowArraySection) { 3717 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3718 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3719 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3720 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3721 RefExpr = Base; 3722 IsArrayExpr = ArraySubscript; 3723 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3724 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3725 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3726 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3727 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3728 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3729 RefExpr = Base; 3730 IsArrayExpr = OMPArraySection; 3731 } 3732 } 3733 ELoc = RefExpr->getExprLoc(); 3734 ERange = RefExpr->getSourceRange(); 3735 RefExpr = RefExpr->IgnoreParenImpCasts(); 3736 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3737 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3738 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3739 (S.getCurrentThisType().isNull() || !ME || 3740 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3741 !isa<FieldDecl>(ME->getMemberDecl()))) { 3742 if (IsArrayExpr != NoArrayExpr) { 3743 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3744 << ERange; 3745 } else { 3746 S.Diag(ELoc, 3747 AllowArraySection 3748 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3749 : diag::err_omp_expected_var_name_member_expr) 3750 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3751 } 3752 return std::make_pair(nullptr, false); 3753 } 3754 return std::make_pair( 3755 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3756 } 3757 3758 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3759 ArrayRef<OMPClause *> Clauses) { 3760 assert(!S.CurContext->isDependentContext() && 3761 "Expected non-dependent context."); 3762 auto AllocateRange = 3763 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3764 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3765 DeclToCopy; 3766 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3767 return isOpenMPPrivate(C->getClauseKind()); 3768 }); 3769 for (OMPClause *Cl : PrivateRange) { 3770 MutableArrayRef<Expr *>::iterator I, It, Et; 3771 if (Cl->getClauseKind() == OMPC_private) { 3772 auto *PC = cast<OMPPrivateClause>(Cl); 3773 I = PC->private_copies().begin(); 3774 It = PC->varlist_begin(); 3775 Et = PC->varlist_end(); 3776 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3777 auto *PC = cast<OMPFirstprivateClause>(Cl); 3778 I = PC->private_copies().begin(); 3779 It = PC->varlist_begin(); 3780 Et = PC->varlist_end(); 3781 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3782 auto *PC = cast<OMPLastprivateClause>(Cl); 3783 I = PC->private_copies().begin(); 3784 It = PC->varlist_begin(); 3785 Et = PC->varlist_end(); 3786 } else if (Cl->getClauseKind() == OMPC_linear) { 3787 auto *PC = cast<OMPLinearClause>(Cl); 3788 I = PC->privates().begin(); 3789 It = PC->varlist_begin(); 3790 Et = PC->varlist_end(); 3791 } else if (Cl->getClauseKind() == OMPC_reduction) { 3792 auto *PC = cast<OMPReductionClause>(Cl); 3793 I = PC->privates().begin(); 3794 It = PC->varlist_begin(); 3795 Et = PC->varlist_end(); 3796 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3797 auto *PC = cast<OMPTaskReductionClause>(Cl); 3798 I = PC->privates().begin(); 3799 It = PC->varlist_begin(); 3800 Et = PC->varlist_end(); 3801 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3802 auto *PC = cast<OMPInReductionClause>(Cl); 3803 I = PC->privates().begin(); 3804 It = PC->varlist_begin(); 3805 Et = PC->varlist_end(); 3806 } else { 3807 llvm_unreachable("Expected private clause."); 3808 } 3809 for (Expr *E : llvm::make_range(It, Et)) { 3810 if (!*I) { 3811 ++I; 3812 continue; 3813 } 3814 SourceLocation ELoc; 3815 SourceRange ERange; 3816 Expr *SimpleRefExpr = E; 3817 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3818 /*AllowArraySection=*/true); 3819 DeclToCopy.try_emplace(Res.first, 3820 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3821 ++I; 3822 } 3823 } 3824 for (OMPClause *C : AllocateRange) { 3825 auto *AC = cast<OMPAllocateClause>(C); 3826 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3827 getAllocatorKind(S, Stack, AC->getAllocator()); 3828 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3829 // For task, taskloop or target directives, allocation requests to memory 3830 // allocators with the trait access set to thread result in unspecified 3831 // behavior. 3832 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3833 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3834 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3835 S.Diag(AC->getAllocator()->getExprLoc(), 3836 diag::warn_omp_allocate_thread_on_task_target_directive) 3837 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3838 } 3839 for (Expr *E : AC->varlists()) { 3840 SourceLocation ELoc; 3841 SourceRange ERange; 3842 Expr *SimpleRefExpr = E; 3843 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3844 ValueDecl *VD = Res.first; 3845 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3846 if (!isOpenMPPrivate(Data.CKind)) { 3847 S.Diag(E->getExprLoc(), 3848 diag::err_omp_expected_private_copy_for_allocate); 3849 continue; 3850 } 3851 VarDecl *PrivateVD = DeclToCopy[VD]; 3852 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3853 AllocatorKind, AC->getAllocator())) 3854 continue; 3855 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3856 E->getSourceRange()); 3857 } 3858 } 3859 } 3860 3861 StmtResult Sema::ActOnOpenMPExecutableDirective( 3862 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3863 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3864 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3865 StmtResult Res = StmtError(); 3866 // First check CancelRegion which is then used in checkNestingOfRegions. 3867 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3868 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3869 StartLoc)) 3870 return StmtError(); 3871 3872 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3873 VarsWithInheritedDSAType VarsWithInheritedDSA; 3874 bool ErrorFound = false; 3875 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3876 if (AStmt && !CurContext->isDependentContext()) { 3877 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3878 3879 // Check default data sharing attributes for referenced variables. 3880 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3881 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3882 Stmt *S = AStmt; 3883 while (--ThisCaptureLevel >= 0) 3884 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3885 DSAChecker.Visit(S); 3886 if (DSAChecker.isErrorFound()) 3887 return StmtError(); 3888 // Generate list of implicitly defined firstprivate variables. 3889 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3890 3891 SmallVector<Expr *, 4> ImplicitFirstprivates( 3892 DSAChecker.getImplicitFirstprivate().begin(), 3893 DSAChecker.getImplicitFirstprivate().end()); 3894 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3895 DSAChecker.getImplicitMap().end()); 3896 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3897 for (OMPClause *C : Clauses) { 3898 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3899 for (Expr *E : IRC->taskgroup_descriptors()) 3900 if (E) 3901 ImplicitFirstprivates.emplace_back(E); 3902 } 3903 } 3904 if (!ImplicitFirstprivates.empty()) { 3905 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3906 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3907 SourceLocation())) { 3908 ClausesWithImplicit.push_back(Implicit); 3909 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3910 ImplicitFirstprivates.size(); 3911 } else { 3912 ErrorFound = true; 3913 } 3914 } 3915 if (!ImplicitMaps.empty()) { 3916 CXXScopeSpec MapperIdScopeSpec; 3917 DeclarationNameInfo MapperId; 3918 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3919 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 3920 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 3921 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 3922 ClausesWithImplicit.emplace_back(Implicit); 3923 ErrorFound |= 3924 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3925 } else { 3926 ErrorFound = true; 3927 } 3928 } 3929 } 3930 3931 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3932 switch (Kind) { 3933 case OMPD_parallel: 3934 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3935 EndLoc); 3936 AllowedNameModifiers.push_back(OMPD_parallel); 3937 break; 3938 case OMPD_simd: 3939 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3940 VarsWithInheritedDSA); 3941 break; 3942 case OMPD_for: 3943 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3944 VarsWithInheritedDSA); 3945 break; 3946 case OMPD_for_simd: 3947 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3948 EndLoc, VarsWithInheritedDSA); 3949 break; 3950 case OMPD_sections: 3951 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3952 EndLoc); 3953 break; 3954 case OMPD_section: 3955 assert(ClausesWithImplicit.empty() && 3956 "No clauses are allowed for 'omp section' directive"); 3957 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3958 break; 3959 case OMPD_single: 3960 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3961 EndLoc); 3962 break; 3963 case OMPD_master: 3964 assert(ClausesWithImplicit.empty() && 3965 "No clauses are allowed for 'omp master' directive"); 3966 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3967 break; 3968 case OMPD_critical: 3969 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3970 StartLoc, EndLoc); 3971 break; 3972 case OMPD_parallel_for: 3973 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3974 EndLoc, VarsWithInheritedDSA); 3975 AllowedNameModifiers.push_back(OMPD_parallel); 3976 break; 3977 case OMPD_parallel_for_simd: 3978 Res = ActOnOpenMPParallelForSimdDirective( 3979 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3980 AllowedNameModifiers.push_back(OMPD_parallel); 3981 break; 3982 case OMPD_parallel_sections: 3983 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3984 StartLoc, EndLoc); 3985 AllowedNameModifiers.push_back(OMPD_parallel); 3986 break; 3987 case OMPD_task: 3988 Res = 3989 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3990 AllowedNameModifiers.push_back(OMPD_task); 3991 break; 3992 case OMPD_taskyield: 3993 assert(ClausesWithImplicit.empty() && 3994 "No clauses are allowed for 'omp taskyield' directive"); 3995 assert(AStmt == nullptr && 3996 "No associated statement allowed for 'omp taskyield' directive"); 3997 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3998 break; 3999 case OMPD_barrier: 4000 assert(ClausesWithImplicit.empty() && 4001 "No clauses are allowed for 'omp barrier' directive"); 4002 assert(AStmt == nullptr && 4003 "No associated statement allowed for 'omp barrier' directive"); 4004 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4005 break; 4006 case OMPD_taskwait: 4007 assert(ClausesWithImplicit.empty() && 4008 "No clauses are allowed for 'omp taskwait' directive"); 4009 assert(AStmt == nullptr && 4010 "No associated statement allowed for 'omp taskwait' directive"); 4011 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4012 break; 4013 case OMPD_taskgroup: 4014 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4015 EndLoc); 4016 break; 4017 case OMPD_flush: 4018 assert(AStmt == nullptr && 4019 "No associated statement allowed for 'omp flush' directive"); 4020 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4021 break; 4022 case OMPD_ordered: 4023 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4024 EndLoc); 4025 break; 4026 case OMPD_atomic: 4027 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4028 EndLoc); 4029 break; 4030 case OMPD_teams: 4031 Res = 4032 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4033 break; 4034 case OMPD_target: 4035 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4036 EndLoc); 4037 AllowedNameModifiers.push_back(OMPD_target); 4038 break; 4039 case OMPD_target_parallel: 4040 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4041 StartLoc, EndLoc); 4042 AllowedNameModifiers.push_back(OMPD_target); 4043 AllowedNameModifiers.push_back(OMPD_parallel); 4044 break; 4045 case OMPD_target_parallel_for: 4046 Res = ActOnOpenMPTargetParallelForDirective( 4047 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4048 AllowedNameModifiers.push_back(OMPD_target); 4049 AllowedNameModifiers.push_back(OMPD_parallel); 4050 break; 4051 case OMPD_cancellation_point: 4052 assert(ClausesWithImplicit.empty() && 4053 "No clauses are allowed for 'omp cancellation point' directive"); 4054 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4055 "cancellation point' directive"); 4056 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4057 break; 4058 case OMPD_cancel: 4059 assert(AStmt == nullptr && 4060 "No associated statement allowed for 'omp cancel' directive"); 4061 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4062 CancelRegion); 4063 AllowedNameModifiers.push_back(OMPD_cancel); 4064 break; 4065 case OMPD_target_data: 4066 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4067 EndLoc); 4068 AllowedNameModifiers.push_back(OMPD_target_data); 4069 break; 4070 case OMPD_target_enter_data: 4071 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4072 EndLoc, AStmt); 4073 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4074 break; 4075 case OMPD_target_exit_data: 4076 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4077 EndLoc, AStmt); 4078 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4079 break; 4080 case OMPD_taskloop: 4081 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4082 EndLoc, VarsWithInheritedDSA); 4083 AllowedNameModifiers.push_back(OMPD_taskloop); 4084 break; 4085 case OMPD_taskloop_simd: 4086 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4087 EndLoc, VarsWithInheritedDSA); 4088 AllowedNameModifiers.push_back(OMPD_taskloop); 4089 break; 4090 case OMPD_distribute: 4091 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4092 EndLoc, VarsWithInheritedDSA); 4093 break; 4094 case OMPD_target_update: 4095 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4096 EndLoc, AStmt); 4097 AllowedNameModifiers.push_back(OMPD_target_update); 4098 break; 4099 case OMPD_distribute_parallel_for: 4100 Res = ActOnOpenMPDistributeParallelForDirective( 4101 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4102 AllowedNameModifiers.push_back(OMPD_parallel); 4103 break; 4104 case OMPD_distribute_parallel_for_simd: 4105 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4106 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4107 AllowedNameModifiers.push_back(OMPD_parallel); 4108 break; 4109 case OMPD_distribute_simd: 4110 Res = ActOnOpenMPDistributeSimdDirective( 4111 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4112 break; 4113 case OMPD_target_parallel_for_simd: 4114 Res = ActOnOpenMPTargetParallelForSimdDirective( 4115 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4116 AllowedNameModifiers.push_back(OMPD_target); 4117 AllowedNameModifiers.push_back(OMPD_parallel); 4118 break; 4119 case OMPD_target_simd: 4120 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4121 EndLoc, VarsWithInheritedDSA); 4122 AllowedNameModifiers.push_back(OMPD_target); 4123 break; 4124 case OMPD_teams_distribute: 4125 Res = ActOnOpenMPTeamsDistributeDirective( 4126 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4127 break; 4128 case OMPD_teams_distribute_simd: 4129 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4130 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4131 break; 4132 case OMPD_teams_distribute_parallel_for_simd: 4133 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4134 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4135 AllowedNameModifiers.push_back(OMPD_parallel); 4136 break; 4137 case OMPD_teams_distribute_parallel_for: 4138 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4139 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4140 AllowedNameModifiers.push_back(OMPD_parallel); 4141 break; 4142 case OMPD_target_teams: 4143 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4144 EndLoc); 4145 AllowedNameModifiers.push_back(OMPD_target); 4146 break; 4147 case OMPD_target_teams_distribute: 4148 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4149 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4150 AllowedNameModifiers.push_back(OMPD_target); 4151 break; 4152 case OMPD_target_teams_distribute_parallel_for: 4153 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4154 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4155 AllowedNameModifiers.push_back(OMPD_target); 4156 AllowedNameModifiers.push_back(OMPD_parallel); 4157 break; 4158 case OMPD_target_teams_distribute_parallel_for_simd: 4159 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4160 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4161 AllowedNameModifiers.push_back(OMPD_target); 4162 AllowedNameModifiers.push_back(OMPD_parallel); 4163 break; 4164 case OMPD_target_teams_distribute_simd: 4165 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4166 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4167 AllowedNameModifiers.push_back(OMPD_target); 4168 break; 4169 case OMPD_declare_target: 4170 case OMPD_end_declare_target: 4171 case OMPD_threadprivate: 4172 case OMPD_allocate: 4173 case OMPD_declare_reduction: 4174 case OMPD_declare_mapper: 4175 case OMPD_declare_simd: 4176 case OMPD_requires: 4177 llvm_unreachable("OpenMP Directive is not allowed"); 4178 case OMPD_unknown: 4179 llvm_unreachable("Unknown OpenMP directive"); 4180 } 4181 4182 ErrorFound = Res.isInvalid() || ErrorFound; 4183 4184 for (const auto &P : VarsWithInheritedDSA) { 4185 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4186 << P.first << P.second->getSourceRange(); 4187 } 4188 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 4189 4190 if (!AllowedNameModifiers.empty()) 4191 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4192 ErrorFound; 4193 4194 if (ErrorFound) 4195 return StmtError(); 4196 4197 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4198 Res.getAs<OMPExecutableDirective>() 4199 ->getStructuredBlock() 4200 ->setIsOMPStructuredBlock(true); 4201 } 4202 4203 if (!CurContext->isDependentContext() && 4204 isOpenMPTargetExecutionDirective(Kind) && 4205 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4206 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4207 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4208 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4209 // Register target to DSA Stack. 4210 DSAStack->addTargetDirLocation(StartLoc); 4211 } 4212 4213 return Res; 4214 } 4215 4216 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4217 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4218 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4219 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4220 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4221 assert(Aligneds.size() == Alignments.size()); 4222 assert(Linears.size() == LinModifiers.size()); 4223 assert(Linears.size() == Steps.size()); 4224 if (!DG || DG.get().isNull()) 4225 return DeclGroupPtrTy(); 4226 4227 if (!DG.get().isSingleDecl()) { 4228 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4229 return DG; 4230 } 4231 Decl *ADecl = DG.get().getSingleDecl(); 4232 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4233 ADecl = FTD->getTemplatedDecl(); 4234 4235 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4236 if (!FD) { 4237 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4238 return DeclGroupPtrTy(); 4239 } 4240 4241 // OpenMP [2.8.2, declare simd construct, Description] 4242 // The parameter of the simdlen clause must be a constant positive integer 4243 // expression. 4244 ExprResult SL; 4245 if (Simdlen) 4246 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4247 // OpenMP [2.8.2, declare simd construct, Description] 4248 // The special this pointer can be used as if was one of the arguments to the 4249 // function in any of the linear, aligned, or uniform clauses. 4250 // The uniform clause declares one or more arguments to have an invariant 4251 // value for all concurrent invocations of the function in the execution of a 4252 // single SIMD loop. 4253 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4254 const Expr *UniformedLinearThis = nullptr; 4255 for (const Expr *E : Uniforms) { 4256 E = E->IgnoreParenImpCasts(); 4257 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4258 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4259 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4260 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4261 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4262 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4263 continue; 4264 } 4265 if (isa<CXXThisExpr>(E)) { 4266 UniformedLinearThis = E; 4267 continue; 4268 } 4269 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4270 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4271 } 4272 // OpenMP [2.8.2, declare simd construct, Description] 4273 // The aligned clause declares that the object to which each list item points 4274 // is aligned to the number of bytes expressed in the optional parameter of 4275 // the aligned clause. 4276 // The special this pointer can be used as if was one of the arguments to the 4277 // function in any of the linear, aligned, or uniform clauses. 4278 // The type of list items appearing in the aligned clause must be array, 4279 // pointer, reference to array, or reference to pointer. 4280 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4281 const Expr *AlignedThis = nullptr; 4282 for (const Expr *E : Aligneds) { 4283 E = E->IgnoreParenImpCasts(); 4284 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4285 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4286 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4287 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4288 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4289 ->getCanonicalDecl() == CanonPVD) { 4290 // OpenMP [2.8.1, simd construct, Restrictions] 4291 // A list-item cannot appear in more than one aligned clause. 4292 if (AlignedArgs.count(CanonPVD) > 0) { 4293 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4294 << 1 << E->getSourceRange(); 4295 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4296 diag::note_omp_explicit_dsa) 4297 << getOpenMPClauseName(OMPC_aligned); 4298 continue; 4299 } 4300 AlignedArgs[CanonPVD] = E; 4301 QualType QTy = PVD->getType() 4302 .getNonReferenceType() 4303 .getUnqualifiedType() 4304 .getCanonicalType(); 4305 const Type *Ty = QTy.getTypePtrOrNull(); 4306 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4307 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4308 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4309 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4310 } 4311 continue; 4312 } 4313 } 4314 if (isa<CXXThisExpr>(E)) { 4315 if (AlignedThis) { 4316 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4317 << 2 << E->getSourceRange(); 4318 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4319 << getOpenMPClauseName(OMPC_aligned); 4320 } 4321 AlignedThis = E; 4322 continue; 4323 } 4324 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4325 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4326 } 4327 // The optional parameter of the aligned clause, alignment, must be a constant 4328 // positive integer expression. If no optional parameter is specified, 4329 // implementation-defined default alignments for SIMD instructions on the 4330 // target platforms are assumed. 4331 SmallVector<const Expr *, 4> NewAligns; 4332 for (Expr *E : Alignments) { 4333 ExprResult Align; 4334 if (E) 4335 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4336 NewAligns.push_back(Align.get()); 4337 } 4338 // OpenMP [2.8.2, declare simd construct, Description] 4339 // The linear clause declares one or more list items to be private to a SIMD 4340 // lane and to have a linear relationship with respect to the iteration space 4341 // of a loop. 4342 // The special this pointer can be used as if was one of the arguments to the 4343 // function in any of the linear, aligned, or uniform clauses. 4344 // When a linear-step expression is specified in a linear clause it must be 4345 // either a constant integer expression or an integer-typed parameter that is 4346 // specified in a uniform clause on the directive. 4347 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4348 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4349 auto MI = LinModifiers.begin(); 4350 for (const Expr *E : Linears) { 4351 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4352 ++MI; 4353 E = E->IgnoreParenImpCasts(); 4354 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4355 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4356 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4357 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4358 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4359 ->getCanonicalDecl() == CanonPVD) { 4360 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4361 // A list-item cannot appear in more than one linear clause. 4362 if (LinearArgs.count(CanonPVD) > 0) { 4363 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4364 << getOpenMPClauseName(OMPC_linear) 4365 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4366 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4367 diag::note_omp_explicit_dsa) 4368 << getOpenMPClauseName(OMPC_linear); 4369 continue; 4370 } 4371 // Each argument can appear in at most one uniform or linear clause. 4372 if (UniformedArgs.count(CanonPVD) > 0) { 4373 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4374 << getOpenMPClauseName(OMPC_linear) 4375 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4376 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4377 diag::note_omp_explicit_dsa) 4378 << getOpenMPClauseName(OMPC_uniform); 4379 continue; 4380 } 4381 LinearArgs[CanonPVD] = E; 4382 if (E->isValueDependent() || E->isTypeDependent() || 4383 E->isInstantiationDependent() || 4384 E->containsUnexpandedParameterPack()) 4385 continue; 4386 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4387 PVD->getOriginalType()); 4388 continue; 4389 } 4390 } 4391 if (isa<CXXThisExpr>(E)) { 4392 if (UniformedLinearThis) { 4393 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4394 << getOpenMPClauseName(OMPC_linear) 4395 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4396 << E->getSourceRange(); 4397 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4398 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4399 : OMPC_linear); 4400 continue; 4401 } 4402 UniformedLinearThis = E; 4403 if (E->isValueDependent() || E->isTypeDependent() || 4404 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4405 continue; 4406 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4407 E->getType()); 4408 continue; 4409 } 4410 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4411 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4412 } 4413 Expr *Step = nullptr; 4414 Expr *NewStep = nullptr; 4415 SmallVector<Expr *, 4> NewSteps; 4416 for (Expr *E : Steps) { 4417 // Skip the same step expression, it was checked already. 4418 if (Step == E || !E) { 4419 NewSteps.push_back(E ? NewStep : nullptr); 4420 continue; 4421 } 4422 Step = E; 4423 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4424 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4425 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4426 if (UniformedArgs.count(CanonPVD) == 0) { 4427 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4428 << Step->getSourceRange(); 4429 } else if (E->isValueDependent() || E->isTypeDependent() || 4430 E->isInstantiationDependent() || 4431 E->containsUnexpandedParameterPack() || 4432 CanonPVD->getType()->hasIntegerRepresentation()) { 4433 NewSteps.push_back(Step); 4434 } else { 4435 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4436 << Step->getSourceRange(); 4437 } 4438 continue; 4439 } 4440 NewStep = Step; 4441 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4442 !Step->isInstantiationDependent() && 4443 !Step->containsUnexpandedParameterPack()) { 4444 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4445 .get(); 4446 if (NewStep) 4447 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4448 } 4449 NewSteps.push_back(NewStep); 4450 } 4451 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4452 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4453 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4454 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4455 const_cast<Expr **>(Linears.data()), Linears.size(), 4456 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4457 NewSteps.data(), NewSteps.size(), SR); 4458 ADecl->addAttr(NewAttr); 4459 return ConvertDeclToDeclGroup(ADecl); 4460 } 4461 4462 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4463 Stmt *AStmt, 4464 SourceLocation StartLoc, 4465 SourceLocation EndLoc) { 4466 if (!AStmt) 4467 return StmtError(); 4468 4469 auto *CS = cast<CapturedStmt>(AStmt); 4470 // 1.2.2 OpenMP Language Terminology 4471 // Structured block - An executable statement with a single entry at the 4472 // top and a single exit at the bottom. 4473 // The point of exit cannot be a branch out of the structured block. 4474 // longjmp() and throw() must not violate the entry/exit criteria. 4475 CS->getCapturedDecl()->setNothrow(); 4476 4477 setFunctionHasBranchProtectedScope(); 4478 4479 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4480 DSAStack->isCancelRegion()); 4481 } 4482 4483 namespace { 4484 /// Helper class for checking canonical form of the OpenMP loops and 4485 /// extracting iteration space of each loop in the loop nest, that will be used 4486 /// for IR generation. 4487 class OpenMPIterationSpaceChecker { 4488 /// Reference to Sema. 4489 Sema &SemaRef; 4490 /// Data-sharing stack. 4491 DSAStackTy &Stack; 4492 /// A location for diagnostics (when there is no some better location). 4493 SourceLocation DefaultLoc; 4494 /// A location for diagnostics (when increment is not compatible). 4495 SourceLocation ConditionLoc; 4496 /// A source location for referring to loop init later. 4497 SourceRange InitSrcRange; 4498 /// A source location for referring to condition later. 4499 SourceRange ConditionSrcRange; 4500 /// A source location for referring to increment later. 4501 SourceRange IncrementSrcRange; 4502 /// Loop variable. 4503 ValueDecl *LCDecl = nullptr; 4504 /// Reference to loop variable. 4505 Expr *LCRef = nullptr; 4506 /// Lower bound (initializer for the var). 4507 Expr *LB = nullptr; 4508 /// Upper bound. 4509 Expr *UB = nullptr; 4510 /// Loop step (increment). 4511 Expr *Step = nullptr; 4512 /// This flag is true when condition is one of: 4513 /// Var < UB 4514 /// Var <= UB 4515 /// UB > Var 4516 /// UB >= Var 4517 /// This will have no value when the condition is != 4518 llvm::Optional<bool> TestIsLessOp; 4519 /// This flag is true when condition is strict ( < or > ). 4520 bool TestIsStrictOp = false; 4521 /// This flag is true when step is subtracted on each iteration. 4522 bool SubtractStep = false; 4523 /// The outer loop counter this loop depends on (if any). 4524 const ValueDecl *DepDecl = nullptr; 4525 /// Contains number of loop (starts from 1) on which loop counter init 4526 /// expression of this loop depends on. 4527 Optional<unsigned> InitDependOnLC; 4528 /// Contains number of loop (starts from 1) on which loop counter condition 4529 /// expression of this loop depends on. 4530 Optional<unsigned> CondDependOnLC; 4531 /// Checks if the provide statement depends on the loop counter. 4532 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4533 4534 public: 4535 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4536 SourceLocation DefaultLoc) 4537 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4538 ConditionLoc(DefaultLoc) {} 4539 /// Check init-expr for canonical loop form and save loop counter 4540 /// variable - #Var and its initialization value - #LB. 4541 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4542 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4543 /// for less/greater and for strict/non-strict comparison. 4544 bool checkAndSetCond(Expr *S); 4545 /// Check incr-expr for canonical loop form and return true if it 4546 /// does not conform, otherwise save loop step (#Step). 4547 bool checkAndSetInc(Expr *S); 4548 /// Return the loop counter variable. 4549 ValueDecl *getLoopDecl() const { return LCDecl; } 4550 /// Return the reference expression to loop counter variable. 4551 Expr *getLoopDeclRefExpr() const { return LCRef; } 4552 /// Source range of the loop init. 4553 SourceRange getInitSrcRange() const { return InitSrcRange; } 4554 /// Source range of the loop condition. 4555 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4556 /// Source range of the loop increment. 4557 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4558 /// True if the step should be subtracted. 4559 bool shouldSubtractStep() const { return SubtractStep; } 4560 /// True, if the compare operator is strict (<, > or !=). 4561 bool isStrictTestOp() const { return TestIsStrictOp; } 4562 /// Build the expression to calculate the number of iterations. 4563 Expr *buildNumIterations( 4564 Scope *S, const bool LimitedType, 4565 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4566 /// Build the precondition expression for the loops. 4567 Expr * 4568 buildPreCond(Scope *S, Expr *Cond, 4569 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4570 /// Build reference expression to the counter be used for codegen. 4571 DeclRefExpr * 4572 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4573 DSAStackTy &DSA) const; 4574 /// Build reference expression to the private counter be used for 4575 /// codegen. 4576 Expr *buildPrivateCounterVar() const; 4577 /// Build initialization of the counter be used for codegen. 4578 Expr *buildCounterInit() const; 4579 /// Build step of the counter be used for codegen. 4580 Expr *buildCounterStep() const; 4581 /// Build loop data with counter value for depend clauses in ordered 4582 /// directives. 4583 Expr * 4584 buildOrderedLoopData(Scope *S, Expr *Counter, 4585 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4586 SourceLocation Loc, Expr *Inc = nullptr, 4587 OverloadedOperatorKind OOK = OO_Amp); 4588 /// Return true if any expression is dependent. 4589 bool dependent() const; 4590 4591 private: 4592 /// Check the right-hand side of an assignment in the increment 4593 /// expression. 4594 bool checkAndSetIncRHS(Expr *RHS); 4595 /// Helper to set loop counter variable and its initializer. 4596 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4597 bool EmitDiags); 4598 /// Helper to set upper bound. 4599 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4600 SourceRange SR, SourceLocation SL); 4601 /// Helper to set loop increment. 4602 bool setStep(Expr *NewStep, bool Subtract); 4603 }; 4604 4605 bool OpenMPIterationSpaceChecker::dependent() const { 4606 if (!LCDecl) { 4607 assert(!LB && !UB && !Step); 4608 return false; 4609 } 4610 return LCDecl->getType()->isDependentType() || 4611 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4612 (Step && Step->isValueDependent()); 4613 } 4614 4615 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4616 Expr *NewLCRefExpr, 4617 Expr *NewLB, bool EmitDiags) { 4618 // State consistency checking to ensure correct usage. 4619 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4620 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4621 if (!NewLCDecl || !NewLB) 4622 return true; 4623 LCDecl = getCanonicalDecl(NewLCDecl); 4624 LCRef = NewLCRefExpr; 4625 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4626 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4627 if ((Ctor->isCopyOrMoveConstructor() || 4628 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4629 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4630 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4631 LB = NewLB; 4632 if (EmitDiags) 4633 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4634 return false; 4635 } 4636 4637 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4638 llvm::Optional<bool> LessOp, 4639 bool StrictOp, SourceRange SR, 4640 SourceLocation SL) { 4641 // State consistency checking to ensure correct usage. 4642 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4643 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4644 if (!NewUB) 4645 return true; 4646 UB = NewUB; 4647 if (LessOp) 4648 TestIsLessOp = LessOp; 4649 TestIsStrictOp = StrictOp; 4650 ConditionSrcRange = SR; 4651 ConditionLoc = SL; 4652 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4653 return false; 4654 } 4655 4656 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4657 // State consistency checking to ensure correct usage. 4658 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4659 if (!NewStep) 4660 return true; 4661 if (!NewStep->isValueDependent()) { 4662 // Check that the step is integer expression. 4663 SourceLocation StepLoc = NewStep->getBeginLoc(); 4664 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4665 StepLoc, getExprAsWritten(NewStep)); 4666 if (Val.isInvalid()) 4667 return true; 4668 NewStep = Val.get(); 4669 4670 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4671 // If test-expr is of form var relational-op b and relational-op is < or 4672 // <= then incr-expr must cause var to increase on each iteration of the 4673 // loop. If test-expr is of form var relational-op b and relational-op is 4674 // > or >= then incr-expr must cause var to decrease on each iteration of 4675 // the loop. 4676 // If test-expr is of form b relational-op var and relational-op is < or 4677 // <= then incr-expr must cause var to decrease on each iteration of the 4678 // loop. If test-expr is of form b relational-op var and relational-op is 4679 // > or >= then incr-expr must cause var to increase on each iteration of 4680 // the loop. 4681 llvm::APSInt Result; 4682 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4683 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4684 bool IsConstNeg = 4685 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4686 bool IsConstPos = 4687 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4688 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4689 4690 // != with increment is treated as <; != with decrement is treated as > 4691 if (!TestIsLessOp.hasValue()) 4692 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4693 if (UB && (IsConstZero || 4694 (TestIsLessOp.getValue() ? 4695 (IsConstNeg || (IsUnsigned && Subtract)) : 4696 (IsConstPos || (IsUnsigned && !Subtract))))) { 4697 SemaRef.Diag(NewStep->getExprLoc(), 4698 diag::err_omp_loop_incr_not_compatible) 4699 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4700 SemaRef.Diag(ConditionLoc, 4701 diag::note_omp_loop_cond_requres_compatible_incr) 4702 << TestIsLessOp.getValue() << ConditionSrcRange; 4703 return true; 4704 } 4705 if (TestIsLessOp.getValue() == Subtract) { 4706 NewStep = 4707 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4708 .get(); 4709 Subtract = !Subtract; 4710 } 4711 } 4712 4713 Step = NewStep; 4714 SubtractStep = Subtract; 4715 return false; 4716 } 4717 4718 namespace { 4719 /// Checker for the non-rectangular loops. Checks if the initializer or 4720 /// condition expression references loop counter variable. 4721 class LoopCounterRefChecker final 4722 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 4723 Sema &SemaRef; 4724 DSAStackTy &Stack; 4725 const ValueDecl *CurLCDecl = nullptr; 4726 const ValueDecl *DepDecl = nullptr; 4727 const ValueDecl *PrevDepDecl = nullptr; 4728 bool IsInitializer = true; 4729 unsigned BaseLoopId = 0; 4730 bool checkDecl(const Expr *E, const ValueDecl *VD) { 4731 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 4732 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 4733 << (IsInitializer ? 0 : 1); 4734 return false; 4735 } 4736 const auto &&Data = Stack.isLoopControlVariable(VD); 4737 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 4738 // The type of the loop iterator on which we depend may not have a random 4739 // access iterator type. 4740 if (Data.first && VD->getType()->isRecordType()) { 4741 SmallString<128> Name; 4742 llvm::raw_svector_ostream OS(Name); 4743 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4744 /*Qualified=*/true); 4745 SemaRef.Diag(E->getExprLoc(), 4746 diag::err_omp_wrong_dependency_iterator_type) 4747 << OS.str(); 4748 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 4749 return false; 4750 } 4751 if (Data.first && 4752 (DepDecl || (PrevDepDecl && 4753 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 4754 if (!DepDecl && PrevDepDecl) 4755 DepDecl = PrevDepDecl; 4756 SmallString<128> Name; 4757 llvm::raw_svector_ostream OS(Name); 4758 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4759 /*Qualified=*/true); 4760 SemaRef.Diag(E->getExprLoc(), 4761 diag::err_omp_invariant_or_linear_dependency) 4762 << OS.str(); 4763 return false; 4764 } 4765 if (Data.first) { 4766 DepDecl = VD; 4767 BaseLoopId = Data.first; 4768 } 4769 return Data.first; 4770 } 4771 4772 public: 4773 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4774 const ValueDecl *VD = E->getDecl(); 4775 if (isa<VarDecl>(VD)) 4776 return checkDecl(E, VD); 4777 return false; 4778 } 4779 bool VisitMemberExpr(const MemberExpr *E) { 4780 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 4781 const ValueDecl *VD = E->getMemberDecl(); 4782 return checkDecl(E, VD); 4783 } 4784 return false; 4785 } 4786 bool VisitStmt(const Stmt *S) { 4787 bool Res = true; 4788 for (const Stmt *Child : S->children()) 4789 Res = Child && Visit(Child) && Res; 4790 return Res; 4791 } 4792 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 4793 const ValueDecl *CurLCDecl, bool IsInitializer, 4794 const ValueDecl *PrevDepDecl = nullptr) 4795 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 4796 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 4797 unsigned getBaseLoopId() const { 4798 assert(CurLCDecl && "Expected loop dependency."); 4799 return BaseLoopId; 4800 } 4801 const ValueDecl *getDepDecl() const { 4802 assert(CurLCDecl && "Expected loop dependency."); 4803 return DepDecl; 4804 } 4805 }; 4806 } // namespace 4807 4808 Optional<unsigned> 4809 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 4810 bool IsInitializer) { 4811 // Check for the non-rectangular loops. 4812 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 4813 DepDecl); 4814 if (LoopStmtChecker.Visit(S)) { 4815 DepDecl = LoopStmtChecker.getDepDecl(); 4816 return LoopStmtChecker.getBaseLoopId(); 4817 } 4818 return llvm::None; 4819 } 4820 4821 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 4822 // Check init-expr for canonical loop form and save loop counter 4823 // variable - #Var and its initialization value - #LB. 4824 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 4825 // var = lb 4826 // integer-type var = lb 4827 // random-access-iterator-type var = lb 4828 // pointer-type var = lb 4829 // 4830 if (!S) { 4831 if (EmitDiags) { 4832 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 4833 } 4834 return true; 4835 } 4836 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4837 if (!ExprTemp->cleanupsHaveSideEffects()) 4838 S = ExprTemp->getSubExpr(); 4839 4840 InitSrcRange = S->getSourceRange(); 4841 if (Expr *E = dyn_cast<Expr>(S)) 4842 S = E->IgnoreParens(); 4843 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4844 if (BO->getOpcode() == BO_Assign) { 4845 Expr *LHS = BO->getLHS()->IgnoreParens(); 4846 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4847 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4848 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4849 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 4850 EmitDiags); 4851 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 4852 } 4853 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4854 if (ME->isArrow() && 4855 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4856 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 4857 EmitDiags); 4858 } 4859 } 4860 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4861 if (DS->isSingleDecl()) { 4862 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4863 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4864 // Accept non-canonical init form here but emit ext. warning. 4865 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4866 SemaRef.Diag(S->getBeginLoc(), 4867 diag::ext_omp_loop_not_canonical_init) 4868 << S->getSourceRange(); 4869 return setLCDeclAndLB( 4870 Var, 4871 buildDeclRefExpr(SemaRef, Var, 4872 Var->getType().getNonReferenceType(), 4873 DS->getBeginLoc()), 4874 Var->getInit(), EmitDiags); 4875 } 4876 } 4877 } 4878 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4879 if (CE->getOperator() == OO_Equal) { 4880 Expr *LHS = CE->getArg(0); 4881 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4882 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4883 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4884 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 4885 EmitDiags); 4886 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 4887 } 4888 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4889 if (ME->isArrow() && 4890 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4891 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 4892 EmitDiags); 4893 } 4894 } 4895 } 4896 4897 if (dependent() || SemaRef.CurContext->isDependentContext()) 4898 return false; 4899 if (EmitDiags) { 4900 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 4901 << S->getSourceRange(); 4902 } 4903 return true; 4904 } 4905 4906 /// Ignore parenthesizes, implicit casts, copy constructor and return the 4907 /// variable (which may be the loop variable) if possible. 4908 static const ValueDecl *getInitLCDecl(const Expr *E) { 4909 if (!E) 4910 return nullptr; 4911 E = getExprAsWritten(E); 4912 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 4913 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4914 if ((Ctor->isCopyOrMoveConstructor() || 4915 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4916 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4917 E = CE->getArg(0)->IgnoreParenImpCasts(); 4918 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 4919 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 4920 return getCanonicalDecl(VD); 4921 } 4922 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 4923 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4924 return getCanonicalDecl(ME->getMemberDecl()); 4925 return nullptr; 4926 } 4927 4928 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 4929 // Check test-expr for canonical form, save upper-bound UB, flags for 4930 // less/greater and for strict/non-strict comparison. 4931 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4932 // var relational-op b 4933 // b relational-op var 4934 // 4935 if (!S) { 4936 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 4937 return true; 4938 } 4939 S = getExprAsWritten(S); 4940 SourceLocation CondLoc = S->getBeginLoc(); 4941 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4942 if (BO->isRelationalOp()) { 4943 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4944 return setUB(BO->getRHS(), 4945 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4946 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4947 BO->getSourceRange(), BO->getOperatorLoc()); 4948 if (getInitLCDecl(BO->getRHS()) == LCDecl) 4949 return setUB(BO->getLHS(), 4950 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4951 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4952 BO->getSourceRange(), BO->getOperatorLoc()); 4953 } else if (BO->getOpcode() == BO_NE) 4954 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 4955 BO->getRHS() : BO->getLHS(), 4956 /*LessOp=*/llvm::None, 4957 /*StrictOp=*/true, 4958 BO->getSourceRange(), BO->getOperatorLoc()); 4959 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4960 if (CE->getNumArgs() == 2) { 4961 auto Op = CE->getOperator(); 4962 switch (Op) { 4963 case OO_Greater: 4964 case OO_GreaterEqual: 4965 case OO_Less: 4966 case OO_LessEqual: 4967 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4968 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4969 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4970 CE->getOperatorLoc()); 4971 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 4972 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4973 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4974 CE->getOperatorLoc()); 4975 break; 4976 case OO_ExclaimEqual: 4977 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 4978 CE->getArg(1) : CE->getArg(0), 4979 /*LessOp=*/llvm::None, 4980 /*StrictOp=*/true, 4981 CE->getSourceRange(), 4982 CE->getOperatorLoc()); 4983 break; 4984 default: 4985 break; 4986 } 4987 } 4988 } 4989 if (dependent() || SemaRef.CurContext->isDependentContext()) 4990 return false; 4991 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4992 << S->getSourceRange() << LCDecl; 4993 return true; 4994 } 4995 4996 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 4997 // RHS of canonical loop form increment can be: 4998 // var + incr 4999 // incr + var 5000 // var - incr 5001 // 5002 RHS = RHS->IgnoreParenImpCasts(); 5003 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5004 if (BO->isAdditiveOp()) { 5005 bool IsAdd = BO->getOpcode() == BO_Add; 5006 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5007 return setStep(BO->getRHS(), !IsAdd); 5008 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5009 return setStep(BO->getLHS(), /*Subtract=*/false); 5010 } 5011 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5012 bool IsAdd = CE->getOperator() == OO_Plus; 5013 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5014 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5015 return setStep(CE->getArg(1), !IsAdd); 5016 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5017 return setStep(CE->getArg(0), /*Subtract=*/false); 5018 } 5019 } 5020 if (dependent() || SemaRef.CurContext->isDependentContext()) 5021 return false; 5022 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5023 << RHS->getSourceRange() << LCDecl; 5024 return true; 5025 } 5026 5027 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5028 // Check incr-expr for canonical loop form and return true if it 5029 // does not conform. 5030 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5031 // ++var 5032 // var++ 5033 // --var 5034 // var-- 5035 // var += incr 5036 // var -= incr 5037 // var = var + incr 5038 // var = incr + var 5039 // var = var - incr 5040 // 5041 if (!S) { 5042 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5043 return true; 5044 } 5045 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5046 if (!ExprTemp->cleanupsHaveSideEffects()) 5047 S = ExprTemp->getSubExpr(); 5048 5049 IncrementSrcRange = S->getSourceRange(); 5050 S = S->IgnoreParens(); 5051 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5052 if (UO->isIncrementDecrementOp() && 5053 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5054 return setStep(SemaRef 5055 .ActOnIntegerConstant(UO->getBeginLoc(), 5056 (UO->isDecrementOp() ? -1 : 1)) 5057 .get(), 5058 /*Subtract=*/false); 5059 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5060 switch (BO->getOpcode()) { 5061 case BO_AddAssign: 5062 case BO_SubAssign: 5063 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5064 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5065 break; 5066 case BO_Assign: 5067 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5068 return checkAndSetIncRHS(BO->getRHS()); 5069 break; 5070 default: 5071 break; 5072 } 5073 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5074 switch (CE->getOperator()) { 5075 case OO_PlusPlus: 5076 case OO_MinusMinus: 5077 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5078 return setStep(SemaRef 5079 .ActOnIntegerConstant( 5080 CE->getBeginLoc(), 5081 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5082 .get(), 5083 /*Subtract=*/false); 5084 break; 5085 case OO_PlusEqual: 5086 case OO_MinusEqual: 5087 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5088 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5089 break; 5090 case OO_Equal: 5091 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5092 return checkAndSetIncRHS(CE->getArg(1)); 5093 break; 5094 default: 5095 break; 5096 } 5097 } 5098 if (dependent() || SemaRef.CurContext->isDependentContext()) 5099 return false; 5100 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5101 << S->getSourceRange() << LCDecl; 5102 return true; 5103 } 5104 5105 static ExprResult 5106 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5107 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5108 if (SemaRef.CurContext->isDependentContext()) 5109 return ExprResult(Capture); 5110 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5111 return SemaRef.PerformImplicitConversion( 5112 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5113 /*AllowExplicit=*/true); 5114 auto I = Captures.find(Capture); 5115 if (I != Captures.end()) 5116 return buildCapture(SemaRef, Capture, I->second); 5117 DeclRefExpr *Ref = nullptr; 5118 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5119 Captures[Capture] = Ref; 5120 return Res; 5121 } 5122 5123 /// Build the expression to calculate the number of iterations. 5124 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5125 Scope *S, const bool LimitedType, 5126 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5127 ExprResult Diff; 5128 QualType VarType = LCDecl->getType().getNonReferenceType(); 5129 if (VarType->isIntegerType() || VarType->isPointerType() || 5130 SemaRef.getLangOpts().CPlusPlus) { 5131 // Upper - Lower 5132 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5133 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5134 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5135 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5136 if (!Upper || !Lower) 5137 return nullptr; 5138 5139 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5140 5141 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5142 // BuildBinOp already emitted error, this one is to point user to upper 5143 // and lower bound, and to tell what is passed to 'operator-'. 5144 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5145 << Upper->getSourceRange() << Lower->getSourceRange(); 5146 return nullptr; 5147 } 5148 } 5149 5150 if (!Diff.isUsable()) 5151 return nullptr; 5152 5153 // Upper - Lower [- 1] 5154 if (TestIsStrictOp) 5155 Diff = SemaRef.BuildBinOp( 5156 S, DefaultLoc, BO_Sub, Diff.get(), 5157 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5158 if (!Diff.isUsable()) 5159 return nullptr; 5160 5161 // Upper - Lower [- 1] + Step 5162 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5163 if (!NewStep.isUsable()) 5164 return nullptr; 5165 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5166 if (!Diff.isUsable()) 5167 return nullptr; 5168 5169 // Parentheses (for dumping/debugging purposes only). 5170 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5171 if (!Diff.isUsable()) 5172 return nullptr; 5173 5174 // (Upper - Lower [- 1] + Step) / Step 5175 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5176 if (!Diff.isUsable()) 5177 return nullptr; 5178 5179 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5180 QualType Type = Diff.get()->getType(); 5181 ASTContext &C = SemaRef.Context; 5182 bool UseVarType = VarType->hasIntegerRepresentation() && 5183 C.getTypeSize(Type) > C.getTypeSize(VarType); 5184 if (!Type->isIntegerType() || UseVarType) { 5185 unsigned NewSize = 5186 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5187 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5188 : Type->hasSignedIntegerRepresentation(); 5189 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5190 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5191 Diff = SemaRef.PerformImplicitConversion( 5192 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5193 if (!Diff.isUsable()) 5194 return nullptr; 5195 } 5196 } 5197 if (LimitedType) { 5198 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5199 if (NewSize != C.getTypeSize(Type)) { 5200 if (NewSize < C.getTypeSize(Type)) { 5201 assert(NewSize == 64 && "incorrect loop var size"); 5202 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5203 << InitSrcRange << ConditionSrcRange; 5204 } 5205 QualType NewType = C.getIntTypeForBitwidth( 5206 NewSize, Type->hasSignedIntegerRepresentation() || 5207 C.getTypeSize(Type) < NewSize); 5208 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5209 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5210 Sema::AA_Converting, true); 5211 if (!Diff.isUsable()) 5212 return nullptr; 5213 } 5214 } 5215 } 5216 5217 return Diff.get(); 5218 } 5219 5220 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5221 Scope *S, Expr *Cond, 5222 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5223 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5224 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5225 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5226 5227 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 5228 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 5229 if (!NewLB.isUsable() || !NewUB.isUsable()) 5230 return nullptr; 5231 5232 ExprResult CondExpr = 5233 SemaRef.BuildBinOp(S, DefaultLoc, 5234 TestIsLessOp.getValue() ? 5235 (TestIsStrictOp ? BO_LT : BO_LE) : 5236 (TestIsStrictOp ? BO_GT : BO_GE), 5237 NewLB.get(), NewUB.get()); 5238 if (CondExpr.isUsable()) { 5239 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5240 SemaRef.Context.BoolTy)) 5241 CondExpr = SemaRef.PerformImplicitConversion( 5242 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5243 /*AllowExplicit=*/true); 5244 } 5245 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5246 // Otherwise use original loop condition and evaluate it in runtime. 5247 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5248 } 5249 5250 /// Build reference expression to the counter be used for codegen. 5251 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5252 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5253 DSAStackTy &DSA) const { 5254 auto *VD = dyn_cast<VarDecl>(LCDecl); 5255 if (!VD) { 5256 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5257 DeclRefExpr *Ref = buildDeclRefExpr( 5258 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5259 const DSAStackTy::DSAVarData Data = 5260 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5261 // If the loop control decl is explicitly marked as private, do not mark it 5262 // as captured again. 5263 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5264 Captures.insert(std::make_pair(LCRef, Ref)); 5265 return Ref; 5266 } 5267 return cast<DeclRefExpr>(LCRef); 5268 } 5269 5270 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5271 if (LCDecl && !LCDecl->isInvalidDecl()) { 5272 QualType Type = LCDecl->getType().getNonReferenceType(); 5273 VarDecl *PrivateVar = buildVarDecl( 5274 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5275 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5276 isa<VarDecl>(LCDecl) 5277 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5278 : nullptr); 5279 if (PrivateVar->isInvalidDecl()) 5280 return nullptr; 5281 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5282 } 5283 return nullptr; 5284 } 5285 5286 /// Build initialization of the counter to be used for codegen. 5287 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5288 5289 /// Build step of the counter be used for codegen. 5290 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5291 5292 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5293 Scope *S, Expr *Counter, 5294 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5295 Expr *Inc, OverloadedOperatorKind OOK) { 5296 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5297 if (!Cnt) 5298 return nullptr; 5299 if (Inc) { 5300 assert((OOK == OO_Plus || OOK == OO_Minus) && 5301 "Expected only + or - operations for depend clauses."); 5302 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5303 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5304 if (!Cnt) 5305 return nullptr; 5306 } 5307 ExprResult Diff; 5308 QualType VarType = LCDecl->getType().getNonReferenceType(); 5309 if (VarType->isIntegerType() || VarType->isPointerType() || 5310 SemaRef.getLangOpts().CPlusPlus) { 5311 // Upper - Lower 5312 Expr *Upper = TestIsLessOp.getValue() 5313 ? Cnt 5314 : tryBuildCapture(SemaRef, UB, Captures).get(); 5315 Expr *Lower = TestIsLessOp.getValue() 5316 ? tryBuildCapture(SemaRef, LB, Captures).get() 5317 : Cnt; 5318 if (!Upper || !Lower) 5319 return nullptr; 5320 5321 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5322 5323 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5324 // BuildBinOp already emitted error, this one is to point user to upper 5325 // and lower bound, and to tell what is passed to 'operator-'. 5326 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5327 << Upper->getSourceRange() << Lower->getSourceRange(); 5328 return nullptr; 5329 } 5330 } 5331 5332 if (!Diff.isUsable()) 5333 return nullptr; 5334 5335 // Parentheses (for dumping/debugging purposes only). 5336 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5337 if (!Diff.isUsable()) 5338 return nullptr; 5339 5340 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5341 if (!NewStep.isUsable()) 5342 return nullptr; 5343 // (Upper - Lower) / Step 5344 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5345 if (!Diff.isUsable()) 5346 return nullptr; 5347 5348 return Diff.get(); 5349 } 5350 5351 /// Iteration space of a single for loop. 5352 struct LoopIterationSpace final { 5353 /// True if the condition operator is the strict compare operator (<, > or 5354 /// !=). 5355 bool IsStrictCompare = false; 5356 /// Condition of the loop. 5357 Expr *PreCond = nullptr; 5358 /// This expression calculates the number of iterations in the loop. 5359 /// It is always possible to calculate it before starting the loop. 5360 Expr *NumIterations = nullptr; 5361 /// The loop counter variable. 5362 Expr *CounterVar = nullptr; 5363 /// Private loop counter variable. 5364 Expr *PrivateCounterVar = nullptr; 5365 /// This is initializer for the initial value of #CounterVar. 5366 Expr *CounterInit = nullptr; 5367 /// This is step for the #CounterVar used to generate its update: 5368 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5369 Expr *CounterStep = nullptr; 5370 /// Should step be subtracted? 5371 bool Subtract = false; 5372 /// Source range of the loop init. 5373 SourceRange InitSrcRange; 5374 /// Source range of the loop condition. 5375 SourceRange CondSrcRange; 5376 /// Source range of the loop increment. 5377 SourceRange IncSrcRange; 5378 }; 5379 5380 } // namespace 5381 5382 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5383 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5384 assert(Init && "Expected loop in canonical form."); 5385 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5386 if (AssociatedLoops > 0 && 5387 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5388 DSAStack->loopStart(); 5389 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5390 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5391 if (ValueDecl *D = ISC.getLoopDecl()) { 5392 auto *VD = dyn_cast<VarDecl>(D); 5393 if (!VD) { 5394 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5395 VD = Private; 5396 } else { 5397 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5398 /*WithInit=*/false); 5399 VD = cast<VarDecl>(Ref->getDecl()); 5400 } 5401 } 5402 DSAStack->addLoopControlVariable(D, VD); 5403 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5404 if (LD != D->getCanonicalDecl()) { 5405 DSAStack->resetPossibleLoopCounter(); 5406 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5407 MarkDeclarationsReferencedInExpr( 5408 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5409 Var->getType().getNonLValueExprType(Context), 5410 ForLoc, /*RefersToCapture=*/true)); 5411 } 5412 } 5413 } 5414 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5415 } 5416 } 5417 5418 /// Called on a for stmt to check and extract its iteration space 5419 /// for further processing (such as collapsing). 5420 static bool checkOpenMPIterationSpace( 5421 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5422 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5423 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5424 Expr *OrderedLoopCountExpr, 5425 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5426 LoopIterationSpace &ResultIterSpace, 5427 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5428 // OpenMP [2.6, Canonical Loop Form] 5429 // for (init-expr; test-expr; incr-expr) structured-block 5430 auto *For = dyn_cast_or_null<ForStmt>(S); 5431 if (!For) { 5432 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5433 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5434 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5435 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5436 if (TotalNestedLoopCount > 1) { 5437 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5438 SemaRef.Diag(DSA.getConstructLoc(), 5439 diag::note_omp_collapse_ordered_expr) 5440 << 2 << CollapseLoopCountExpr->getSourceRange() 5441 << OrderedLoopCountExpr->getSourceRange(); 5442 else if (CollapseLoopCountExpr) 5443 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5444 diag::note_omp_collapse_ordered_expr) 5445 << 0 << CollapseLoopCountExpr->getSourceRange(); 5446 else 5447 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5448 diag::note_omp_collapse_ordered_expr) 5449 << 1 << OrderedLoopCountExpr->getSourceRange(); 5450 } 5451 return true; 5452 } 5453 assert(For->getBody()); 5454 5455 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 5456 5457 // Check init. 5458 Stmt *Init = For->getInit(); 5459 if (ISC.checkAndSetInit(Init)) 5460 return true; 5461 5462 bool HasErrors = false; 5463 5464 // Check loop variable's type. 5465 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5466 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5467 5468 // OpenMP [2.6, Canonical Loop Form] 5469 // Var is one of the following: 5470 // A variable of signed or unsigned integer type. 5471 // For C++, a variable of a random access iterator type. 5472 // For C, a variable of a pointer type. 5473 QualType VarType = LCDecl->getType().getNonReferenceType(); 5474 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5475 !VarType->isPointerType() && 5476 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5477 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5478 << SemaRef.getLangOpts().CPlusPlus; 5479 HasErrors = true; 5480 } 5481 5482 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5483 // a Construct 5484 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5485 // parallel for construct is (are) private. 5486 // The loop iteration variable in the associated for-loop of a simd 5487 // construct with just one associated for-loop is linear with a 5488 // constant-linear-step that is the increment of the associated for-loop. 5489 // Exclude loop var from the list of variables with implicitly defined data 5490 // sharing attributes. 5491 VarsWithImplicitDSA.erase(LCDecl); 5492 5493 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5494 // in a Construct, C/C++]. 5495 // The loop iteration variable in the associated for-loop of a simd 5496 // construct with just one associated for-loop may be listed in a linear 5497 // clause with a constant-linear-step that is the increment of the 5498 // associated for-loop. 5499 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5500 // parallel for construct may be listed in a private or lastprivate clause. 5501 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5502 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5503 // declared in the loop and it is predetermined as a private. 5504 OpenMPClauseKind PredeterminedCKind = 5505 isOpenMPSimdDirective(DKind) 5506 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5507 : OMPC_private; 5508 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5509 DVar.CKind != PredeterminedCKind) || 5510 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5511 isOpenMPDistributeDirective(DKind)) && 5512 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5513 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5514 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5515 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5516 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5517 << getOpenMPClauseName(PredeterminedCKind); 5518 if (DVar.RefExpr == nullptr) 5519 DVar.CKind = PredeterminedCKind; 5520 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5521 HasErrors = true; 5522 } else if (LoopDeclRefExpr != nullptr) { 5523 // Make the loop iteration variable private (for worksharing constructs), 5524 // linear (for simd directives with the only one associated loop) or 5525 // lastprivate (for simd directives with several collapsed or ordered 5526 // loops). 5527 if (DVar.CKind == OMPC_unknown) 5528 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5529 } 5530 5531 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5532 5533 // Check test-expr. 5534 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5535 5536 // Check incr-expr. 5537 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5538 } 5539 5540 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5541 return HasErrors; 5542 5543 // Build the loop's iteration space representation. 5544 ResultIterSpace.PreCond = 5545 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5546 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5547 DSA.getCurScope(), 5548 (isOpenMPWorksharingDirective(DKind) || 5549 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5550 Captures); 5551 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5552 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5553 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5554 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5555 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5556 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5557 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5558 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5559 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5560 5561 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5562 ResultIterSpace.NumIterations == nullptr || 5563 ResultIterSpace.CounterVar == nullptr || 5564 ResultIterSpace.PrivateCounterVar == nullptr || 5565 ResultIterSpace.CounterInit == nullptr || 5566 ResultIterSpace.CounterStep == nullptr); 5567 if (!HasErrors && DSA.isOrderedRegion()) { 5568 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5569 if (CurrentNestedLoopCount < 5570 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5571 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5572 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5573 DSA.getOrderedRegionParam().second->setLoopCounter( 5574 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5575 } 5576 } 5577 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5578 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5579 // Erroneous case - clause has some problems. 5580 continue; 5581 } 5582 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5583 Pair.second.size() <= CurrentNestedLoopCount) { 5584 // Erroneous case - clause has some problems. 5585 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5586 continue; 5587 } 5588 Expr *CntValue; 5589 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5590 CntValue = ISC.buildOrderedLoopData( 5591 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5592 Pair.first->getDependencyLoc()); 5593 else 5594 CntValue = ISC.buildOrderedLoopData( 5595 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5596 Pair.first->getDependencyLoc(), 5597 Pair.second[CurrentNestedLoopCount].first, 5598 Pair.second[CurrentNestedLoopCount].second); 5599 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5600 } 5601 } 5602 5603 return HasErrors; 5604 } 5605 5606 /// Build 'VarRef = Start. 5607 static ExprResult 5608 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5609 ExprResult Start, 5610 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5611 // Build 'VarRef = Start. 5612 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5613 if (!NewStart.isUsable()) 5614 return ExprError(); 5615 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5616 VarRef.get()->getType())) { 5617 NewStart = SemaRef.PerformImplicitConversion( 5618 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5619 /*AllowExplicit=*/true); 5620 if (!NewStart.isUsable()) 5621 return ExprError(); 5622 } 5623 5624 ExprResult Init = 5625 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5626 return Init; 5627 } 5628 5629 /// Build 'VarRef = Start + Iter * Step'. 5630 static ExprResult buildCounterUpdate( 5631 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5632 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5633 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5634 // Add parentheses (for debugging purposes only). 5635 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5636 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5637 !Step.isUsable()) 5638 return ExprError(); 5639 5640 ExprResult NewStep = Step; 5641 if (Captures) 5642 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5643 if (NewStep.isInvalid()) 5644 return ExprError(); 5645 ExprResult Update = 5646 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5647 if (!Update.isUsable()) 5648 return ExprError(); 5649 5650 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5651 // 'VarRef = Start (+|-) Iter * Step'. 5652 ExprResult NewStart = Start; 5653 if (Captures) 5654 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5655 if (NewStart.isInvalid()) 5656 return ExprError(); 5657 5658 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5659 ExprResult SavedUpdate = Update; 5660 ExprResult UpdateVal; 5661 if (VarRef.get()->getType()->isOverloadableType() || 5662 NewStart.get()->getType()->isOverloadableType() || 5663 Update.get()->getType()->isOverloadableType()) { 5664 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5665 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5666 Update = 5667 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5668 if (Update.isUsable()) { 5669 UpdateVal = 5670 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5671 VarRef.get(), SavedUpdate.get()); 5672 if (UpdateVal.isUsable()) { 5673 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5674 UpdateVal.get()); 5675 } 5676 } 5677 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5678 } 5679 5680 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5681 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5682 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5683 NewStart.get(), SavedUpdate.get()); 5684 if (!Update.isUsable()) 5685 return ExprError(); 5686 5687 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5688 VarRef.get()->getType())) { 5689 Update = SemaRef.PerformImplicitConversion( 5690 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5691 if (!Update.isUsable()) 5692 return ExprError(); 5693 } 5694 5695 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5696 } 5697 return Update; 5698 } 5699 5700 /// Convert integer expression \a E to make it have at least \a Bits 5701 /// bits. 5702 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5703 if (E == nullptr) 5704 return ExprError(); 5705 ASTContext &C = SemaRef.Context; 5706 QualType OldType = E->getType(); 5707 unsigned HasBits = C.getTypeSize(OldType); 5708 if (HasBits >= Bits) 5709 return ExprResult(E); 5710 // OK to convert to signed, because new type has more bits than old. 5711 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5712 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5713 true); 5714 } 5715 5716 /// Check if the given expression \a E is a constant integer that fits 5717 /// into \a Bits bits. 5718 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5719 if (E == nullptr) 5720 return false; 5721 llvm::APSInt Result; 5722 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5723 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5724 return false; 5725 } 5726 5727 /// Build preinits statement for the given declarations. 5728 static Stmt *buildPreInits(ASTContext &Context, 5729 MutableArrayRef<Decl *> PreInits) { 5730 if (!PreInits.empty()) { 5731 return new (Context) DeclStmt( 5732 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5733 SourceLocation(), SourceLocation()); 5734 } 5735 return nullptr; 5736 } 5737 5738 /// Build preinits statement for the given declarations. 5739 static Stmt * 5740 buildPreInits(ASTContext &Context, 5741 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5742 if (!Captures.empty()) { 5743 SmallVector<Decl *, 16> PreInits; 5744 for (const auto &Pair : Captures) 5745 PreInits.push_back(Pair.second->getDecl()); 5746 return buildPreInits(Context, PreInits); 5747 } 5748 return nullptr; 5749 } 5750 5751 /// Build postupdate expression for the given list of postupdates expressions. 5752 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5753 Expr *PostUpdate = nullptr; 5754 if (!PostUpdates.empty()) { 5755 for (Expr *E : PostUpdates) { 5756 Expr *ConvE = S.BuildCStyleCastExpr( 5757 E->getExprLoc(), 5758 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5759 E->getExprLoc(), E) 5760 .get(); 5761 PostUpdate = PostUpdate 5762 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5763 PostUpdate, ConvE) 5764 .get() 5765 : ConvE; 5766 } 5767 } 5768 return PostUpdate; 5769 } 5770 5771 /// Called on a for stmt to check itself and nested loops (if any). 5772 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5773 /// number of collapsed loops otherwise. 5774 static unsigned 5775 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5776 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5777 DSAStackTy &DSA, 5778 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5779 OMPLoopDirective::HelperExprs &Built) { 5780 unsigned NestedLoopCount = 1; 5781 if (CollapseLoopCountExpr) { 5782 // Found 'collapse' clause - calculate collapse number. 5783 Expr::EvalResult Result; 5784 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 5785 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5786 } 5787 unsigned OrderedLoopCount = 1; 5788 if (OrderedLoopCountExpr) { 5789 // Found 'ordered' clause - calculate collapse number. 5790 Expr::EvalResult EVResult; 5791 if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { 5792 llvm::APSInt Result = EVResult.Val.getInt(); 5793 if (Result.getLimitedValue() < NestedLoopCount) { 5794 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5795 diag::err_omp_wrong_ordered_loop_count) 5796 << OrderedLoopCountExpr->getSourceRange(); 5797 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5798 diag::note_collapse_loop_count) 5799 << CollapseLoopCountExpr->getSourceRange(); 5800 } 5801 OrderedLoopCount = Result.getLimitedValue(); 5802 } 5803 } 5804 // This is helper routine for loop directives (e.g., 'for', 'simd', 5805 // 'for simd', etc.). 5806 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 5807 SmallVector<LoopIterationSpace, 4> IterSpaces( 5808 std::max(OrderedLoopCount, NestedLoopCount)); 5809 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 5810 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5811 if (checkOpenMPIterationSpace( 5812 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5813 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5814 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5815 Captures)) 5816 return 0; 5817 // Move on to the next nested for loop, or to the loop body. 5818 // OpenMP [2.8.1, simd construct, Restrictions] 5819 // All loops associated with the construct must be perfectly nested; that 5820 // is, there must be no intervening code nor any OpenMP directive between 5821 // any two loops. 5822 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5823 } 5824 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 5825 if (checkOpenMPIterationSpace( 5826 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5827 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5828 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5829 Captures)) 5830 return 0; 5831 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 5832 // Handle initialization of captured loop iterator variables. 5833 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 5834 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 5835 Captures[DRE] = DRE; 5836 } 5837 } 5838 // Move on to the next nested for loop, or to the loop body. 5839 // OpenMP [2.8.1, simd construct, Restrictions] 5840 // All loops associated with the construct must be perfectly nested; that 5841 // is, there must be no intervening code nor any OpenMP directive between 5842 // any two loops. 5843 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5844 } 5845 5846 Built.clear(/* size */ NestedLoopCount); 5847 5848 if (SemaRef.CurContext->isDependentContext()) 5849 return NestedLoopCount; 5850 5851 // An example of what is generated for the following code: 5852 // 5853 // #pragma omp simd collapse(2) ordered(2) 5854 // for (i = 0; i < NI; ++i) 5855 // for (k = 0; k < NK; ++k) 5856 // for (j = J0; j < NJ; j+=2) { 5857 // <loop body> 5858 // } 5859 // 5860 // We generate the code below. 5861 // Note: the loop body may be outlined in CodeGen. 5862 // Note: some counters may be C++ classes, operator- is used to find number of 5863 // iterations and operator+= to calculate counter value. 5864 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 5865 // or i64 is currently supported). 5866 // 5867 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 5868 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 5869 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 5870 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 5871 // // similar updates for vars in clauses (e.g. 'linear') 5872 // <loop body (using local i and j)> 5873 // } 5874 // i = NI; // assign final values of counters 5875 // j = NJ; 5876 // 5877 5878 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 5879 // the iteration counts of the collapsed for loops. 5880 // Precondition tests if there is at least one iteration (all conditions are 5881 // true). 5882 auto PreCond = ExprResult(IterSpaces[0].PreCond); 5883 Expr *N0 = IterSpaces[0].NumIterations; 5884 ExprResult LastIteration32 = 5885 widenIterationCount(/*Bits=*/32, 5886 SemaRef 5887 .PerformImplicitConversion( 5888 N0->IgnoreImpCasts(), N0->getType(), 5889 Sema::AA_Converting, /*AllowExplicit=*/true) 5890 .get(), 5891 SemaRef); 5892 ExprResult LastIteration64 = widenIterationCount( 5893 /*Bits=*/64, 5894 SemaRef 5895 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 5896 Sema::AA_Converting, 5897 /*AllowExplicit=*/true) 5898 .get(), 5899 SemaRef); 5900 5901 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 5902 return NestedLoopCount; 5903 5904 ASTContext &C = SemaRef.Context; 5905 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 5906 5907 Scope *CurScope = DSA.getCurScope(); 5908 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 5909 if (PreCond.isUsable()) { 5910 PreCond = 5911 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 5912 PreCond.get(), IterSpaces[Cnt].PreCond); 5913 } 5914 Expr *N = IterSpaces[Cnt].NumIterations; 5915 SourceLocation Loc = N->getExprLoc(); 5916 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 5917 if (LastIteration32.isUsable()) 5918 LastIteration32 = SemaRef.BuildBinOp( 5919 CurScope, Loc, BO_Mul, LastIteration32.get(), 5920 SemaRef 5921 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5922 Sema::AA_Converting, 5923 /*AllowExplicit=*/true) 5924 .get()); 5925 if (LastIteration64.isUsable()) 5926 LastIteration64 = SemaRef.BuildBinOp( 5927 CurScope, Loc, BO_Mul, LastIteration64.get(), 5928 SemaRef 5929 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5930 Sema::AA_Converting, 5931 /*AllowExplicit=*/true) 5932 .get()); 5933 } 5934 5935 // Choose either the 32-bit or 64-bit version. 5936 ExprResult LastIteration = LastIteration64; 5937 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 5938 (LastIteration32.isUsable() && 5939 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 5940 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 5941 fitsInto( 5942 /*Bits=*/32, 5943 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 5944 LastIteration64.get(), SemaRef)))) 5945 LastIteration = LastIteration32; 5946 QualType VType = LastIteration.get()->getType(); 5947 QualType RealVType = VType; 5948 QualType StrideVType = VType; 5949 if (isOpenMPTaskLoopDirective(DKind)) { 5950 VType = 5951 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 5952 StrideVType = 5953 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 5954 } 5955 5956 if (!LastIteration.isUsable()) 5957 return 0; 5958 5959 // Save the number of iterations. 5960 ExprResult NumIterations = LastIteration; 5961 { 5962 LastIteration = SemaRef.BuildBinOp( 5963 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 5964 LastIteration.get(), 5965 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5966 if (!LastIteration.isUsable()) 5967 return 0; 5968 } 5969 5970 // Calculate the last iteration number beforehand instead of doing this on 5971 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5972 llvm::APSInt Result; 5973 bool IsConstant = 5974 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5975 ExprResult CalcLastIteration; 5976 if (!IsConstant) { 5977 ExprResult SaveRef = 5978 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5979 LastIteration = SaveRef; 5980 5981 // Prepare SaveRef + 1. 5982 NumIterations = SemaRef.BuildBinOp( 5983 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 5984 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5985 if (!NumIterations.isUsable()) 5986 return 0; 5987 } 5988 5989 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5990 5991 // Build variables passed into runtime, necessary for worksharing directives. 5992 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 5993 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5994 isOpenMPDistributeDirective(DKind)) { 5995 // Lower bound variable, initialized with zero. 5996 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5997 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5998 SemaRef.AddInitializerToDecl(LBDecl, 5999 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6000 /*DirectInit*/ false); 6001 6002 // Upper bound variable, initialized with last iteration number. 6003 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6004 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6005 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6006 /*DirectInit*/ false); 6007 6008 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6009 // This will be used to implement clause 'lastprivate'. 6010 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6011 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6012 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6013 SemaRef.AddInitializerToDecl(ILDecl, 6014 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6015 /*DirectInit*/ false); 6016 6017 // Stride variable returned by runtime (we initialize it to 1 by default). 6018 VarDecl *STDecl = 6019 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6020 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6021 SemaRef.AddInitializerToDecl(STDecl, 6022 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6023 /*DirectInit*/ false); 6024 6025 // Build expression: UB = min(UB, LastIteration) 6026 // It is necessary for CodeGen of directives with static scheduling. 6027 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6028 UB.get(), LastIteration.get()); 6029 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6030 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6031 LastIteration.get(), UB.get()); 6032 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6033 CondOp.get()); 6034 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6035 6036 // If we have a combined directive that combines 'distribute', 'for' or 6037 // 'simd' we need to be able to access the bounds of the schedule of the 6038 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6039 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6040 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6041 // Lower bound variable, initialized with zero. 6042 VarDecl *CombLBDecl = 6043 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6044 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6045 SemaRef.AddInitializerToDecl( 6046 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6047 /*DirectInit*/ false); 6048 6049 // Upper bound variable, initialized with last iteration number. 6050 VarDecl *CombUBDecl = 6051 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6052 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6053 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6054 /*DirectInit*/ false); 6055 6056 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6057 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6058 ExprResult CombCondOp = 6059 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6060 LastIteration.get(), CombUB.get()); 6061 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6062 CombCondOp.get()); 6063 CombEUB = 6064 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6065 6066 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6067 // We expect to have at least 2 more parameters than the 'parallel' 6068 // directive does - the lower and upper bounds of the previous schedule. 6069 assert(CD->getNumParams() >= 4 && 6070 "Unexpected number of parameters in loop combined directive"); 6071 6072 // Set the proper type for the bounds given what we learned from the 6073 // enclosed loops. 6074 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6075 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6076 6077 // Previous lower and upper bounds are obtained from the region 6078 // parameters. 6079 PrevLB = 6080 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6081 PrevUB = 6082 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6083 } 6084 } 6085 6086 // Build the iteration variable and its initialization before loop. 6087 ExprResult IV; 6088 ExprResult Init, CombInit; 6089 { 6090 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6091 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6092 Expr *RHS = 6093 (isOpenMPWorksharingDirective(DKind) || 6094 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6095 ? LB.get() 6096 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6097 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6098 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6099 6100 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6101 Expr *CombRHS = 6102 (isOpenMPWorksharingDirective(DKind) || 6103 isOpenMPTaskLoopDirective(DKind) || 6104 isOpenMPDistributeDirective(DKind)) 6105 ? CombLB.get() 6106 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6107 CombInit = 6108 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6109 CombInit = 6110 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6111 } 6112 } 6113 6114 bool UseStrictCompare = 6115 RealVType->hasUnsignedIntegerRepresentation() && 6116 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6117 return LIS.IsStrictCompare; 6118 }); 6119 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6120 // unsigned IV)) for worksharing loops. 6121 SourceLocation CondLoc = AStmt->getBeginLoc(); 6122 Expr *BoundUB = UB.get(); 6123 if (UseStrictCompare) { 6124 BoundUB = 6125 SemaRef 6126 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6127 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6128 .get(); 6129 BoundUB = 6130 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6131 } 6132 ExprResult Cond = 6133 (isOpenMPWorksharingDirective(DKind) || 6134 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6135 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6136 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6137 BoundUB) 6138 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6139 NumIterations.get()); 6140 ExprResult CombDistCond; 6141 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6142 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6143 NumIterations.get()); 6144 } 6145 6146 ExprResult CombCond; 6147 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6148 Expr *BoundCombUB = CombUB.get(); 6149 if (UseStrictCompare) { 6150 BoundCombUB = 6151 SemaRef 6152 .BuildBinOp( 6153 CurScope, CondLoc, BO_Add, BoundCombUB, 6154 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6155 .get(); 6156 BoundCombUB = 6157 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6158 .get(); 6159 } 6160 CombCond = 6161 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6162 IV.get(), BoundCombUB); 6163 } 6164 // Loop increment (IV = IV + 1) 6165 SourceLocation IncLoc = AStmt->getBeginLoc(); 6166 ExprResult Inc = 6167 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6168 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6169 if (!Inc.isUsable()) 6170 return 0; 6171 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6172 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6173 if (!Inc.isUsable()) 6174 return 0; 6175 6176 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6177 // Used for directives with static scheduling. 6178 // In combined construct, add combined version that use CombLB and CombUB 6179 // base variables for the update 6180 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6181 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6182 isOpenMPDistributeDirective(DKind)) { 6183 // LB + ST 6184 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6185 if (!NextLB.isUsable()) 6186 return 0; 6187 // LB = LB + ST 6188 NextLB = 6189 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6190 NextLB = 6191 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6192 if (!NextLB.isUsable()) 6193 return 0; 6194 // UB + ST 6195 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6196 if (!NextUB.isUsable()) 6197 return 0; 6198 // UB = UB + ST 6199 NextUB = 6200 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6201 NextUB = 6202 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6203 if (!NextUB.isUsable()) 6204 return 0; 6205 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6206 CombNextLB = 6207 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6208 if (!NextLB.isUsable()) 6209 return 0; 6210 // LB = LB + ST 6211 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6212 CombNextLB.get()); 6213 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6214 /*DiscardedValue*/ false); 6215 if (!CombNextLB.isUsable()) 6216 return 0; 6217 // UB + ST 6218 CombNextUB = 6219 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6220 if (!CombNextUB.isUsable()) 6221 return 0; 6222 // UB = UB + ST 6223 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6224 CombNextUB.get()); 6225 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6226 /*DiscardedValue*/ false); 6227 if (!CombNextUB.isUsable()) 6228 return 0; 6229 } 6230 } 6231 6232 // Create increment expression for distribute loop when combined in a same 6233 // directive with for as IV = IV + ST; ensure upper bound expression based 6234 // on PrevUB instead of NumIterations - used to implement 'for' when found 6235 // in combination with 'distribute', like in 'distribute parallel for' 6236 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6237 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6238 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6239 DistCond = SemaRef.BuildBinOp( 6240 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6241 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6242 6243 DistInc = 6244 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6245 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6246 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6247 DistInc.get()); 6248 DistInc = 6249 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6250 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6251 6252 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6253 // construct 6254 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6255 ExprResult IsUBGreater = 6256 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6257 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6258 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6259 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6260 CondOp.get()); 6261 PrevEUB = 6262 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6263 6264 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6265 // parallel for is in combination with a distribute directive with 6266 // schedule(static, 1) 6267 Expr *BoundPrevUB = PrevUB.get(); 6268 if (UseStrictCompare) { 6269 BoundPrevUB = 6270 SemaRef 6271 .BuildBinOp( 6272 CurScope, CondLoc, BO_Add, BoundPrevUB, 6273 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6274 .get(); 6275 BoundPrevUB = 6276 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6277 .get(); 6278 } 6279 ParForInDistCond = 6280 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6281 IV.get(), BoundPrevUB); 6282 } 6283 6284 // Build updates and final values of the loop counters. 6285 bool HasErrors = false; 6286 Built.Counters.resize(NestedLoopCount); 6287 Built.Inits.resize(NestedLoopCount); 6288 Built.Updates.resize(NestedLoopCount); 6289 Built.Finals.resize(NestedLoopCount); 6290 { 6291 // We implement the following algorithm for obtaining the 6292 // original loop iteration variable values based on the 6293 // value of the collapsed loop iteration variable IV. 6294 // 6295 // Let n+1 be the number of collapsed loops in the nest. 6296 // Iteration variables (I0, I1, .... In) 6297 // Iteration counts (N0, N1, ... Nn) 6298 // 6299 // Acc = IV; 6300 // 6301 // To compute Ik for loop k, 0 <= k <= n, generate: 6302 // Prod = N(k+1) * N(k+2) * ... * Nn; 6303 // Ik = Acc / Prod; 6304 // Acc -= Ik * Prod; 6305 // 6306 ExprResult Acc = IV; 6307 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6308 LoopIterationSpace &IS = IterSpaces[Cnt]; 6309 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6310 ExprResult Iter; 6311 6312 // Compute prod 6313 ExprResult Prod = 6314 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6315 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6316 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6317 IterSpaces[K].NumIterations); 6318 6319 // Iter = Acc / Prod 6320 // If there is at least one more inner loop to avoid 6321 // multiplication by 1. 6322 if (Cnt + 1 < NestedLoopCount) 6323 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6324 Acc.get(), Prod.get()); 6325 else 6326 Iter = Acc; 6327 if (!Iter.isUsable()) { 6328 HasErrors = true; 6329 break; 6330 } 6331 6332 // Update Acc: 6333 // Acc -= Iter * Prod 6334 // Check if there is at least one more inner loop to avoid 6335 // multiplication by 1. 6336 if (Cnt + 1 < NestedLoopCount) 6337 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6338 Iter.get(), Prod.get()); 6339 else 6340 Prod = Iter; 6341 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6342 Acc.get(), Prod.get()); 6343 6344 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6345 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6346 DeclRefExpr *CounterVar = buildDeclRefExpr( 6347 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6348 /*RefersToCapture=*/true); 6349 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6350 IS.CounterInit, Captures); 6351 if (!Init.isUsable()) { 6352 HasErrors = true; 6353 break; 6354 } 6355 ExprResult Update = buildCounterUpdate( 6356 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6357 IS.CounterStep, IS.Subtract, &Captures); 6358 if (!Update.isUsable()) { 6359 HasErrors = true; 6360 break; 6361 } 6362 6363 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6364 ExprResult Final = buildCounterUpdate( 6365 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 6366 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 6367 if (!Final.isUsable()) { 6368 HasErrors = true; 6369 break; 6370 } 6371 6372 if (!Update.isUsable() || !Final.isUsable()) { 6373 HasErrors = true; 6374 break; 6375 } 6376 // Save results 6377 Built.Counters[Cnt] = IS.CounterVar; 6378 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6379 Built.Inits[Cnt] = Init.get(); 6380 Built.Updates[Cnt] = Update.get(); 6381 Built.Finals[Cnt] = Final.get(); 6382 } 6383 } 6384 6385 if (HasErrors) 6386 return 0; 6387 6388 // Save results 6389 Built.IterationVarRef = IV.get(); 6390 Built.LastIteration = LastIteration.get(); 6391 Built.NumIterations = NumIterations.get(); 6392 Built.CalcLastIteration = SemaRef 6393 .ActOnFinishFullExpr(CalcLastIteration.get(), 6394 /*DiscardedValue*/ false) 6395 .get(); 6396 Built.PreCond = PreCond.get(); 6397 Built.PreInits = buildPreInits(C, Captures); 6398 Built.Cond = Cond.get(); 6399 Built.Init = Init.get(); 6400 Built.Inc = Inc.get(); 6401 Built.LB = LB.get(); 6402 Built.UB = UB.get(); 6403 Built.IL = IL.get(); 6404 Built.ST = ST.get(); 6405 Built.EUB = EUB.get(); 6406 Built.NLB = NextLB.get(); 6407 Built.NUB = NextUB.get(); 6408 Built.PrevLB = PrevLB.get(); 6409 Built.PrevUB = PrevUB.get(); 6410 Built.DistInc = DistInc.get(); 6411 Built.PrevEUB = PrevEUB.get(); 6412 Built.DistCombinedFields.LB = CombLB.get(); 6413 Built.DistCombinedFields.UB = CombUB.get(); 6414 Built.DistCombinedFields.EUB = CombEUB.get(); 6415 Built.DistCombinedFields.Init = CombInit.get(); 6416 Built.DistCombinedFields.Cond = CombCond.get(); 6417 Built.DistCombinedFields.NLB = CombNextLB.get(); 6418 Built.DistCombinedFields.NUB = CombNextUB.get(); 6419 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6420 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6421 6422 return NestedLoopCount; 6423 } 6424 6425 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6426 auto CollapseClauses = 6427 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6428 if (CollapseClauses.begin() != CollapseClauses.end()) 6429 return (*CollapseClauses.begin())->getNumForLoops(); 6430 return nullptr; 6431 } 6432 6433 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6434 auto OrderedClauses = 6435 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6436 if (OrderedClauses.begin() != OrderedClauses.end()) 6437 return (*OrderedClauses.begin())->getNumForLoops(); 6438 return nullptr; 6439 } 6440 6441 static bool checkSimdlenSafelenSpecified(Sema &S, 6442 const ArrayRef<OMPClause *> Clauses) { 6443 const OMPSafelenClause *Safelen = nullptr; 6444 const OMPSimdlenClause *Simdlen = nullptr; 6445 6446 for (const OMPClause *Clause : Clauses) { 6447 if (Clause->getClauseKind() == OMPC_safelen) 6448 Safelen = cast<OMPSafelenClause>(Clause); 6449 else if (Clause->getClauseKind() == OMPC_simdlen) 6450 Simdlen = cast<OMPSimdlenClause>(Clause); 6451 if (Safelen && Simdlen) 6452 break; 6453 } 6454 6455 if (Simdlen && Safelen) { 6456 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6457 const Expr *SafelenLength = Safelen->getSafelen(); 6458 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6459 SimdlenLength->isInstantiationDependent() || 6460 SimdlenLength->containsUnexpandedParameterPack()) 6461 return false; 6462 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6463 SafelenLength->isInstantiationDependent() || 6464 SafelenLength->containsUnexpandedParameterPack()) 6465 return false; 6466 Expr::EvalResult SimdlenResult, SafelenResult; 6467 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6468 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6469 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6470 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6471 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6472 // If both simdlen and safelen clauses are specified, the value of the 6473 // simdlen parameter must be less than or equal to the value of the safelen 6474 // parameter. 6475 if (SimdlenRes > SafelenRes) { 6476 S.Diag(SimdlenLength->getExprLoc(), 6477 diag::err_omp_wrong_simdlen_safelen_values) 6478 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6479 return true; 6480 } 6481 } 6482 return false; 6483 } 6484 6485 StmtResult 6486 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6487 SourceLocation StartLoc, SourceLocation EndLoc, 6488 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6489 if (!AStmt) 6490 return StmtError(); 6491 6492 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6493 OMPLoopDirective::HelperExprs B; 6494 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6495 // define the nested loops number. 6496 unsigned NestedLoopCount = checkOpenMPLoop( 6497 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6498 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6499 if (NestedLoopCount == 0) 6500 return StmtError(); 6501 6502 assert((CurContext->isDependentContext() || B.builtAll()) && 6503 "omp simd loop exprs were not built"); 6504 6505 if (!CurContext->isDependentContext()) { 6506 // Finalize the clauses that need pre-built expressions for CodeGen. 6507 for (OMPClause *C : Clauses) { 6508 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6509 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6510 B.NumIterations, *this, CurScope, 6511 DSAStack)) 6512 return StmtError(); 6513 } 6514 } 6515 6516 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6517 return StmtError(); 6518 6519 setFunctionHasBranchProtectedScope(); 6520 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6521 Clauses, AStmt, B); 6522 } 6523 6524 StmtResult 6525 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6526 SourceLocation StartLoc, SourceLocation EndLoc, 6527 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6528 if (!AStmt) 6529 return StmtError(); 6530 6531 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6532 OMPLoopDirective::HelperExprs B; 6533 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6534 // define the nested loops number. 6535 unsigned NestedLoopCount = checkOpenMPLoop( 6536 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6537 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6538 if (NestedLoopCount == 0) 6539 return StmtError(); 6540 6541 assert((CurContext->isDependentContext() || B.builtAll()) && 6542 "omp for loop exprs were not built"); 6543 6544 if (!CurContext->isDependentContext()) { 6545 // Finalize the clauses that need pre-built expressions for CodeGen. 6546 for (OMPClause *C : Clauses) { 6547 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6548 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6549 B.NumIterations, *this, CurScope, 6550 DSAStack)) 6551 return StmtError(); 6552 } 6553 } 6554 6555 setFunctionHasBranchProtectedScope(); 6556 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6557 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6558 } 6559 6560 StmtResult Sema::ActOnOpenMPForSimdDirective( 6561 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6562 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6563 if (!AStmt) 6564 return StmtError(); 6565 6566 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6567 OMPLoopDirective::HelperExprs B; 6568 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6569 // define the nested loops number. 6570 unsigned NestedLoopCount = 6571 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6572 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6573 VarsWithImplicitDSA, B); 6574 if (NestedLoopCount == 0) 6575 return StmtError(); 6576 6577 assert((CurContext->isDependentContext() || B.builtAll()) && 6578 "omp for simd loop exprs were not built"); 6579 6580 if (!CurContext->isDependentContext()) { 6581 // Finalize the clauses that need pre-built expressions for CodeGen. 6582 for (OMPClause *C : Clauses) { 6583 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6584 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6585 B.NumIterations, *this, CurScope, 6586 DSAStack)) 6587 return StmtError(); 6588 } 6589 } 6590 6591 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6592 return StmtError(); 6593 6594 setFunctionHasBranchProtectedScope(); 6595 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6596 Clauses, AStmt, B); 6597 } 6598 6599 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6600 Stmt *AStmt, 6601 SourceLocation StartLoc, 6602 SourceLocation EndLoc) { 6603 if (!AStmt) 6604 return StmtError(); 6605 6606 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6607 auto BaseStmt = AStmt; 6608 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6609 BaseStmt = CS->getCapturedStmt(); 6610 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6611 auto S = C->children(); 6612 if (S.begin() == S.end()) 6613 return StmtError(); 6614 // All associated statements must be '#pragma omp section' except for 6615 // the first one. 6616 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6617 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6618 if (SectionStmt) 6619 Diag(SectionStmt->getBeginLoc(), 6620 diag::err_omp_sections_substmt_not_section); 6621 return StmtError(); 6622 } 6623 cast<OMPSectionDirective>(SectionStmt) 6624 ->setHasCancel(DSAStack->isCancelRegion()); 6625 } 6626 } else { 6627 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6628 return StmtError(); 6629 } 6630 6631 setFunctionHasBranchProtectedScope(); 6632 6633 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6634 DSAStack->isCancelRegion()); 6635 } 6636 6637 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6638 SourceLocation StartLoc, 6639 SourceLocation EndLoc) { 6640 if (!AStmt) 6641 return StmtError(); 6642 6643 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6644 6645 setFunctionHasBranchProtectedScope(); 6646 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6647 6648 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6649 DSAStack->isCancelRegion()); 6650 } 6651 6652 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6653 Stmt *AStmt, 6654 SourceLocation StartLoc, 6655 SourceLocation EndLoc) { 6656 if (!AStmt) 6657 return StmtError(); 6658 6659 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6660 6661 setFunctionHasBranchProtectedScope(); 6662 6663 // OpenMP [2.7.3, single Construct, Restrictions] 6664 // The copyprivate clause must not be used with the nowait clause. 6665 const OMPClause *Nowait = nullptr; 6666 const OMPClause *Copyprivate = nullptr; 6667 for (const OMPClause *Clause : Clauses) { 6668 if (Clause->getClauseKind() == OMPC_nowait) 6669 Nowait = Clause; 6670 else if (Clause->getClauseKind() == OMPC_copyprivate) 6671 Copyprivate = Clause; 6672 if (Copyprivate && Nowait) { 6673 Diag(Copyprivate->getBeginLoc(), 6674 diag::err_omp_single_copyprivate_with_nowait); 6675 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6676 return StmtError(); 6677 } 6678 } 6679 6680 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6681 } 6682 6683 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6684 SourceLocation StartLoc, 6685 SourceLocation EndLoc) { 6686 if (!AStmt) 6687 return StmtError(); 6688 6689 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6690 6691 setFunctionHasBranchProtectedScope(); 6692 6693 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6694 } 6695 6696 StmtResult Sema::ActOnOpenMPCriticalDirective( 6697 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6698 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6699 if (!AStmt) 6700 return StmtError(); 6701 6702 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6703 6704 bool ErrorFound = false; 6705 llvm::APSInt Hint; 6706 SourceLocation HintLoc; 6707 bool DependentHint = false; 6708 for (const OMPClause *C : Clauses) { 6709 if (C->getClauseKind() == OMPC_hint) { 6710 if (!DirName.getName()) { 6711 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6712 ErrorFound = true; 6713 } 6714 Expr *E = cast<OMPHintClause>(C)->getHint(); 6715 if (E->isTypeDependent() || E->isValueDependent() || 6716 E->isInstantiationDependent()) { 6717 DependentHint = true; 6718 } else { 6719 Hint = E->EvaluateKnownConstInt(Context); 6720 HintLoc = C->getBeginLoc(); 6721 } 6722 } 6723 } 6724 if (ErrorFound) 6725 return StmtError(); 6726 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6727 if (Pair.first && DirName.getName() && !DependentHint) { 6728 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6729 Diag(StartLoc, diag::err_omp_critical_with_hint); 6730 if (HintLoc.isValid()) 6731 Diag(HintLoc, diag::note_omp_critical_hint_here) 6732 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6733 else 6734 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6735 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6736 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6737 << 1 6738 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6739 /*Radix=*/10, /*Signed=*/false); 6740 } else { 6741 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6742 } 6743 } 6744 } 6745 6746 setFunctionHasBranchProtectedScope(); 6747 6748 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6749 Clauses, AStmt); 6750 if (!Pair.first && DirName.getName() && !DependentHint) 6751 DSAStack->addCriticalWithHint(Dir, Hint); 6752 return Dir; 6753 } 6754 6755 StmtResult Sema::ActOnOpenMPParallelForDirective( 6756 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6757 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6758 if (!AStmt) 6759 return StmtError(); 6760 6761 auto *CS = cast<CapturedStmt>(AStmt); 6762 // 1.2.2 OpenMP Language Terminology 6763 // Structured block - An executable statement with a single entry at the 6764 // top and a single exit at the bottom. 6765 // The point of exit cannot be a branch out of the structured block. 6766 // longjmp() and throw() must not violate the entry/exit criteria. 6767 CS->getCapturedDecl()->setNothrow(); 6768 6769 OMPLoopDirective::HelperExprs B; 6770 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6771 // define the nested loops number. 6772 unsigned NestedLoopCount = 6773 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6774 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6775 VarsWithImplicitDSA, B); 6776 if (NestedLoopCount == 0) 6777 return StmtError(); 6778 6779 assert((CurContext->isDependentContext() || B.builtAll()) && 6780 "omp parallel for loop exprs were not built"); 6781 6782 if (!CurContext->isDependentContext()) { 6783 // Finalize the clauses that need pre-built expressions for CodeGen. 6784 for (OMPClause *C : Clauses) { 6785 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6786 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6787 B.NumIterations, *this, CurScope, 6788 DSAStack)) 6789 return StmtError(); 6790 } 6791 } 6792 6793 setFunctionHasBranchProtectedScope(); 6794 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6795 NestedLoopCount, Clauses, AStmt, B, 6796 DSAStack->isCancelRegion()); 6797 } 6798 6799 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6800 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6801 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6802 if (!AStmt) 6803 return StmtError(); 6804 6805 auto *CS = cast<CapturedStmt>(AStmt); 6806 // 1.2.2 OpenMP Language Terminology 6807 // Structured block - An executable statement with a single entry at the 6808 // top and a single exit at the bottom. 6809 // The point of exit cannot be a branch out of the structured block. 6810 // longjmp() and throw() must not violate the entry/exit criteria. 6811 CS->getCapturedDecl()->setNothrow(); 6812 6813 OMPLoopDirective::HelperExprs B; 6814 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6815 // define the nested loops number. 6816 unsigned NestedLoopCount = 6817 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 6818 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6819 VarsWithImplicitDSA, B); 6820 if (NestedLoopCount == 0) 6821 return StmtError(); 6822 6823 if (!CurContext->isDependentContext()) { 6824 // Finalize the clauses that need pre-built expressions for CodeGen. 6825 for (OMPClause *C : Clauses) { 6826 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6827 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6828 B.NumIterations, *this, CurScope, 6829 DSAStack)) 6830 return StmtError(); 6831 } 6832 } 6833 6834 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6835 return StmtError(); 6836 6837 setFunctionHasBranchProtectedScope(); 6838 return OMPParallelForSimdDirective::Create( 6839 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6840 } 6841 6842 StmtResult 6843 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 6844 Stmt *AStmt, SourceLocation StartLoc, 6845 SourceLocation EndLoc) { 6846 if (!AStmt) 6847 return StmtError(); 6848 6849 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6850 auto BaseStmt = AStmt; 6851 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6852 BaseStmt = CS->getCapturedStmt(); 6853 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6854 auto S = C->children(); 6855 if (S.begin() == S.end()) 6856 return StmtError(); 6857 // All associated statements must be '#pragma omp section' except for 6858 // the first one. 6859 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6860 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6861 if (SectionStmt) 6862 Diag(SectionStmt->getBeginLoc(), 6863 diag::err_omp_parallel_sections_substmt_not_section); 6864 return StmtError(); 6865 } 6866 cast<OMPSectionDirective>(SectionStmt) 6867 ->setHasCancel(DSAStack->isCancelRegion()); 6868 } 6869 } else { 6870 Diag(AStmt->getBeginLoc(), 6871 diag::err_omp_parallel_sections_not_compound_stmt); 6872 return StmtError(); 6873 } 6874 6875 setFunctionHasBranchProtectedScope(); 6876 6877 return OMPParallelSectionsDirective::Create( 6878 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 6879 } 6880 6881 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 6882 Stmt *AStmt, SourceLocation StartLoc, 6883 SourceLocation EndLoc) { 6884 if (!AStmt) 6885 return StmtError(); 6886 6887 auto *CS = cast<CapturedStmt>(AStmt); 6888 // 1.2.2 OpenMP Language Terminology 6889 // Structured block - An executable statement with a single entry at the 6890 // top and a single exit at the bottom. 6891 // The point of exit cannot be a branch out of the structured block. 6892 // longjmp() and throw() must not violate the entry/exit criteria. 6893 CS->getCapturedDecl()->setNothrow(); 6894 6895 setFunctionHasBranchProtectedScope(); 6896 6897 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6898 DSAStack->isCancelRegion()); 6899 } 6900 6901 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 6902 SourceLocation EndLoc) { 6903 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 6904 } 6905 6906 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 6907 SourceLocation EndLoc) { 6908 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 6909 } 6910 6911 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 6912 SourceLocation EndLoc) { 6913 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 6914 } 6915 6916 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 6917 Stmt *AStmt, 6918 SourceLocation StartLoc, 6919 SourceLocation EndLoc) { 6920 if (!AStmt) 6921 return StmtError(); 6922 6923 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6924 6925 setFunctionHasBranchProtectedScope(); 6926 6927 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 6928 AStmt, 6929 DSAStack->getTaskgroupReductionRef()); 6930 } 6931 6932 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 6933 SourceLocation StartLoc, 6934 SourceLocation EndLoc) { 6935 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 6936 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 6937 } 6938 6939 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 6940 Stmt *AStmt, 6941 SourceLocation StartLoc, 6942 SourceLocation EndLoc) { 6943 const OMPClause *DependFound = nullptr; 6944 const OMPClause *DependSourceClause = nullptr; 6945 const OMPClause *DependSinkClause = nullptr; 6946 bool ErrorFound = false; 6947 const OMPThreadsClause *TC = nullptr; 6948 const OMPSIMDClause *SC = nullptr; 6949 for (const OMPClause *C : Clauses) { 6950 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 6951 DependFound = C; 6952 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 6953 if (DependSourceClause) { 6954 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 6955 << getOpenMPDirectiveName(OMPD_ordered) 6956 << getOpenMPClauseName(OMPC_depend) << 2; 6957 ErrorFound = true; 6958 } else { 6959 DependSourceClause = C; 6960 } 6961 if (DependSinkClause) { 6962 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6963 << 0; 6964 ErrorFound = true; 6965 } 6966 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 6967 if (DependSourceClause) { 6968 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6969 << 1; 6970 ErrorFound = true; 6971 } 6972 DependSinkClause = C; 6973 } 6974 } else if (C->getClauseKind() == OMPC_threads) { 6975 TC = cast<OMPThreadsClause>(C); 6976 } else if (C->getClauseKind() == OMPC_simd) { 6977 SC = cast<OMPSIMDClause>(C); 6978 } 6979 } 6980 if (!ErrorFound && !SC && 6981 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 6982 // OpenMP [2.8.1,simd Construct, Restrictions] 6983 // An ordered construct with the simd clause is the only OpenMP construct 6984 // that can appear in the simd region. 6985 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 6986 ErrorFound = true; 6987 } else if (DependFound && (TC || SC)) { 6988 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 6989 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 6990 ErrorFound = true; 6991 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 6992 Diag(DependFound->getBeginLoc(), 6993 diag::err_omp_ordered_directive_without_param); 6994 ErrorFound = true; 6995 } else if (TC || Clauses.empty()) { 6996 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 6997 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 6998 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 6999 << (TC != nullptr); 7000 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7001 ErrorFound = true; 7002 } 7003 } 7004 if ((!AStmt && !DependFound) || ErrorFound) 7005 return StmtError(); 7006 7007 if (AStmt) { 7008 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7009 7010 setFunctionHasBranchProtectedScope(); 7011 } 7012 7013 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7014 } 7015 7016 namespace { 7017 /// Helper class for checking expression in 'omp atomic [update]' 7018 /// construct. 7019 class OpenMPAtomicUpdateChecker { 7020 /// Error results for atomic update expressions. 7021 enum ExprAnalysisErrorCode { 7022 /// A statement is not an expression statement. 7023 NotAnExpression, 7024 /// Expression is not builtin binary or unary operation. 7025 NotABinaryOrUnaryExpression, 7026 /// Unary operation is not post-/pre- increment/decrement operation. 7027 NotAnUnaryIncDecExpression, 7028 /// An expression is not of scalar type. 7029 NotAScalarType, 7030 /// A binary operation is not an assignment operation. 7031 NotAnAssignmentOp, 7032 /// RHS part of the binary operation is not a binary expression. 7033 NotABinaryExpression, 7034 /// RHS part is not additive/multiplicative/shift/biwise binary 7035 /// expression. 7036 NotABinaryOperator, 7037 /// RHS binary operation does not have reference to the updated LHS 7038 /// part. 7039 NotAnUpdateExpression, 7040 /// No errors is found. 7041 NoError 7042 }; 7043 /// Reference to Sema. 7044 Sema &SemaRef; 7045 /// A location for note diagnostics (when error is found). 7046 SourceLocation NoteLoc; 7047 /// 'x' lvalue part of the source atomic expression. 7048 Expr *X; 7049 /// 'expr' rvalue part of the source atomic expression. 7050 Expr *E; 7051 /// Helper expression of the form 7052 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7053 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7054 Expr *UpdateExpr; 7055 /// Is 'x' a LHS in a RHS part of full update expression. It is 7056 /// important for non-associative operations. 7057 bool IsXLHSInRHSPart; 7058 BinaryOperatorKind Op; 7059 SourceLocation OpLoc; 7060 /// true if the source expression is a postfix unary operation, false 7061 /// if it is a prefix unary operation. 7062 bool IsPostfixUpdate; 7063 7064 public: 7065 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7066 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7067 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7068 /// Check specified statement that it is suitable for 'atomic update' 7069 /// constructs and extract 'x', 'expr' and Operation from the original 7070 /// expression. If DiagId and NoteId == 0, then only check is performed 7071 /// without error notification. 7072 /// \param DiagId Diagnostic which should be emitted if error is found. 7073 /// \param NoteId Diagnostic note for the main error message. 7074 /// \return true if statement is not an update expression, false otherwise. 7075 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7076 /// Return the 'x' lvalue part of the source atomic expression. 7077 Expr *getX() const { return X; } 7078 /// Return the 'expr' rvalue part of the source atomic expression. 7079 Expr *getExpr() const { return E; } 7080 /// Return the update expression used in calculation of the updated 7081 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7082 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7083 Expr *getUpdateExpr() const { return UpdateExpr; } 7084 /// Return true if 'x' is LHS in RHS part of full update expression, 7085 /// false otherwise. 7086 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7087 7088 /// true if the source expression is a postfix unary operation, false 7089 /// if it is a prefix unary operation. 7090 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7091 7092 private: 7093 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7094 unsigned NoteId = 0); 7095 }; 7096 } // namespace 7097 7098 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7099 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7100 ExprAnalysisErrorCode ErrorFound = NoError; 7101 SourceLocation ErrorLoc, NoteLoc; 7102 SourceRange ErrorRange, NoteRange; 7103 // Allowed constructs are: 7104 // x = x binop expr; 7105 // x = expr binop x; 7106 if (AtomicBinOp->getOpcode() == BO_Assign) { 7107 X = AtomicBinOp->getLHS(); 7108 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7109 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7110 if (AtomicInnerBinOp->isMultiplicativeOp() || 7111 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7112 AtomicInnerBinOp->isBitwiseOp()) { 7113 Op = AtomicInnerBinOp->getOpcode(); 7114 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7115 Expr *LHS = AtomicInnerBinOp->getLHS(); 7116 Expr *RHS = AtomicInnerBinOp->getRHS(); 7117 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7118 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7119 /*Canonical=*/true); 7120 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7121 /*Canonical=*/true); 7122 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7123 /*Canonical=*/true); 7124 if (XId == LHSId) { 7125 E = RHS; 7126 IsXLHSInRHSPart = true; 7127 } else if (XId == RHSId) { 7128 E = LHS; 7129 IsXLHSInRHSPart = false; 7130 } else { 7131 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7132 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7133 NoteLoc = X->getExprLoc(); 7134 NoteRange = X->getSourceRange(); 7135 ErrorFound = NotAnUpdateExpression; 7136 } 7137 } else { 7138 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7139 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7140 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7141 NoteRange = SourceRange(NoteLoc, NoteLoc); 7142 ErrorFound = NotABinaryOperator; 7143 } 7144 } else { 7145 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7146 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7147 ErrorFound = NotABinaryExpression; 7148 } 7149 } else { 7150 ErrorLoc = AtomicBinOp->getExprLoc(); 7151 ErrorRange = AtomicBinOp->getSourceRange(); 7152 NoteLoc = AtomicBinOp->getOperatorLoc(); 7153 NoteRange = SourceRange(NoteLoc, NoteLoc); 7154 ErrorFound = NotAnAssignmentOp; 7155 } 7156 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7157 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7158 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7159 return true; 7160 } 7161 if (SemaRef.CurContext->isDependentContext()) 7162 E = X = UpdateExpr = nullptr; 7163 return ErrorFound != NoError; 7164 } 7165 7166 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7167 unsigned NoteId) { 7168 ExprAnalysisErrorCode ErrorFound = NoError; 7169 SourceLocation ErrorLoc, NoteLoc; 7170 SourceRange ErrorRange, NoteRange; 7171 // Allowed constructs are: 7172 // x++; 7173 // x--; 7174 // ++x; 7175 // --x; 7176 // x binop= expr; 7177 // x = x binop expr; 7178 // x = expr binop x; 7179 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7180 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7181 if (AtomicBody->getType()->isScalarType() || 7182 AtomicBody->isInstantiationDependent()) { 7183 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7184 AtomicBody->IgnoreParenImpCasts())) { 7185 // Check for Compound Assignment Operation 7186 Op = BinaryOperator::getOpForCompoundAssignment( 7187 AtomicCompAssignOp->getOpcode()); 7188 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7189 E = AtomicCompAssignOp->getRHS(); 7190 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7191 IsXLHSInRHSPart = true; 7192 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7193 AtomicBody->IgnoreParenImpCasts())) { 7194 // Check for Binary Operation 7195 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7196 return true; 7197 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7198 AtomicBody->IgnoreParenImpCasts())) { 7199 // Check for Unary Operation 7200 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7201 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7202 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7203 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7204 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7205 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7206 IsXLHSInRHSPart = true; 7207 } else { 7208 ErrorFound = NotAnUnaryIncDecExpression; 7209 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7210 ErrorRange = AtomicUnaryOp->getSourceRange(); 7211 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7212 NoteRange = SourceRange(NoteLoc, NoteLoc); 7213 } 7214 } else if (!AtomicBody->isInstantiationDependent()) { 7215 ErrorFound = NotABinaryOrUnaryExpression; 7216 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7217 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7218 } 7219 } else { 7220 ErrorFound = NotAScalarType; 7221 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7222 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7223 } 7224 } else { 7225 ErrorFound = NotAnExpression; 7226 NoteLoc = ErrorLoc = S->getBeginLoc(); 7227 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7228 } 7229 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7230 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7231 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7232 return true; 7233 } 7234 if (SemaRef.CurContext->isDependentContext()) 7235 E = X = UpdateExpr = nullptr; 7236 if (ErrorFound == NoError && E && X) { 7237 // Build an update expression of form 'OpaqueValueExpr(x) binop 7238 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7239 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7240 auto *OVEX = new (SemaRef.getASTContext()) 7241 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7242 auto *OVEExpr = new (SemaRef.getASTContext()) 7243 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7244 ExprResult Update = 7245 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7246 IsXLHSInRHSPart ? OVEExpr : OVEX); 7247 if (Update.isInvalid()) 7248 return true; 7249 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7250 Sema::AA_Casting); 7251 if (Update.isInvalid()) 7252 return true; 7253 UpdateExpr = Update.get(); 7254 } 7255 return ErrorFound != NoError; 7256 } 7257 7258 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7259 Stmt *AStmt, 7260 SourceLocation StartLoc, 7261 SourceLocation EndLoc) { 7262 if (!AStmt) 7263 return StmtError(); 7264 7265 auto *CS = cast<CapturedStmt>(AStmt); 7266 // 1.2.2 OpenMP Language Terminology 7267 // Structured block - An executable statement with a single entry at the 7268 // top and a single exit at the bottom. 7269 // The point of exit cannot be a branch out of the structured block. 7270 // longjmp() and throw() must not violate the entry/exit criteria. 7271 OpenMPClauseKind AtomicKind = OMPC_unknown; 7272 SourceLocation AtomicKindLoc; 7273 for (const OMPClause *C : Clauses) { 7274 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7275 C->getClauseKind() == OMPC_update || 7276 C->getClauseKind() == OMPC_capture) { 7277 if (AtomicKind != OMPC_unknown) { 7278 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7279 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7280 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7281 << getOpenMPClauseName(AtomicKind); 7282 } else { 7283 AtomicKind = C->getClauseKind(); 7284 AtomicKindLoc = C->getBeginLoc(); 7285 } 7286 } 7287 } 7288 7289 Stmt *Body = CS->getCapturedStmt(); 7290 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7291 Body = EWC->getSubExpr(); 7292 7293 Expr *X = nullptr; 7294 Expr *V = nullptr; 7295 Expr *E = nullptr; 7296 Expr *UE = nullptr; 7297 bool IsXLHSInRHSPart = false; 7298 bool IsPostfixUpdate = false; 7299 // OpenMP [2.12.6, atomic Construct] 7300 // In the next expressions: 7301 // * x and v (as applicable) are both l-value expressions with scalar type. 7302 // * During the execution of an atomic region, multiple syntactic 7303 // occurrences of x must designate the same storage location. 7304 // * Neither of v and expr (as applicable) may access the storage location 7305 // designated by x. 7306 // * Neither of x and expr (as applicable) may access the storage location 7307 // designated by v. 7308 // * expr is an expression with scalar type. 7309 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7310 // * binop, binop=, ++, and -- are not overloaded operators. 7311 // * The expression x binop expr must be numerically equivalent to x binop 7312 // (expr). This requirement is satisfied if the operators in expr have 7313 // precedence greater than binop, or by using parentheses around expr or 7314 // subexpressions of expr. 7315 // * The expression expr binop x must be numerically equivalent to (expr) 7316 // binop x. This requirement is satisfied if the operators in expr have 7317 // precedence equal to or greater than binop, or by using parentheses around 7318 // expr or subexpressions of expr. 7319 // * For forms that allow multiple occurrences of x, the number of times 7320 // that x is evaluated is unspecified. 7321 if (AtomicKind == OMPC_read) { 7322 enum { 7323 NotAnExpression, 7324 NotAnAssignmentOp, 7325 NotAScalarType, 7326 NotAnLValue, 7327 NoError 7328 } ErrorFound = NoError; 7329 SourceLocation ErrorLoc, NoteLoc; 7330 SourceRange ErrorRange, NoteRange; 7331 // If clause is read: 7332 // v = x; 7333 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7334 const auto *AtomicBinOp = 7335 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7336 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7337 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7338 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7339 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7340 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7341 if (!X->isLValue() || !V->isLValue()) { 7342 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7343 ErrorFound = NotAnLValue; 7344 ErrorLoc = AtomicBinOp->getExprLoc(); 7345 ErrorRange = AtomicBinOp->getSourceRange(); 7346 NoteLoc = NotLValueExpr->getExprLoc(); 7347 NoteRange = NotLValueExpr->getSourceRange(); 7348 } 7349 } else if (!X->isInstantiationDependent() || 7350 !V->isInstantiationDependent()) { 7351 const Expr *NotScalarExpr = 7352 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7353 ? V 7354 : X; 7355 ErrorFound = NotAScalarType; 7356 ErrorLoc = AtomicBinOp->getExprLoc(); 7357 ErrorRange = AtomicBinOp->getSourceRange(); 7358 NoteLoc = NotScalarExpr->getExprLoc(); 7359 NoteRange = NotScalarExpr->getSourceRange(); 7360 } 7361 } else if (!AtomicBody->isInstantiationDependent()) { 7362 ErrorFound = NotAnAssignmentOp; 7363 ErrorLoc = AtomicBody->getExprLoc(); 7364 ErrorRange = AtomicBody->getSourceRange(); 7365 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7366 : AtomicBody->getExprLoc(); 7367 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7368 : AtomicBody->getSourceRange(); 7369 } 7370 } else { 7371 ErrorFound = NotAnExpression; 7372 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7373 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7374 } 7375 if (ErrorFound != NoError) { 7376 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7377 << ErrorRange; 7378 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7379 << NoteRange; 7380 return StmtError(); 7381 } 7382 if (CurContext->isDependentContext()) 7383 V = X = nullptr; 7384 } else if (AtomicKind == OMPC_write) { 7385 enum { 7386 NotAnExpression, 7387 NotAnAssignmentOp, 7388 NotAScalarType, 7389 NotAnLValue, 7390 NoError 7391 } ErrorFound = NoError; 7392 SourceLocation ErrorLoc, NoteLoc; 7393 SourceRange ErrorRange, NoteRange; 7394 // If clause is write: 7395 // x = expr; 7396 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7397 const auto *AtomicBinOp = 7398 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7399 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7400 X = AtomicBinOp->getLHS(); 7401 E = AtomicBinOp->getRHS(); 7402 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7403 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 7404 if (!X->isLValue()) { 7405 ErrorFound = NotAnLValue; 7406 ErrorLoc = AtomicBinOp->getExprLoc(); 7407 ErrorRange = AtomicBinOp->getSourceRange(); 7408 NoteLoc = X->getExprLoc(); 7409 NoteRange = X->getSourceRange(); 7410 } 7411 } else if (!X->isInstantiationDependent() || 7412 !E->isInstantiationDependent()) { 7413 const Expr *NotScalarExpr = 7414 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7415 ? E 7416 : X; 7417 ErrorFound = NotAScalarType; 7418 ErrorLoc = AtomicBinOp->getExprLoc(); 7419 ErrorRange = AtomicBinOp->getSourceRange(); 7420 NoteLoc = NotScalarExpr->getExprLoc(); 7421 NoteRange = NotScalarExpr->getSourceRange(); 7422 } 7423 } else if (!AtomicBody->isInstantiationDependent()) { 7424 ErrorFound = NotAnAssignmentOp; 7425 ErrorLoc = AtomicBody->getExprLoc(); 7426 ErrorRange = AtomicBody->getSourceRange(); 7427 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7428 : AtomicBody->getExprLoc(); 7429 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7430 : AtomicBody->getSourceRange(); 7431 } 7432 } else { 7433 ErrorFound = NotAnExpression; 7434 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7435 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7436 } 7437 if (ErrorFound != NoError) { 7438 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7439 << ErrorRange; 7440 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7441 << NoteRange; 7442 return StmtError(); 7443 } 7444 if (CurContext->isDependentContext()) 7445 E = X = nullptr; 7446 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7447 // If clause is update: 7448 // x++; 7449 // x--; 7450 // ++x; 7451 // --x; 7452 // x binop= expr; 7453 // x = x binop expr; 7454 // x = expr binop x; 7455 OpenMPAtomicUpdateChecker Checker(*this); 7456 if (Checker.checkStatement( 7457 Body, (AtomicKind == OMPC_update) 7458 ? diag::err_omp_atomic_update_not_expression_statement 7459 : diag::err_omp_atomic_not_expression_statement, 7460 diag::note_omp_atomic_update)) 7461 return StmtError(); 7462 if (!CurContext->isDependentContext()) { 7463 E = Checker.getExpr(); 7464 X = Checker.getX(); 7465 UE = Checker.getUpdateExpr(); 7466 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7467 } 7468 } else if (AtomicKind == OMPC_capture) { 7469 enum { 7470 NotAnAssignmentOp, 7471 NotACompoundStatement, 7472 NotTwoSubstatements, 7473 NotASpecificExpression, 7474 NoError 7475 } ErrorFound = NoError; 7476 SourceLocation ErrorLoc, NoteLoc; 7477 SourceRange ErrorRange, NoteRange; 7478 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7479 // If clause is a capture: 7480 // v = x++; 7481 // v = x--; 7482 // v = ++x; 7483 // v = --x; 7484 // v = x binop= expr; 7485 // v = x = x binop expr; 7486 // v = x = expr binop x; 7487 const auto *AtomicBinOp = 7488 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7489 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7490 V = AtomicBinOp->getLHS(); 7491 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7492 OpenMPAtomicUpdateChecker Checker(*this); 7493 if (Checker.checkStatement( 7494 Body, diag::err_omp_atomic_capture_not_expression_statement, 7495 diag::note_omp_atomic_update)) 7496 return StmtError(); 7497 E = Checker.getExpr(); 7498 X = Checker.getX(); 7499 UE = Checker.getUpdateExpr(); 7500 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7501 IsPostfixUpdate = Checker.isPostfixUpdate(); 7502 } else if (!AtomicBody->isInstantiationDependent()) { 7503 ErrorLoc = AtomicBody->getExprLoc(); 7504 ErrorRange = AtomicBody->getSourceRange(); 7505 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7506 : AtomicBody->getExprLoc(); 7507 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7508 : AtomicBody->getSourceRange(); 7509 ErrorFound = NotAnAssignmentOp; 7510 } 7511 if (ErrorFound != NoError) { 7512 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7513 << ErrorRange; 7514 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7515 return StmtError(); 7516 } 7517 if (CurContext->isDependentContext()) 7518 UE = V = E = X = nullptr; 7519 } else { 7520 // If clause is a capture: 7521 // { v = x; x = expr; } 7522 // { v = x; x++; } 7523 // { v = x; x--; } 7524 // { v = x; ++x; } 7525 // { v = x; --x; } 7526 // { v = x; x binop= expr; } 7527 // { v = x; x = x binop expr; } 7528 // { v = x; x = expr binop x; } 7529 // { x++; v = x; } 7530 // { x--; v = x; } 7531 // { ++x; v = x; } 7532 // { --x; v = x; } 7533 // { x binop= expr; v = x; } 7534 // { x = x binop expr; v = x; } 7535 // { x = expr binop x; v = x; } 7536 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7537 // Check that this is { expr1; expr2; } 7538 if (CS->size() == 2) { 7539 Stmt *First = CS->body_front(); 7540 Stmt *Second = CS->body_back(); 7541 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7542 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7543 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7544 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7545 // Need to find what subexpression is 'v' and what is 'x'. 7546 OpenMPAtomicUpdateChecker Checker(*this); 7547 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7548 BinaryOperator *BinOp = nullptr; 7549 if (IsUpdateExprFound) { 7550 BinOp = dyn_cast<BinaryOperator>(First); 7551 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7552 } 7553 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7554 // { v = x; x++; } 7555 // { v = x; x--; } 7556 // { v = x; ++x; } 7557 // { v = x; --x; } 7558 // { v = x; x binop= expr; } 7559 // { v = x; x = x binop expr; } 7560 // { v = x; x = expr binop x; } 7561 // Check that the first expression has form v = x. 7562 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7563 llvm::FoldingSetNodeID XId, PossibleXId; 7564 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7565 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7566 IsUpdateExprFound = XId == PossibleXId; 7567 if (IsUpdateExprFound) { 7568 V = BinOp->getLHS(); 7569 X = Checker.getX(); 7570 E = Checker.getExpr(); 7571 UE = Checker.getUpdateExpr(); 7572 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7573 IsPostfixUpdate = true; 7574 } 7575 } 7576 if (!IsUpdateExprFound) { 7577 IsUpdateExprFound = !Checker.checkStatement(First); 7578 BinOp = nullptr; 7579 if (IsUpdateExprFound) { 7580 BinOp = dyn_cast<BinaryOperator>(Second); 7581 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7582 } 7583 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7584 // { x++; v = x; } 7585 // { x--; v = x; } 7586 // { ++x; v = x; } 7587 // { --x; v = x; } 7588 // { x binop= expr; v = x; } 7589 // { x = x binop expr; v = x; } 7590 // { x = expr binop x; v = x; } 7591 // Check that the second expression has form v = x. 7592 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7593 llvm::FoldingSetNodeID XId, PossibleXId; 7594 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7595 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7596 IsUpdateExprFound = XId == PossibleXId; 7597 if (IsUpdateExprFound) { 7598 V = BinOp->getLHS(); 7599 X = Checker.getX(); 7600 E = Checker.getExpr(); 7601 UE = Checker.getUpdateExpr(); 7602 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7603 IsPostfixUpdate = false; 7604 } 7605 } 7606 } 7607 if (!IsUpdateExprFound) { 7608 // { v = x; x = expr; } 7609 auto *FirstExpr = dyn_cast<Expr>(First); 7610 auto *SecondExpr = dyn_cast<Expr>(Second); 7611 if (!FirstExpr || !SecondExpr || 7612 !(FirstExpr->isInstantiationDependent() || 7613 SecondExpr->isInstantiationDependent())) { 7614 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7615 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7616 ErrorFound = NotAnAssignmentOp; 7617 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7618 : First->getBeginLoc(); 7619 NoteRange = ErrorRange = FirstBinOp 7620 ? FirstBinOp->getSourceRange() 7621 : SourceRange(ErrorLoc, ErrorLoc); 7622 } else { 7623 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7624 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7625 ErrorFound = NotAnAssignmentOp; 7626 NoteLoc = ErrorLoc = SecondBinOp 7627 ? SecondBinOp->getOperatorLoc() 7628 : Second->getBeginLoc(); 7629 NoteRange = ErrorRange = 7630 SecondBinOp ? SecondBinOp->getSourceRange() 7631 : SourceRange(ErrorLoc, ErrorLoc); 7632 } else { 7633 Expr *PossibleXRHSInFirst = 7634 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7635 Expr *PossibleXLHSInSecond = 7636 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7637 llvm::FoldingSetNodeID X1Id, X2Id; 7638 PossibleXRHSInFirst->Profile(X1Id, Context, 7639 /*Canonical=*/true); 7640 PossibleXLHSInSecond->Profile(X2Id, Context, 7641 /*Canonical=*/true); 7642 IsUpdateExprFound = X1Id == X2Id; 7643 if (IsUpdateExprFound) { 7644 V = FirstBinOp->getLHS(); 7645 X = SecondBinOp->getLHS(); 7646 E = SecondBinOp->getRHS(); 7647 UE = nullptr; 7648 IsXLHSInRHSPart = false; 7649 IsPostfixUpdate = true; 7650 } else { 7651 ErrorFound = NotASpecificExpression; 7652 ErrorLoc = FirstBinOp->getExprLoc(); 7653 ErrorRange = FirstBinOp->getSourceRange(); 7654 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7655 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7656 } 7657 } 7658 } 7659 } 7660 } 7661 } else { 7662 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7663 NoteRange = ErrorRange = 7664 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7665 ErrorFound = NotTwoSubstatements; 7666 } 7667 } else { 7668 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7669 NoteRange = ErrorRange = 7670 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7671 ErrorFound = NotACompoundStatement; 7672 } 7673 if (ErrorFound != NoError) { 7674 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7675 << ErrorRange; 7676 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7677 return StmtError(); 7678 } 7679 if (CurContext->isDependentContext()) 7680 UE = V = E = X = nullptr; 7681 } 7682 } 7683 7684 setFunctionHasBranchProtectedScope(); 7685 7686 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7687 X, V, E, UE, IsXLHSInRHSPart, 7688 IsPostfixUpdate); 7689 } 7690 7691 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7692 Stmt *AStmt, 7693 SourceLocation StartLoc, 7694 SourceLocation EndLoc) { 7695 if (!AStmt) 7696 return StmtError(); 7697 7698 auto *CS = cast<CapturedStmt>(AStmt); 7699 // 1.2.2 OpenMP Language Terminology 7700 // Structured block - An executable statement with a single entry at the 7701 // top and a single exit at the bottom. 7702 // The point of exit cannot be a branch out of the structured block. 7703 // longjmp() and throw() must not violate the entry/exit criteria. 7704 CS->getCapturedDecl()->setNothrow(); 7705 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7706 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7707 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7708 // 1.2.2 OpenMP Language Terminology 7709 // Structured block - An executable statement with a single entry at the 7710 // top and a single exit at the bottom. 7711 // The point of exit cannot be a branch out of the structured block. 7712 // longjmp() and throw() must not violate the entry/exit criteria. 7713 CS->getCapturedDecl()->setNothrow(); 7714 } 7715 7716 // OpenMP [2.16, Nesting of Regions] 7717 // If specified, a teams construct must be contained within a target 7718 // construct. That target construct must contain no statements or directives 7719 // outside of the teams construct. 7720 if (DSAStack->hasInnerTeamsRegion()) { 7721 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7722 bool OMPTeamsFound = true; 7723 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7724 auto I = CS->body_begin(); 7725 while (I != CS->body_end()) { 7726 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7727 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7728 OMPTeamsFound) { 7729 7730 OMPTeamsFound = false; 7731 break; 7732 } 7733 ++I; 7734 } 7735 assert(I != CS->body_end() && "Not found statement"); 7736 S = *I; 7737 } else { 7738 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7739 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7740 } 7741 if (!OMPTeamsFound) { 7742 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7743 Diag(DSAStack->getInnerTeamsRegionLoc(), 7744 diag::note_omp_nested_teams_construct_here); 7745 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7746 << isa<OMPExecutableDirective>(S); 7747 return StmtError(); 7748 } 7749 } 7750 7751 setFunctionHasBranchProtectedScope(); 7752 7753 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7754 } 7755 7756 StmtResult 7757 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7758 Stmt *AStmt, SourceLocation StartLoc, 7759 SourceLocation EndLoc) { 7760 if (!AStmt) 7761 return StmtError(); 7762 7763 auto *CS = cast<CapturedStmt>(AStmt); 7764 // 1.2.2 OpenMP Language Terminology 7765 // Structured block - An executable statement with a single entry at the 7766 // top and a single exit at the bottom. 7767 // The point of exit cannot be a branch out of the structured block. 7768 // longjmp() and throw() must not violate the entry/exit criteria. 7769 CS->getCapturedDecl()->setNothrow(); 7770 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7771 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7772 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7773 // 1.2.2 OpenMP Language Terminology 7774 // Structured block - An executable statement with a single entry at the 7775 // top and a single exit at the bottom. 7776 // The point of exit cannot be a branch out of the structured block. 7777 // longjmp() and throw() must not violate the entry/exit criteria. 7778 CS->getCapturedDecl()->setNothrow(); 7779 } 7780 7781 setFunctionHasBranchProtectedScope(); 7782 7783 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7784 AStmt); 7785 } 7786 7787 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7788 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7789 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7790 if (!AStmt) 7791 return StmtError(); 7792 7793 auto *CS = cast<CapturedStmt>(AStmt); 7794 // 1.2.2 OpenMP Language Terminology 7795 // Structured block - An executable statement with a single entry at the 7796 // top and a single exit at the bottom. 7797 // The point of exit cannot be a branch out of the structured block. 7798 // longjmp() and throw() must not violate the entry/exit criteria. 7799 CS->getCapturedDecl()->setNothrow(); 7800 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7801 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7802 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7803 // 1.2.2 OpenMP Language Terminology 7804 // Structured block - An executable statement with a single entry at the 7805 // top and a single exit at the bottom. 7806 // The point of exit cannot be a branch out of the structured block. 7807 // longjmp() and throw() must not violate the entry/exit criteria. 7808 CS->getCapturedDecl()->setNothrow(); 7809 } 7810 7811 OMPLoopDirective::HelperExprs B; 7812 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7813 // define the nested loops number. 7814 unsigned NestedLoopCount = 7815 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 7816 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7817 VarsWithImplicitDSA, B); 7818 if (NestedLoopCount == 0) 7819 return StmtError(); 7820 7821 assert((CurContext->isDependentContext() || B.builtAll()) && 7822 "omp target parallel for loop exprs were not built"); 7823 7824 if (!CurContext->isDependentContext()) { 7825 // Finalize the clauses that need pre-built expressions for CodeGen. 7826 for (OMPClause *C : Clauses) { 7827 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7828 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7829 B.NumIterations, *this, CurScope, 7830 DSAStack)) 7831 return StmtError(); 7832 } 7833 } 7834 7835 setFunctionHasBranchProtectedScope(); 7836 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 7837 NestedLoopCount, Clauses, AStmt, 7838 B, DSAStack->isCancelRegion()); 7839 } 7840 7841 /// Check for existence of a map clause in the list of clauses. 7842 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 7843 const OpenMPClauseKind K) { 7844 return llvm::any_of( 7845 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 7846 } 7847 7848 template <typename... Params> 7849 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 7850 const Params... ClauseTypes) { 7851 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 7852 } 7853 7854 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 7855 Stmt *AStmt, 7856 SourceLocation StartLoc, 7857 SourceLocation EndLoc) { 7858 if (!AStmt) 7859 return StmtError(); 7860 7861 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7862 7863 // OpenMP [2.10.1, Restrictions, p. 97] 7864 // At least one map clause must appear on the directive. 7865 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 7866 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7867 << "'map' or 'use_device_ptr'" 7868 << getOpenMPDirectiveName(OMPD_target_data); 7869 return StmtError(); 7870 } 7871 7872 setFunctionHasBranchProtectedScope(); 7873 7874 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7875 AStmt); 7876 } 7877 7878 StmtResult 7879 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 7880 SourceLocation StartLoc, 7881 SourceLocation EndLoc, Stmt *AStmt) { 7882 if (!AStmt) 7883 return StmtError(); 7884 7885 auto *CS = cast<CapturedStmt>(AStmt); 7886 // 1.2.2 OpenMP Language Terminology 7887 // Structured block - An executable statement with a single entry at the 7888 // top and a single exit at the bottom. 7889 // The point of exit cannot be a branch out of the structured block. 7890 // longjmp() and throw() must not violate the entry/exit criteria. 7891 CS->getCapturedDecl()->setNothrow(); 7892 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 7893 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7894 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7895 // 1.2.2 OpenMP Language Terminology 7896 // Structured block - An executable statement with a single entry at the 7897 // top and a single exit at the bottom. 7898 // The point of exit cannot be a branch out of the structured block. 7899 // longjmp() and throw() must not violate the entry/exit criteria. 7900 CS->getCapturedDecl()->setNothrow(); 7901 } 7902 7903 // OpenMP [2.10.2, Restrictions, p. 99] 7904 // At least one map clause must appear on the directive. 7905 if (!hasClauses(Clauses, OMPC_map)) { 7906 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7907 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 7908 return StmtError(); 7909 } 7910 7911 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7912 AStmt); 7913 } 7914 7915 StmtResult 7916 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 7917 SourceLocation StartLoc, 7918 SourceLocation EndLoc, Stmt *AStmt) { 7919 if (!AStmt) 7920 return StmtError(); 7921 7922 auto *CS = cast<CapturedStmt>(AStmt); 7923 // 1.2.2 OpenMP Language Terminology 7924 // Structured block - An executable statement with a single entry at the 7925 // top and a single exit at the bottom. 7926 // The point of exit cannot be a branch out of the structured block. 7927 // longjmp() and throw() must not violate the entry/exit criteria. 7928 CS->getCapturedDecl()->setNothrow(); 7929 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 7930 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7931 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7932 // 1.2.2 OpenMP Language Terminology 7933 // Structured block - An executable statement with a single entry at the 7934 // top and a single exit at the bottom. 7935 // The point of exit cannot be a branch out of the structured block. 7936 // longjmp() and throw() must not violate the entry/exit criteria. 7937 CS->getCapturedDecl()->setNothrow(); 7938 } 7939 7940 // OpenMP [2.10.3, Restrictions, p. 102] 7941 // At least one map clause must appear on the directive. 7942 if (!hasClauses(Clauses, OMPC_map)) { 7943 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7944 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 7945 return StmtError(); 7946 } 7947 7948 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7949 AStmt); 7950 } 7951 7952 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 7953 SourceLocation StartLoc, 7954 SourceLocation EndLoc, 7955 Stmt *AStmt) { 7956 if (!AStmt) 7957 return StmtError(); 7958 7959 auto *CS = cast<CapturedStmt>(AStmt); 7960 // 1.2.2 OpenMP Language Terminology 7961 // Structured block - An executable statement with a single entry at the 7962 // top and a single exit at the bottom. 7963 // The point of exit cannot be a branch out of the structured block. 7964 // longjmp() and throw() must not violate the entry/exit criteria. 7965 CS->getCapturedDecl()->setNothrow(); 7966 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 7967 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7968 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7969 // 1.2.2 OpenMP Language Terminology 7970 // Structured block - An executable statement with a single entry at the 7971 // top and a single exit at the bottom. 7972 // The point of exit cannot be a branch out of the structured block. 7973 // longjmp() and throw() must not violate the entry/exit criteria. 7974 CS->getCapturedDecl()->setNothrow(); 7975 } 7976 7977 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 7978 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 7979 return StmtError(); 7980 } 7981 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 7982 AStmt); 7983 } 7984 7985 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 7986 Stmt *AStmt, SourceLocation StartLoc, 7987 SourceLocation EndLoc) { 7988 if (!AStmt) 7989 return StmtError(); 7990 7991 auto *CS = cast<CapturedStmt>(AStmt); 7992 // 1.2.2 OpenMP Language Terminology 7993 // Structured block - An executable statement with a single entry at the 7994 // top and a single exit at the bottom. 7995 // The point of exit cannot be a branch out of the structured block. 7996 // longjmp() and throw() must not violate the entry/exit criteria. 7997 CS->getCapturedDecl()->setNothrow(); 7998 7999 setFunctionHasBranchProtectedScope(); 8000 8001 DSAStack->setParentTeamsRegionLoc(StartLoc); 8002 8003 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8004 } 8005 8006 StmtResult 8007 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8008 SourceLocation EndLoc, 8009 OpenMPDirectiveKind CancelRegion) { 8010 if (DSAStack->isParentNowaitRegion()) { 8011 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8012 return StmtError(); 8013 } 8014 if (DSAStack->isParentOrderedRegion()) { 8015 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8016 return StmtError(); 8017 } 8018 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8019 CancelRegion); 8020 } 8021 8022 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8023 SourceLocation StartLoc, 8024 SourceLocation EndLoc, 8025 OpenMPDirectiveKind CancelRegion) { 8026 if (DSAStack->isParentNowaitRegion()) { 8027 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8028 return StmtError(); 8029 } 8030 if (DSAStack->isParentOrderedRegion()) { 8031 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8032 return StmtError(); 8033 } 8034 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8035 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8036 CancelRegion); 8037 } 8038 8039 static bool checkGrainsizeNumTasksClauses(Sema &S, 8040 ArrayRef<OMPClause *> Clauses) { 8041 const OMPClause *PrevClause = nullptr; 8042 bool ErrorFound = false; 8043 for (const OMPClause *C : Clauses) { 8044 if (C->getClauseKind() == OMPC_grainsize || 8045 C->getClauseKind() == OMPC_num_tasks) { 8046 if (!PrevClause) 8047 PrevClause = C; 8048 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8049 S.Diag(C->getBeginLoc(), 8050 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8051 << getOpenMPClauseName(C->getClauseKind()) 8052 << getOpenMPClauseName(PrevClause->getClauseKind()); 8053 S.Diag(PrevClause->getBeginLoc(), 8054 diag::note_omp_previous_grainsize_num_tasks) 8055 << getOpenMPClauseName(PrevClause->getClauseKind()); 8056 ErrorFound = true; 8057 } 8058 } 8059 } 8060 return ErrorFound; 8061 } 8062 8063 static bool checkReductionClauseWithNogroup(Sema &S, 8064 ArrayRef<OMPClause *> Clauses) { 8065 const OMPClause *ReductionClause = nullptr; 8066 const OMPClause *NogroupClause = nullptr; 8067 for (const OMPClause *C : Clauses) { 8068 if (C->getClauseKind() == OMPC_reduction) { 8069 ReductionClause = C; 8070 if (NogroupClause) 8071 break; 8072 continue; 8073 } 8074 if (C->getClauseKind() == OMPC_nogroup) { 8075 NogroupClause = C; 8076 if (ReductionClause) 8077 break; 8078 continue; 8079 } 8080 } 8081 if (ReductionClause && NogroupClause) { 8082 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8083 << SourceRange(NogroupClause->getBeginLoc(), 8084 NogroupClause->getEndLoc()); 8085 return true; 8086 } 8087 return false; 8088 } 8089 8090 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8091 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8092 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8093 if (!AStmt) 8094 return StmtError(); 8095 8096 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8097 OMPLoopDirective::HelperExprs B; 8098 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8099 // define the nested loops number. 8100 unsigned NestedLoopCount = 8101 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8102 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8103 VarsWithImplicitDSA, B); 8104 if (NestedLoopCount == 0) 8105 return StmtError(); 8106 8107 assert((CurContext->isDependentContext() || B.builtAll()) && 8108 "omp for loop exprs were not built"); 8109 8110 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8111 // The grainsize clause and num_tasks clause are mutually exclusive and may 8112 // not appear on the same taskloop directive. 8113 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8114 return StmtError(); 8115 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8116 // If a reduction clause is present on the taskloop directive, the nogroup 8117 // clause must not be specified. 8118 if (checkReductionClauseWithNogroup(*this, Clauses)) 8119 return StmtError(); 8120 8121 setFunctionHasBranchProtectedScope(); 8122 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8123 NestedLoopCount, Clauses, AStmt, B); 8124 } 8125 8126 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8127 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8128 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8129 if (!AStmt) 8130 return StmtError(); 8131 8132 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8133 OMPLoopDirective::HelperExprs B; 8134 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8135 // define the nested loops number. 8136 unsigned NestedLoopCount = 8137 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8138 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8139 VarsWithImplicitDSA, B); 8140 if (NestedLoopCount == 0) 8141 return StmtError(); 8142 8143 assert((CurContext->isDependentContext() || B.builtAll()) && 8144 "omp for loop exprs were not built"); 8145 8146 if (!CurContext->isDependentContext()) { 8147 // Finalize the clauses that need pre-built expressions for CodeGen. 8148 for (OMPClause *C : Clauses) { 8149 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8150 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8151 B.NumIterations, *this, CurScope, 8152 DSAStack)) 8153 return StmtError(); 8154 } 8155 } 8156 8157 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8158 // The grainsize clause and num_tasks clause are mutually exclusive and may 8159 // not appear on the same taskloop directive. 8160 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8161 return StmtError(); 8162 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8163 // If a reduction clause is present on the taskloop directive, the nogroup 8164 // clause must not be specified. 8165 if (checkReductionClauseWithNogroup(*this, Clauses)) 8166 return StmtError(); 8167 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8168 return StmtError(); 8169 8170 setFunctionHasBranchProtectedScope(); 8171 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8172 NestedLoopCount, Clauses, AStmt, B); 8173 } 8174 8175 StmtResult Sema::ActOnOpenMPDistributeDirective( 8176 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8177 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8178 if (!AStmt) 8179 return StmtError(); 8180 8181 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8182 OMPLoopDirective::HelperExprs B; 8183 // In presence of clause 'collapse' with number of loops, it will 8184 // define the nested loops number. 8185 unsigned NestedLoopCount = 8186 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8187 nullptr /*ordered not a clause on distribute*/, AStmt, 8188 *this, *DSAStack, VarsWithImplicitDSA, B); 8189 if (NestedLoopCount == 0) 8190 return StmtError(); 8191 8192 assert((CurContext->isDependentContext() || B.builtAll()) && 8193 "omp for loop exprs were not built"); 8194 8195 setFunctionHasBranchProtectedScope(); 8196 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8197 NestedLoopCount, Clauses, AStmt, B); 8198 } 8199 8200 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8201 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8202 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8203 if (!AStmt) 8204 return StmtError(); 8205 8206 auto *CS = cast<CapturedStmt>(AStmt); 8207 // 1.2.2 OpenMP Language Terminology 8208 // Structured block - An executable statement with a single entry at the 8209 // top and a single exit at the bottom. 8210 // The point of exit cannot be a branch out of the structured block. 8211 // longjmp() and throw() must not violate the entry/exit criteria. 8212 CS->getCapturedDecl()->setNothrow(); 8213 for (int ThisCaptureLevel = 8214 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8215 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8216 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8217 // 1.2.2 OpenMP Language Terminology 8218 // Structured block - An executable statement with a single entry at the 8219 // top and a single exit at the bottom. 8220 // The point of exit cannot be a branch out of the structured block. 8221 // longjmp() and throw() must not violate the entry/exit criteria. 8222 CS->getCapturedDecl()->setNothrow(); 8223 } 8224 8225 OMPLoopDirective::HelperExprs B; 8226 // In presence of clause 'collapse' with number of loops, it will 8227 // define the nested loops number. 8228 unsigned NestedLoopCount = checkOpenMPLoop( 8229 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8230 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8231 VarsWithImplicitDSA, B); 8232 if (NestedLoopCount == 0) 8233 return StmtError(); 8234 8235 assert((CurContext->isDependentContext() || B.builtAll()) && 8236 "omp for loop exprs were not built"); 8237 8238 setFunctionHasBranchProtectedScope(); 8239 return OMPDistributeParallelForDirective::Create( 8240 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8241 DSAStack->isCancelRegion()); 8242 } 8243 8244 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8245 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8246 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8247 if (!AStmt) 8248 return StmtError(); 8249 8250 auto *CS = cast<CapturedStmt>(AStmt); 8251 // 1.2.2 OpenMP Language Terminology 8252 // Structured block - An executable statement with a single entry at the 8253 // top and a single exit at the bottom. 8254 // The point of exit cannot be a branch out of the structured block. 8255 // longjmp() and throw() must not violate the entry/exit criteria. 8256 CS->getCapturedDecl()->setNothrow(); 8257 for (int ThisCaptureLevel = 8258 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8259 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8260 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8261 // 1.2.2 OpenMP Language Terminology 8262 // Structured block - An executable statement with a single entry at the 8263 // top and a single exit at the bottom. 8264 // The point of exit cannot be a branch out of the structured block. 8265 // longjmp() and throw() must not violate the entry/exit criteria. 8266 CS->getCapturedDecl()->setNothrow(); 8267 } 8268 8269 OMPLoopDirective::HelperExprs B; 8270 // In presence of clause 'collapse' with number of loops, it will 8271 // define the nested loops number. 8272 unsigned NestedLoopCount = checkOpenMPLoop( 8273 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8274 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8275 VarsWithImplicitDSA, B); 8276 if (NestedLoopCount == 0) 8277 return StmtError(); 8278 8279 assert((CurContext->isDependentContext() || B.builtAll()) && 8280 "omp for loop exprs were not built"); 8281 8282 if (!CurContext->isDependentContext()) { 8283 // Finalize the clauses that need pre-built expressions for CodeGen. 8284 for (OMPClause *C : Clauses) { 8285 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8286 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8287 B.NumIterations, *this, CurScope, 8288 DSAStack)) 8289 return StmtError(); 8290 } 8291 } 8292 8293 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8294 return StmtError(); 8295 8296 setFunctionHasBranchProtectedScope(); 8297 return OMPDistributeParallelForSimdDirective::Create( 8298 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8299 } 8300 8301 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8302 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8303 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8304 if (!AStmt) 8305 return StmtError(); 8306 8307 auto *CS = cast<CapturedStmt>(AStmt); 8308 // 1.2.2 OpenMP Language Terminology 8309 // Structured block - An executable statement with a single entry at the 8310 // top and a single exit at the bottom. 8311 // The point of exit cannot be a branch out of the structured block. 8312 // longjmp() and throw() must not violate the entry/exit criteria. 8313 CS->getCapturedDecl()->setNothrow(); 8314 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8315 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8316 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8317 // 1.2.2 OpenMP Language Terminology 8318 // Structured block - An executable statement with a single entry at the 8319 // top and a single exit at the bottom. 8320 // The point of exit cannot be a branch out of the structured block. 8321 // longjmp() and throw() must not violate the entry/exit criteria. 8322 CS->getCapturedDecl()->setNothrow(); 8323 } 8324 8325 OMPLoopDirective::HelperExprs B; 8326 // In presence of clause 'collapse' with number of loops, it will 8327 // define the nested loops number. 8328 unsigned NestedLoopCount = 8329 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8330 nullptr /*ordered not a clause on distribute*/, CS, *this, 8331 *DSAStack, VarsWithImplicitDSA, B); 8332 if (NestedLoopCount == 0) 8333 return StmtError(); 8334 8335 assert((CurContext->isDependentContext() || B.builtAll()) && 8336 "omp for loop exprs were not built"); 8337 8338 if (!CurContext->isDependentContext()) { 8339 // Finalize the clauses that need pre-built expressions for CodeGen. 8340 for (OMPClause *C : Clauses) { 8341 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8342 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8343 B.NumIterations, *this, CurScope, 8344 DSAStack)) 8345 return StmtError(); 8346 } 8347 } 8348 8349 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8350 return StmtError(); 8351 8352 setFunctionHasBranchProtectedScope(); 8353 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8354 NestedLoopCount, Clauses, AStmt, B); 8355 } 8356 8357 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 8358 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8359 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8360 if (!AStmt) 8361 return StmtError(); 8362 8363 auto *CS = cast<CapturedStmt>(AStmt); 8364 // 1.2.2 OpenMP Language Terminology 8365 // Structured block - An executable statement with a single entry at the 8366 // top and a single exit at the bottom. 8367 // The point of exit cannot be a branch out of the structured block. 8368 // longjmp() and throw() must not violate the entry/exit criteria. 8369 CS->getCapturedDecl()->setNothrow(); 8370 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8371 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8372 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8373 // 1.2.2 OpenMP Language Terminology 8374 // Structured block - An executable statement with a single entry at the 8375 // top and a single exit at the bottom. 8376 // The point of exit cannot be a branch out of the structured block. 8377 // longjmp() and throw() must not violate the entry/exit criteria. 8378 CS->getCapturedDecl()->setNothrow(); 8379 } 8380 8381 OMPLoopDirective::HelperExprs B; 8382 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8383 // define the nested loops number. 8384 unsigned NestedLoopCount = checkOpenMPLoop( 8385 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8386 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8387 VarsWithImplicitDSA, B); 8388 if (NestedLoopCount == 0) 8389 return StmtError(); 8390 8391 assert((CurContext->isDependentContext() || B.builtAll()) && 8392 "omp target parallel for simd loop exprs were not built"); 8393 8394 if (!CurContext->isDependentContext()) { 8395 // Finalize the clauses that need pre-built expressions for CodeGen. 8396 for (OMPClause *C : Clauses) { 8397 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8398 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8399 B.NumIterations, *this, CurScope, 8400 DSAStack)) 8401 return StmtError(); 8402 } 8403 } 8404 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8405 return StmtError(); 8406 8407 setFunctionHasBranchProtectedScope(); 8408 return OMPTargetParallelForSimdDirective::Create( 8409 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8410 } 8411 8412 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8413 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8414 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8415 if (!AStmt) 8416 return StmtError(); 8417 8418 auto *CS = cast<CapturedStmt>(AStmt); 8419 // 1.2.2 OpenMP Language Terminology 8420 // Structured block - An executable statement with a single entry at the 8421 // top and a single exit at the bottom. 8422 // The point of exit cannot be a branch out of the structured block. 8423 // longjmp() and throw() must not violate the entry/exit criteria. 8424 CS->getCapturedDecl()->setNothrow(); 8425 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8426 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8427 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8428 // 1.2.2 OpenMP Language Terminology 8429 // Structured block - An executable statement with a single entry at the 8430 // top and a single exit at the bottom. 8431 // The point of exit cannot be a branch out of the structured block. 8432 // longjmp() and throw() must not violate the entry/exit criteria. 8433 CS->getCapturedDecl()->setNothrow(); 8434 } 8435 8436 OMPLoopDirective::HelperExprs B; 8437 // In presence of clause 'collapse' with number of loops, it will define the 8438 // nested loops number. 8439 unsigned NestedLoopCount = 8440 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8441 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8442 VarsWithImplicitDSA, B); 8443 if (NestedLoopCount == 0) 8444 return StmtError(); 8445 8446 assert((CurContext->isDependentContext() || B.builtAll()) && 8447 "omp target simd loop exprs were not built"); 8448 8449 if (!CurContext->isDependentContext()) { 8450 // Finalize the clauses that need pre-built expressions for CodeGen. 8451 for (OMPClause *C : Clauses) { 8452 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8453 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8454 B.NumIterations, *this, CurScope, 8455 DSAStack)) 8456 return StmtError(); 8457 } 8458 } 8459 8460 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8461 return StmtError(); 8462 8463 setFunctionHasBranchProtectedScope(); 8464 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8465 NestedLoopCount, Clauses, AStmt, B); 8466 } 8467 8468 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8469 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8470 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8471 if (!AStmt) 8472 return StmtError(); 8473 8474 auto *CS = cast<CapturedStmt>(AStmt); 8475 // 1.2.2 OpenMP Language Terminology 8476 // Structured block - An executable statement with a single entry at the 8477 // top and a single exit at the bottom. 8478 // The point of exit cannot be a branch out of the structured block. 8479 // longjmp() and throw() must not violate the entry/exit criteria. 8480 CS->getCapturedDecl()->setNothrow(); 8481 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8482 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8483 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8484 // 1.2.2 OpenMP Language Terminology 8485 // Structured block - An executable statement with a single entry at the 8486 // top and a single exit at the bottom. 8487 // The point of exit cannot be a branch out of the structured block. 8488 // longjmp() and throw() must not violate the entry/exit criteria. 8489 CS->getCapturedDecl()->setNothrow(); 8490 } 8491 8492 OMPLoopDirective::HelperExprs B; 8493 // In presence of clause 'collapse' with number of loops, it will 8494 // define the nested loops number. 8495 unsigned NestedLoopCount = 8496 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8497 nullptr /*ordered not a clause on distribute*/, CS, *this, 8498 *DSAStack, VarsWithImplicitDSA, B); 8499 if (NestedLoopCount == 0) 8500 return StmtError(); 8501 8502 assert((CurContext->isDependentContext() || B.builtAll()) && 8503 "omp teams distribute loop exprs were not built"); 8504 8505 setFunctionHasBranchProtectedScope(); 8506 8507 DSAStack->setParentTeamsRegionLoc(StartLoc); 8508 8509 return OMPTeamsDistributeDirective::Create( 8510 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8511 } 8512 8513 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8514 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8515 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8516 if (!AStmt) 8517 return StmtError(); 8518 8519 auto *CS = cast<CapturedStmt>(AStmt); 8520 // 1.2.2 OpenMP Language Terminology 8521 // Structured block - An executable statement with a single entry at the 8522 // top and a single exit at the bottom. 8523 // The point of exit cannot be a branch out of the structured block. 8524 // longjmp() and throw() must not violate the entry/exit criteria. 8525 CS->getCapturedDecl()->setNothrow(); 8526 for (int ThisCaptureLevel = 8527 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8528 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8529 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8530 // 1.2.2 OpenMP Language Terminology 8531 // Structured block - An executable statement with a single entry at the 8532 // top and a single exit at the bottom. 8533 // The point of exit cannot be a branch out of the structured block. 8534 // longjmp() and throw() must not violate the entry/exit criteria. 8535 CS->getCapturedDecl()->setNothrow(); 8536 } 8537 8538 8539 OMPLoopDirective::HelperExprs B; 8540 // In presence of clause 'collapse' with number of loops, it will 8541 // define the nested loops number. 8542 unsigned NestedLoopCount = checkOpenMPLoop( 8543 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8544 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8545 VarsWithImplicitDSA, B); 8546 8547 if (NestedLoopCount == 0) 8548 return StmtError(); 8549 8550 assert((CurContext->isDependentContext() || B.builtAll()) && 8551 "omp teams distribute simd loop exprs were not built"); 8552 8553 if (!CurContext->isDependentContext()) { 8554 // Finalize the clauses that need pre-built expressions for CodeGen. 8555 for (OMPClause *C : Clauses) { 8556 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8557 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8558 B.NumIterations, *this, CurScope, 8559 DSAStack)) 8560 return StmtError(); 8561 } 8562 } 8563 8564 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8565 return StmtError(); 8566 8567 setFunctionHasBranchProtectedScope(); 8568 8569 DSAStack->setParentTeamsRegionLoc(StartLoc); 8570 8571 return OMPTeamsDistributeSimdDirective::Create( 8572 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8573 } 8574 8575 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8576 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8577 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8578 if (!AStmt) 8579 return StmtError(); 8580 8581 auto *CS = cast<CapturedStmt>(AStmt); 8582 // 1.2.2 OpenMP Language Terminology 8583 // Structured block - An executable statement with a single entry at the 8584 // top and a single exit at the bottom. 8585 // The point of exit cannot be a branch out of the structured block. 8586 // longjmp() and throw() must not violate the entry/exit criteria. 8587 CS->getCapturedDecl()->setNothrow(); 8588 8589 for (int ThisCaptureLevel = 8590 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8591 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8592 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8593 // 1.2.2 OpenMP Language Terminology 8594 // Structured block - An executable statement with a single entry at the 8595 // top and a single exit at the bottom. 8596 // The point of exit cannot be a branch out of the structured block. 8597 // longjmp() and throw() must not violate the entry/exit criteria. 8598 CS->getCapturedDecl()->setNothrow(); 8599 } 8600 8601 OMPLoopDirective::HelperExprs B; 8602 // In presence of clause 'collapse' with number of loops, it will 8603 // define the nested loops number. 8604 unsigned NestedLoopCount = checkOpenMPLoop( 8605 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8606 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8607 VarsWithImplicitDSA, B); 8608 8609 if (NestedLoopCount == 0) 8610 return StmtError(); 8611 8612 assert((CurContext->isDependentContext() || B.builtAll()) && 8613 "omp for loop exprs were not built"); 8614 8615 if (!CurContext->isDependentContext()) { 8616 // Finalize the clauses that need pre-built expressions for CodeGen. 8617 for (OMPClause *C : Clauses) { 8618 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8619 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8620 B.NumIterations, *this, CurScope, 8621 DSAStack)) 8622 return StmtError(); 8623 } 8624 } 8625 8626 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8627 return StmtError(); 8628 8629 setFunctionHasBranchProtectedScope(); 8630 8631 DSAStack->setParentTeamsRegionLoc(StartLoc); 8632 8633 return OMPTeamsDistributeParallelForSimdDirective::Create( 8634 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8635 } 8636 8637 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8638 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8639 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8640 if (!AStmt) 8641 return StmtError(); 8642 8643 auto *CS = cast<CapturedStmt>(AStmt); 8644 // 1.2.2 OpenMP Language Terminology 8645 // Structured block - An executable statement with a single entry at the 8646 // top and a single exit at the bottom. 8647 // The point of exit cannot be a branch out of the structured block. 8648 // longjmp() and throw() must not violate the entry/exit criteria. 8649 CS->getCapturedDecl()->setNothrow(); 8650 8651 for (int ThisCaptureLevel = 8652 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8653 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8654 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8655 // 1.2.2 OpenMP Language Terminology 8656 // Structured block - An executable statement with a single entry at the 8657 // top and a single exit at the bottom. 8658 // The point of exit cannot be a branch out of the structured block. 8659 // longjmp() and throw() must not violate the entry/exit criteria. 8660 CS->getCapturedDecl()->setNothrow(); 8661 } 8662 8663 OMPLoopDirective::HelperExprs B; 8664 // In presence of clause 'collapse' with number of loops, it will 8665 // define the nested loops number. 8666 unsigned NestedLoopCount = checkOpenMPLoop( 8667 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8668 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8669 VarsWithImplicitDSA, B); 8670 8671 if (NestedLoopCount == 0) 8672 return StmtError(); 8673 8674 assert((CurContext->isDependentContext() || B.builtAll()) && 8675 "omp for loop exprs were not built"); 8676 8677 setFunctionHasBranchProtectedScope(); 8678 8679 DSAStack->setParentTeamsRegionLoc(StartLoc); 8680 8681 return OMPTeamsDistributeParallelForDirective::Create( 8682 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8683 DSAStack->isCancelRegion()); 8684 } 8685 8686 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8687 Stmt *AStmt, 8688 SourceLocation StartLoc, 8689 SourceLocation EndLoc) { 8690 if (!AStmt) 8691 return StmtError(); 8692 8693 auto *CS = cast<CapturedStmt>(AStmt); 8694 // 1.2.2 OpenMP Language Terminology 8695 // Structured block - An executable statement with a single entry at the 8696 // top and a single exit at the bottom. 8697 // The point of exit cannot be a branch out of the structured block. 8698 // longjmp() and throw() must not violate the entry/exit criteria. 8699 CS->getCapturedDecl()->setNothrow(); 8700 8701 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8702 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8703 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8704 // 1.2.2 OpenMP Language Terminology 8705 // Structured block - An executable statement with a single entry at the 8706 // top and a single exit at the bottom. 8707 // The point of exit cannot be a branch out of the structured block. 8708 // longjmp() and throw() must not violate the entry/exit criteria. 8709 CS->getCapturedDecl()->setNothrow(); 8710 } 8711 setFunctionHasBranchProtectedScope(); 8712 8713 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8714 AStmt); 8715 } 8716 8717 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8718 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8719 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8720 if (!AStmt) 8721 return StmtError(); 8722 8723 auto *CS = cast<CapturedStmt>(AStmt); 8724 // 1.2.2 OpenMP Language Terminology 8725 // Structured block - An executable statement with a single entry at the 8726 // top and a single exit at the bottom. 8727 // The point of exit cannot be a branch out of the structured block. 8728 // longjmp() and throw() must not violate the entry/exit criteria. 8729 CS->getCapturedDecl()->setNothrow(); 8730 for (int ThisCaptureLevel = 8731 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8732 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8733 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8734 // 1.2.2 OpenMP Language Terminology 8735 // Structured block - An executable statement with a single entry at the 8736 // top and a single exit at the bottom. 8737 // The point of exit cannot be a branch out of the structured block. 8738 // longjmp() and throw() must not violate the entry/exit criteria. 8739 CS->getCapturedDecl()->setNothrow(); 8740 } 8741 8742 OMPLoopDirective::HelperExprs B; 8743 // In presence of clause 'collapse' with number of loops, it will 8744 // define the nested loops number. 8745 unsigned NestedLoopCount = checkOpenMPLoop( 8746 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8747 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8748 VarsWithImplicitDSA, B); 8749 if (NestedLoopCount == 0) 8750 return StmtError(); 8751 8752 assert((CurContext->isDependentContext() || B.builtAll()) && 8753 "omp target teams distribute loop exprs were not built"); 8754 8755 setFunctionHasBranchProtectedScope(); 8756 return OMPTargetTeamsDistributeDirective::Create( 8757 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8758 } 8759 8760 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8761 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8762 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8763 if (!AStmt) 8764 return StmtError(); 8765 8766 auto *CS = cast<CapturedStmt>(AStmt); 8767 // 1.2.2 OpenMP Language Terminology 8768 // Structured block - An executable statement with a single entry at the 8769 // top and a single exit at the bottom. 8770 // The point of exit cannot be a branch out of the structured block. 8771 // longjmp() and throw() must not violate the entry/exit criteria. 8772 CS->getCapturedDecl()->setNothrow(); 8773 for (int ThisCaptureLevel = 8774 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8775 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8776 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8777 // 1.2.2 OpenMP Language Terminology 8778 // Structured block - An executable statement with a single entry at the 8779 // top and a single exit at the bottom. 8780 // The point of exit cannot be a branch out of the structured block. 8781 // longjmp() and throw() must not violate the entry/exit criteria. 8782 CS->getCapturedDecl()->setNothrow(); 8783 } 8784 8785 OMPLoopDirective::HelperExprs B; 8786 // In presence of clause 'collapse' with number of loops, it will 8787 // define the nested loops number. 8788 unsigned NestedLoopCount = checkOpenMPLoop( 8789 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8790 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8791 VarsWithImplicitDSA, B); 8792 if (NestedLoopCount == 0) 8793 return StmtError(); 8794 8795 assert((CurContext->isDependentContext() || B.builtAll()) && 8796 "omp target teams distribute parallel for loop exprs were not built"); 8797 8798 if (!CurContext->isDependentContext()) { 8799 // Finalize the clauses that need pre-built expressions for CodeGen. 8800 for (OMPClause *C : Clauses) { 8801 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8802 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8803 B.NumIterations, *this, CurScope, 8804 DSAStack)) 8805 return StmtError(); 8806 } 8807 } 8808 8809 setFunctionHasBranchProtectedScope(); 8810 return OMPTargetTeamsDistributeParallelForDirective::Create( 8811 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8812 DSAStack->isCancelRegion()); 8813 } 8814 8815 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 8816 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8817 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8818 if (!AStmt) 8819 return StmtError(); 8820 8821 auto *CS = cast<CapturedStmt>(AStmt); 8822 // 1.2.2 OpenMP Language Terminology 8823 // Structured block - An executable statement with a single entry at the 8824 // top and a single exit at the bottom. 8825 // The point of exit cannot be a branch out of the structured block. 8826 // longjmp() and throw() must not violate the entry/exit criteria. 8827 CS->getCapturedDecl()->setNothrow(); 8828 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 8829 OMPD_target_teams_distribute_parallel_for_simd); 8830 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8831 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8832 // 1.2.2 OpenMP Language Terminology 8833 // Structured block - An executable statement with a single entry at the 8834 // top and a single exit at the bottom. 8835 // The point of exit cannot be a branch out of the structured block. 8836 // longjmp() and throw() must not violate the entry/exit criteria. 8837 CS->getCapturedDecl()->setNothrow(); 8838 } 8839 8840 OMPLoopDirective::HelperExprs B; 8841 // In presence of clause 'collapse' with number of loops, it will 8842 // define the nested loops number. 8843 unsigned NestedLoopCount = 8844 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 8845 getCollapseNumberExpr(Clauses), 8846 nullptr /*ordered not a clause on distribute*/, CS, *this, 8847 *DSAStack, VarsWithImplicitDSA, B); 8848 if (NestedLoopCount == 0) 8849 return StmtError(); 8850 8851 assert((CurContext->isDependentContext() || B.builtAll()) && 8852 "omp target teams distribute parallel for simd loop exprs were not " 8853 "built"); 8854 8855 if (!CurContext->isDependentContext()) { 8856 // Finalize the clauses that need pre-built expressions for CodeGen. 8857 for (OMPClause *C : Clauses) { 8858 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8859 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8860 B.NumIterations, *this, CurScope, 8861 DSAStack)) 8862 return StmtError(); 8863 } 8864 } 8865 8866 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8867 return StmtError(); 8868 8869 setFunctionHasBranchProtectedScope(); 8870 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 8871 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8872 } 8873 8874 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 8875 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8876 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8877 if (!AStmt) 8878 return StmtError(); 8879 8880 auto *CS = cast<CapturedStmt>(AStmt); 8881 // 1.2.2 OpenMP Language Terminology 8882 // Structured block - An executable statement with a single entry at the 8883 // top and a single exit at the bottom. 8884 // The point of exit cannot be a branch out of the structured block. 8885 // longjmp() and throw() must not violate the entry/exit criteria. 8886 CS->getCapturedDecl()->setNothrow(); 8887 for (int ThisCaptureLevel = 8888 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 8889 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8890 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8891 // 1.2.2 OpenMP Language Terminology 8892 // Structured block - An executable statement with a single entry at the 8893 // top and a single exit at the bottom. 8894 // The point of exit cannot be a branch out of the structured block. 8895 // longjmp() and throw() must not violate the entry/exit criteria. 8896 CS->getCapturedDecl()->setNothrow(); 8897 } 8898 8899 OMPLoopDirective::HelperExprs B; 8900 // In presence of clause 'collapse' with number of loops, it will 8901 // define the nested loops number. 8902 unsigned NestedLoopCount = checkOpenMPLoop( 8903 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8904 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8905 VarsWithImplicitDSA, B); 8906 if (NestedLoopCount == 0) 8907 return StmtError(); 8908 8909 assert((CurContext->isDependentContext() || B.builtAll()) && 8910 "omp target teams distribute simd loop exprs were not built"); 8911 8912 if (!CurContext->isDependentContext()) { 8913 // Finalize the clauses that need pre-built expressions for CodeGen. 8914 for (OMPClause *C : Clauses) { 8915 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8916 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8917 B.NumIterations, *this, CurScope, 8918 DSAStack)) 8919 return StmtError(); 8920 } 8921 } 8922 8923 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8924 return StmtError(); 8925 8926 setFunctionHasBranchProtectedScope(); 8927 return OMPTargetTeamsDistributeSimdDirective::Create( 8928 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8929 } 8930 8931 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 8932 SourceLocation StartLoc, 8933 SourceLocation LParenLoc, 8934 SourceLocation EndLoc) { 8935 OMPClause *Res = nullptr; 8936 switch (Kind) { 8937 case OMPC_final: 8938 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 8939 break; 8940 case OMPC_num_threads: 8941 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 8942 break; 8943 case OMPC_safelen: 8944 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 8945 break; 8946 case OMPC_simdlen: 8947 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 8948 break; 8949 case OMPC_allocator: 8950 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 8951 break; 8952 case OMPC_collapse: 8953 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 8954 break; 8955 case OMPC_ordered: 8956 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 8957 break; 8958 case OMPC_device: 8959 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 8960 break; 8961 case OMPC_num_teams: 8962 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 8963 break; 8964 case OMPC_thread_limit: 8965 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 8966 break; 8967 case OMPC_priority: 8968 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 8969 break; 8970 case OMPC_grainsize: 8971 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 8972 break; 8973 case OMPC_num_tasks: 8974 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 8975 break; 8976 case OMPC_hint: 8977 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 8978 break; 8979 case OMPC_if: 8980 case OMPC_default: 8981 case OMPC_proc_bind: 8982 case OMPC_schedule: 8983 case OMPC_private: 8984 case OMPC_firstprivate: 8985 case OMPC_lastprivate: 8986 case OMPC_shared: 8987 case OMPC_reduction: 8988 case OMPC_task_reduction: 8989 case OMPC_in_reduction: 8990 case OMPC_linear: 8991 case OMPC_aligned: 8992 case OMPC_copyin: 8993 case OMPC_copyprivate: 8994 case OMPC_nowait: 8995 case OMPC_untied: 8996 case OMPC_mergeable: 8997 case OMPC_threadprivate: 8998 case OMPC_allocate: 8999 case OMPC_flush: 9000 case OMPC_read: 9001 case OMPC_write: 9002 case OMPC_update: 9003 case OMPC_capture: 9004 case OMPC_seq_cst: 9005 case OMPC_depend: 9006 case OMPC_threads: 9007 case OMPC_simd: 9008 case OMPC_map: 9009 case OMPC_nogroup: 9010 case OMPC_dist_schedule: 9011 case OMPC_defaultmap: 9012 case OMPC_unknown: 9013 case OMPC_uniform: 9014 case OMPC_to: 9015 case OMPC_from: 9016 case OMPC_use_device_ptr: 9017 case OMPC_is_device_ptr: 9018 case OMPC_unified_address: 9019 case OMPC_unified_shared_memory: 9020 case OMPC_reverse_offload: 9021 case OMPC_dynamic_allocators: 9022 case OMPC_atomic_default_mem_order: 9023 llvm_unreachable("Clause is not allowed."); 9024 } 9025 return Res; 9026 } 9027 9028 // An OpenMP directive such as 'target parallel' has two captured regions: 9029 // for the 'target' and 'parallel' respectively. This function returns 9030 // the region in which to capture expressions associated with a clause. 9031 // A return value of OMPD_unknown signifies that the expression should not 9032 // be captured. 9033 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9034 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9035 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9036 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9037 switch (CKind) { 9038 case OMPC_if: 9039 switch (DKind) { 9040 case OMPD_target_parallel: 9041 case OMPD_target_parallel_for: 9042 case OMPD_target_parallel_for_simd: 9043 // If this clause applies to the nested 'parallel' region, capture within 9044 // the 'target' region, otherwise do not capture. 9045 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9046 CaptureRegion = OMPD_target; 9047 break; 9048 case OMPD_target_teams_distribute_parallel_for: 9049 case OMPD_target_teams_distribute_parallel_for_simd: 9050 // If this clause applies to the nested 'parallel' region, capture within 9051 // the 'teams' region, otherwise do not capture. 9052 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9053 CaptureRegion = OMPD_teams; 9054 break; 9055 case OMPD_teams_distribute_parallel_for: 9056 case OMPD_teams_distribute_parallel_for_simd: 9057 CaptureRegion = OMPD_teams; 9058 break; 9059 case OMPD_target_update: 9060 case OMPD_target_enter_data: 9061 case OMPD_target_exit_data: 9062 CaptureRegion = OMPD_task; 9063 break; 9064 case OMPD_cancel: 9065 case OMPD_parallel: 9066 case OMPD_parallel_sections: 9067 case OMPD_parallel_for: 9068 case OMPD_parallel_for_simd: 9069 case OMPD_target: 9070 case OMPD_target_simd: 9071 case OMPD_target_teams: 9072 case OMPD_target_teams_distribute: 9073 case OMPD_target_teams_distribute_simd: 9074 case OMPD_distribute_parallel_for: 9075 case OMPD_distribute_parallel_for_simd: 9076 case OMPD_task: 9077 case OMPD_taskloop: 9078 case OMPD_taskloop_simd: 9079 case OMPD_target_data: 9080 // Do not capture if-clause expressions. 9081 break; 9082 case OMPD_threadprivate: 9083 case OMPD_allocate: 9084 case OMPD_taskyield: 9085 case OMPD_barrier: 9086 case OMPD_taskwait: 9087 case OMPD_cancellation_point: 9088 case OMPD_flush: 9089 case OMPD_declare_reduction: 9090 case OMPD_declare_mapper: 9091 case OMPD_declare_simd: 9092 case OMPD_declare_target: 9093 case OMPD_end_declare_target: 9094 case OMPD_teams: 9095 case OMPD_simd: 9096 case OMPD_for: 9097 case OMPD_for_simd: 9098 case OMPD_sections: 9099 case OMPD_section: 9100 case OMPD_single: 9101 case OMPD_master: 9102 case OMPD_critical: 9103 case OMPD_taskgroup: 9104 case OMPD_distribute: 9105 case OMPD_ordered: 9106 case OMPD_atomic: 9107 case OMPD_distribute_simd: 9108 case OMPD_teams_distribute: 9109 case OMPD_teams_distribute_simd: 9110 case OMPD_requires: 9111 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9112 case OMPD_unknown: 9113 llvm_unreachable("Unknown OpenMP directive"); 9114 } 9115 break; 9116 case OMPC_num_threads: 9117 switch (DKind) { 9118 case OMPD_target_parallel: 9119 case OMPD_target_parallel_for: 9120 case OMPD_target_parallel_for_simd: 9121 CaptureRegion = OMPD_target; 9122 break; 9123 case OMPD_teams_distribute_parallel_for: 9124 case OMPD_teams_distribute_parallel_for_simd: 9125 case OMPD_target_teams_distribute_parallel_for: 9126 case OMPD_target_teams_distribute_parallel_for_simd: 9127 CaptureRegion = OMPD_teams; 9128 break; 9129 case OMPD_parallel: 9130 case OMPD_parallel_sections: 9131 case OMPD_parallel_for: 9132 case OMPD_parallel_for_simd: 9133 case OMPD_distribute_parallel_for: 9134 case OMPD_distribute_parallel_for_simd: 9135 // Do not capture num_threads-clause expressions. 9136 break; 9137 case OMPD_target_data: 9138 case OMPD_target_enter_data: 9139 case OMPD_target_exit_data: 9140 case OMPD_target_update: 9141 case OMPD_target: 9142 case OMPD_target_simd: 9143 case OMPD_target_teams: 9144 case OMPD_target_teams_distribute: 9145 case OMPD_target_teams_distribute_simd: 9146 case OMPD_cancel: 9147 case OMPD_task: 9148 case OMPD_taskloop: 9149 case OMPD_taskloop_simd: 9150 case OMPD_threadprivate: 9151 case OMPD_allocate: 9152 case OMPD_taskyield: 9153 case OMPD_barrier: 9154 case OMPD_taskwait: 9155 case OMPD_cancellation_point: 9156 case OMPD_flush: 9157 case OMPD_declare_reduction: 9158 case OMPD_declare_mapper: 9159 case OMPD_declare_simd: 9160 case OMPD_declare_target: 9161 case OMPD_end_declare_target: 9162 case OMPD_teams: 9163 case OMPD_simd: 9164 case OMPD_for: 9165 case OMPD_for_simd: 9166 case OMPD_sections: 9167 case OMPD_section: 9168 case OMPD_single: 9169 case OMPD_master: 9170 case OMPD_critical: 9171 case OMPD_taskgroup: 9172 case OMPD_distribute: 9173 case OMPD_ordered: 9174 case OMPD_atomic: 9175 case OMPD_distribute_simd: 9176 case OMPD_teams_distribute: 9177 case OMPD_teams_distribute_simd: 9178 case OMPD_requires: 9179 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9180 case OMPD_unknown: 9181 llvm_unreachable("Unknown OpenMP directive"); 9182 } 9183 break; 9184 case OMPC_num_teams: 9185 switch (DKind) { 9186 case OMPD_target_teams: 9187 case OMPD_target_teams_distribute: 9188 case OMPD_target_teams_distribute_simd: 9189 case OMPD_target_teams_distribute_parallel_for: 9190 case OMPD_target_teams_distribute_parallel_for_simd: 9191 CaptureRegion = OMPD_target; 9192 break; 9193 case OMPD_teams_distribute_parallel_for: 9194 case OMPD_teams_distribute_parallel_for_simd: 9195 case OMPD_teams: 9196 case OMPD_teams_distribute: 9197 case OMPD_teams_distribute_simd: 9198 // Do not capture num_teams-clause expressions. 9199 break; 9200 case OMPD_distribute_parallel_for: 9201 case OMPD_distribute_parallel_for_simd: 9202 case OMPD_task: 9203 case OMPD_taskloop: 9204 case OMPD_taskloop_simd: 9205 case OMPD_target_data: 9206 case OMPD_target_enter_data: 9207 case OMPD_target_exit_data: 9208 case OMPD_target_update: 9209 case OMPD_cancel: 9210 case OMPD_parallel: 9211 case OMPD_parallel_sections: 9212 case OMPD_parallel_for: 9213 case OMPD_parallel_for_simd: 9214 case OMPD_target: 9215 case OMPD_target_simd: 9216 case OMPD_target_parallel: 9217 case OMPD_target_parallel_for: 9218 case OMPD_target_parallel_for_simd: 9219 case OMPD_threadprivate: 9220 case OMPD_allocate: 9221 case OMPD_taskyield: 9222 case OMPD_barrier: 9223 case OMPD_taskwait: 9224 case OMPD_cancellation_point: 9225 case OMPD_flush: 9226 case OMPD_declare_reduction: 9227 case OMPD_declare_mapper: 9228 case OMPD_declare_simd: 9229 case OMPD_declare_target: 9230 case OMPD_end_declare_target: 9231 case OMPD_simd: 9232 case OMPD_for: 9233 case OMPD_for_simd: 9234 case OMPD_sections: 9235 case OMPD_section: 9236 case OMPD_single: 9237 case OMPD_master: 9238 case OMPD_critical: 9239 case OMPD_taskgroup: 9240 case OMPD_distribute: 9241 case OMPD_ordered: 9242 case OMPD_atomic: 9243 case OMPD_distribute_simd: 9244 case OMPD_requires: 9245 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9246 case OMPD_unknown: 9247 llvm_unreachable("Unknown OpenMP directive"); 9248 } 9249 break; 9250 case OMPC_thread_limit: 9251 switch (DKind) { 9252 case OMPD_target_teams: 9253 case OMPD_target_teams_distribute: 9254 case OMPD_target_teams_distribute_simd: 9255 case OMPD_target_teams_distribute_parallel_for: 9256 case OMPD_target_teams_distribute_parallel_for_simd: 9257 CaptureRegion = OMPD_target; 9258 break; 9259 case OMPD_teams_distribute_parallel_for: 9260 case OMPD_teams_distribute_parallel_for_simd: 9261 case OMPD_teams: 9262 case OMPD_teams_distribute: 9263 case OMPD_teams_distribute_simd: 9264 // Do not capture thread_limit-clause expressions. 9265 break; 9266 case OMPD_distribute_parallel_for: 9267 case OMPD_distribute_parallel_for_simd: 9268 case OMPD_task: 9269 case OMPD_taskloop: 9270 case OMPD_taskloop_simd: 9271 case OMPD_target_data: 9272 case OMPD_target_enter_data: 9273 case OMPD_target_exit_data: 9274 case OMPD_target_update: 9275 case OMPD_cancel: 9276 case OMPD_parallel: 9277 case OMPD_parallel_sections: 9278 case OMPD_parallel_for: 9279 case OMPD_parallel_for_simd: 9280 case OMPD_target: 9281 case OMPD_target_simd: 9282 case OMPD_target_parallel: 9283 case OMPD_target_parallel_for: 9284 case OMPD_target_parallel_for_simd: 9285 case OMPD_threadprivate: 9286 case OMPD_allocate: 9287 case OMPD_taskyield: 9288 case OMPD_barrier: 9289 case OMPD_taskwait: 9290 case OMPD_cancellation_point: 9291 case OMPD_flush: 9292 case OMPD_declare_reduction: 9293 case OMPD_declare_mapper: 9294 case OMPD_declare_simd: 9295 case OMPD_declare_target: 9296 case OMPD_end_declare_target: 9297 case OMPD_simd: 9298 case OMPD_for: 9299 case OMPD_for_simd: 9300 case OMPD_sections: 9301 case OMPD_section: 9302 case OMPD_single: 9303 case OMPD_master: 9304 case OMPD_critical: 9305 case OMPD_taskgroup: 9306 case OMPD_distribute: 9307 case OMPD_ordered: 9308 case OMPD_atomic: 9309 case OMPD_distribute_simd: 9310 case OMPD_requires: 9311 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9312 case OMPD_unknown: 9313 llvm_unreachable("Unknown OpenMP directive"); 9314 } 9315 break; 9316 case OMPC_schedule: 9317 switch (DKind) { 9318 case OMPD_parallel_for: 9319 case OMPD_parallel_for_simd: 9320 case OMPD_distribute_parallel_for: 9321 case OMPD_distribute_parallel_for_simd: 9322 case OMPD_teams_distribute_parallel_for: 9323 case OMPD_teams_distribute_parallel_for_simd: 9324 case OMPD_target_parallel_for: 9325 case OMPD_target_parallel_for_simd: 9326 case OMPD_target_teams_distribute_parallel_for: 9327 case OMPD_target_teams_distribute_parallel_for_simd: 9328 CaptureRegion = OMPD_parallel; 9329 break; 9330 case OMPD_for: 9331 case OMPD_for_simd: 9332 // Do not capture schedule-clause expressions. 9333 break; 9334 case OMPD_task: 9335 case OMPD_taskloop: 9336 case OMPD_taskloop_simd: 9337 case OMPD_target_data: 9338 case OMPD_target_enter_data: 9339 case OMPD_target_exit_data: 9340 case OMPD_target_update: 9341 case OMPD_teams: 9342 case OMPD_teams_distribute: 9343 case OMPD_teams_distribute_simd: 9344 case OMPD_target_teams_distribute: 9345 case OMPD_target_teams_distribute_simd: 9346 case OMPD_target: 9347 case OMPD_target_simd: 9348 case OMPD_target_parallel: 9349 case OMPD_cancel: 9350 case OMPD_parallel: 9351 case OMPD_parallel_sections: 9352 case OMPD_threadprivate: 9353 case OMPD_allocate: 9354 case OMPD_taskyield: 9355 case OMPD_barrier: 9356 case OMPD_taskwait: 9357 case OMPD_cancellation_point: 9358 case OMPD_flush: 9359 case OMPD_declare_reduction: 9360 case OMPD_declare_mapper: 9361 case OMPD_declare_simd: 9362 case OMPD_declare_target: 9363 case OMPD_end_declare_target: 9364 case OMPD_simd: 9365 case OMPD_sections: 9366 case OMPD_section: 9367 case OMPD_single: 9368 case OMPD_master: 9369 case OMPD_critical: 9370 case OMPD_taskgroup: 9371 case OMPD_distribute: 9372 case OMPD_ordered: 9373 case OMPD_atomic: 9374 case OMPD_distribute_simd: 9375 case OMPD_target_teams: 9376 case OMPD_requires: 9377 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9378 case OMPD_unknown: 9379 llvm_unreachable("Unknown OpenMP directive"); 9380 } 9381 break; 9382 case OMPC_dist_schedule: 9383 switch (DKind) { 9384 case OMPD_teams_distribute_parallel_for: 9385 case OMPD_teams_distribute_parallel_for_simd: 9386 case OMPD_teams_distribute: 9387 case OMPD_teams_distribute_simd: 9388 case OMPD_target_teams_distribute_parallel_for: 9389 case OMPD_target_teams_distribute_parallel_for_simd: 9390 case OMPD_target_teams_distribute: 9391 case OMPD_target_teams_distribute_simd: 9392 CaptureRegion = OMPD_teams; 9393 break; 9394 case OMPD_distribute_parallel_for: 9395 case OMPD_distribute_parallel_for_simd: 9396 case OMPD_distribute: 9397 case OMPD_distribute_simd: 9398 // Do not capture thread_limit-clause expressions. 9399 break; 9400 case OMPD_parallel_for: 9401 case OMPD_parallel_for_simd: 9402 case OMPD_target_parallel_for_simd: 9403 case OMPD_target_parallel_for: 9404 case OMPD_task: 9405 case OMPD_taskloop: 9406 case OMPD_taskloop_simd: 9407 case OMPD_target_data: 9408 case OMPD_target_enter_data: 9409 case OMPD_target_exit_data: 9410 case OMPD_target_update: 9411 case OMPD_teams: 9412 case OMPD_target: 9413 case OMPD_target_simd: 9414 case OMPD_target_parallel: 9415 case OMPD_cancel: 9416 case OMPD_parallel: 9417 case OMPD_parallel_sections: 9418 case OMPD_threadprivate: 9419 case OMPD_allocate: 9420 case OMPD_taskyield: 9421 case OMPD_barrier: 9422 case OMPD_taskwait: 9423 case OMPD_cancellation_point: 9424 case OMPD_flush: 9425 case OMPD_declare_reduction: 9426 case OMPD_declare_mapper: 9427 case OMPD_declare_simd: 9428 case OMPD_declare_target: 9429 case OMPD_end_declare_target: 9430 case OMPD_simd: 9431 case OMPD_for: 9432 case OMPD_for_simd: 9433 case OMPD_sections: 9434 case OMPD_section: 9435 case OMPD_single: 9436 case OMPD_master: 9437 case OMPD_critical: 9438 case OMPD_taskgroup: 9439 case OMPD_ordered: 9440 case OMPD_atomic: 9441 case OMPD_target_teams: 9442 case OMPD_requires: 9443 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9444 case OMPD_unknown: 9445 llvm_unreachable("Unknown OpenMP directive"); 9446 } 9447 break; 9448 case OMPC_device: 9449 switch (DKind) { 9450 case OMPD_target_update: 9451 case OMPD_target_enter_data: 9452 case OMPD_target_exit_data: 9453 case OMPD_target: 9454 case OMPD_target_simd: 9455 case OMPD_target_teams: 9456 case OMPD_target_parallel: 9457 case OMPD_target_teams_distribute: 9458 case OMPD_target_teams_distribute_simd: 9459 case OMPD_target_parallel_for: 9460 case OMPD_target_parallel_for_simd: 9461 case OMPD_target_teams_distribute_parallel_for: 9462 case OMPD_target_teams_distribute_parallel_for_simd: 9463 CaptureRegion = OMPD_task; 9464 break; 9465 case OMPD_target_data: 9466 // Do not capture device-clause expressions. 9467 break; 9468 case OMPD_teams_distribute_parallel_for: 9469 case OMPD_teams_distribute_parallel_for_simd: 9470 case OMPD_teams: 9471 case OMPD_teams_distribute: 9472 case OMPD_teams_distribute_simd: 9473 case OMPD_distribute_parallel_for: 9474 case OMPD_distribute_parallel_for_simd: 9475 case OMPD_task: 9476 case OMPD_taskloop: 9477 case OMPD_taskloop_simd: 9478 case OMPD_cancel: 9479 case OMPD_parallel: 9480 case OMPD_parallel_sections: 9481 case OMPD_parallel_for: 9482 case OMPD_parallel_for_simd: 9483 case OMPD_threadprivate: 9484 case OMPD_allocate: 9485 case OMPD_taskyield: 9486 case OMPD_barrier: 9487 case OMPD_taskwait: 9488 case OMPD_cancellation_point: 9489 case OMPD_flush: 9490 case OMPD_declare_reduction: 9491 case OMPD_declare_mapper: 9492 case OMPD_declare_simd: 9493 case OMPD_declare_target: 9494 case OMPD_end_declare_target: 9495 case OMPD_simd: 9496 case OMPD_for: 9497 case OMPD_for_simd: 9498 case OMPD_sections: 9499 case OMPD_section: 9500 case OMPD_single: 9501 case OMPD_master: 9502 case OMPD_critical: 9503 case OMPD_taskgroup: 9504 case OMPD_distribute: 9505 case OMPD_ordered: 9506 case OMPD_atomic: 9507 case OMPD_distribute_simd: 9508 case OMPD_requires: 9509 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9510 case OMPD_unknown: 9511 llvm_unreachable("Unknown OpenMP directive"); 9512 } 9513 break; 9514 case OMPC_firstprivate: 9515 case OMPC_lastprivate: 9516 case OMPC_reduction: 9517 case OMPC_task_reduction: 9518 case OMPC_in_reduction: 9519 case OMPC_linear: 9520 case OMPC_default: 9521 case OMPC_proc_bind: 9522 case OMPC_final: 9523 case OMPC_safelen: 9524 case OMPC_simdlen: 9525 case OMPC_allocator: 9526 case OMPC_collapse: 9527 case OMPC_private: 9528 case OMPC_shared: 9529 case OMPC_aligned: 9530 case OMPC_copyin: 9531 case OMPC_copyprivate: 9532 case OMPC_ordered: 9533 case OMPC_nowait: 9534 case OMPC_untied: 9535 case OMPC_mergeable: 9536 case OMPC_threadprivate: 9537 case OMPC_allocate: 9538 case OMPC_flush: 9539 case OMPC_read: 9540 case OMPC_write: 9541 case OMPC_update: 9542 case OMPC_capture: 9543 case OMPC_seq_cst: 9544 case OMPC_depend: 9545 case OMPC_threads: 9546 case OMPC_simd: 9547 case OMPC_map: 9548 case OMPC_priority: 9549 case OMPC_grainsize: 9550 case OMPC_nogroup: 9551 case OMPC_num_tasks: 9552 case OMPC_hint: 9553 case OMPC_defaultmap: 9554 case OMPC_unknown: 9555 case OMPC_uniform: 9556 case OMPC_to: 9557 case OMPC_from: 9558 case OMPC_use_device_ptr: 9559 case OMPC_is_device_ptr: 9560 case OMPC_unified_address: 9561 case OMPC_unified_shared_memory: 9562 case OMPC_reverse_offload: 9563 case OMPC_dynamic_allocators: 9564 case OMPC_atomic_default_mem_order: 9565 llvm_unreachable("Unexpected OpenMP clause."); 9566 } 9567 return CaptureRegion; 9568 } 9569 9570 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9571 Expr *Condition, SourceLocation StartLoc, 9572 SourceLocation LParenLoc, 9573 SourceLocation NameModifierLoc, 9574 SourceLocation ColonLoc, 9575 SourceLocation EndLoc) { 9576 Expr *ValExpr = Condition; 9577 Stmt *HelperValStmt = nullptr; 9578 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9579 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9580 !Condition->isInstantiationDependent() && 9581 !Condition->containsUnexpandedParameterPack()) { 9582 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9583 if (Val.isInvalid()) 9584 return nullptr; 9585 9586 ValExpr = Val.get(); 9587 9588 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9589 CaptureRegion = 9590 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9591 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9592 ValExpr = MakeFullExpr(ValExpr).get(); 9593 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9594 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9595 HelperValStmt = buildPreInits(Context, Captures); 9596 } 9597 } 9598 9599 return new (Context) 9600 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9601 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9602 } 9603 9604 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9605 SourceLocation StartLoc, 9606 SourceLocation LParenLoc, 9607 SourceLocation EndLoc) { 9608 Expr *ValExpr = Condition; 9609 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9610 !Condition->isInstantiationDependent() && 9611 !Condition->containsUnexpandedParameterPack()) { 9612 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9613 if (Val.isInvalid()) 9614 return nullptr; 9615 9616 ValExpr = MakeFullExpr(Val.get()).get(); 9617 } 9618 9619 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9620 } 9621 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9622 Expr *Op) { 9623 if (!Op) 9624 return ExprError(); 9625 9626 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9627 public: 9628 IntConvertDiagnoser() 9629 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9630 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9631 QualType T) override { 9632 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9633 } 9634 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9635 QualType T) override { 9636 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9637 } 9638 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9639 QualType T, 9640 QualType ConvTy) override { 9641 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9642 } 9643 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9644 QualType ConvTy) override { 9645 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9646 << ConvTy->isEnumeralType() << ConvTy; 9647 } 9648 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9649 QualType T) override { 9650 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9651 } 9652 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9653 QualType ConvTy) override { 9654 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9655 << ConvTy->isEnumeralType() << ConvTy; 9656 } 9657 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9658 QualType) override { 9659 llvm_unreachable("conversion functions are permitted"); 9660 } 9661 } ConvertDiagnoser; 9662 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9663 } 9664 9665 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9666 OpenMPClauseKind CKind, 9667 bool StrictlyPositive) { 9668 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9669 !ValExpr->isInstantiationDependent()) { 9670 SourceLocation Loc = ValExpr->getExprLoc(); 9671 ExprResult Value = 9672 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9673 if (Value.isInvalid()) 9674 return false; 9675 9676 ValExpr = Value.get(); 9677 // The expression must evaluate to a non-negative integer value. 9678 llvm::APSInt Result; 9679 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9680 Result.isSigned() && 9681 !((!StrictlyPositive && Result.isNonNegative()) || 9682 (StrictlyPositive && Result.isStrictlyPositive()))) { 9683 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9684 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9685 << ValExpr->getSourceRange(); 9686 return false; 9687 } 9688 } 9689 return true; 9690 } 9691 9692 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9693 SourceLocation StartLoc, 9694 SourceLocation LParenLoc, 9695 SourceLocation EndLoc) { 9696 Expr *ValExpr = NumThreads; 9697 Stmt *HelperValStmt = nullptr; 9698 9699 // OpenMP [2.5, Restrictions] 9700 // The num_threads expression must evaluate to a positive integer value. 9701 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9702 /*StrictlyPositive=*/true)) 9703 return nullptr; 9704 9705 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9706 OpenMPDirectiveKind CaptureRegion = 9707 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9708 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9709 ValExpr = MakeFullExpr(ValExpr).get(); 9710 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9711 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9712 HelperValStmt = buildPreInits(Context, Captures); 9713 } 9714 9715 return new (Context) OMPNumThreadsClause( 9716 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9717 } 9718 9719 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9720 OpenMPClauseKind CKind, 9721 bool StrictlyPositive) { 9722 if (!E) 9723 return ExprError(); 9724 if (E->isValueDependent() || E->isTypeDependent() || 9725 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9726 return E; 9727 llvm::APSInt Result; 9728 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9729 if (ICE.isInvalid()) 9730 return ExprError(); 9731 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9732 (!StrictlyPositive && !Result.isNonNegative())) { 9733 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9734 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9735 << E->getSourceRange(); 9736 return ExprError(); 9737 } 9738 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9739 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9740 << E->getSourceRange(); 9741 return ExprError(); 9742 } 9743 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9744 DSAStack->setAssociatedLoops(Result.getExtValue()); 9745 else if (CKind == OMPC_ordered) 9746 DSAStack->setAssociatedLoops(Result.getExtValue()); 9747 return ICE; 9748 } 9749 9750 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9751 SourceLocation LParenLoc, 9752 SourceLocation EndLoc) { 9753 // OpenMP [2.8.1, simd construct, Description] 9754 // The parameter of the safelen clause must be a constant 9755 // positive integer expression. 9756 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9757 if (Safelen.isInvalid()) 9758 return nullptr; 9759 return new (Context) 9760 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9761 } 9762 9763 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9764 SourceLocation LParenLoc, 9765 SourceLocation EndLoc) { 9766 // OpenMP [2.8.1, simd construct, Description] 9767 // The parameter of the simdlen clause must be a constant 9768 // positive integer expression. 9769 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9770 if (Simdlen.isInvalid()) 9771 return nullptr; 9772 return new (Context) 9773 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9774 } 9775 9776 /// Tries to find omp_allocator_handle_t type. 9777 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9778 DSAStackTy *Stack) { 9779 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 9780 if (!OMPAllocatorHandleT.isNull()) 9781 return true; 9782 // Build the predefined allocator expressions. 9783 bool ErrorFound = false; 9784 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 9785 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 9786 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 9787 StringRef Allocator = 9788 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 9789 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 9790 auto *VD = dyn_cast_or_null<ValueDecl>( 9791 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 9792 if (!VD) { 9793 ErrorFound = true; 9794 break; 9795 } 9796 QualType AllocatorType = 9797 VD->getType().getNonLValueExprType(S.getASTContext()); 9798 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 9799 if (!Res.isUsable()) { 9800 ErrorFound = true; 9801 break; 9802 } 9803 if (OMPAllocatorHandleT.isNull()) 9804 OMPAllocatorHandleT = AllocatorType; 9805 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 9806 ErrorFound = true; 9807 break; 9808 } 9809 Stack->setAllocator(AllocatorKind, Res.get()); 9810 } 9811 if (ErrorFound) { 9812 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 9813 return false; 9814 } 9815 OMPAllocatorHandleT.addConst(); 9816 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 9817 return true; 9818 } 9819 9820 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 9821 SourceLocation LParenLoc, 9822 SourceLocation EndLoc) { 9823 // OpenMP [2.11.3, allocate Directive, Description] 9824 // allocator is an expression of omp_allocator_handle_t type. 9825 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 9826 return nullptr; 9827 9828 ExprResult Allocator = DefaultLvalueConversion(A); 9829 if (Allocator.isInvalid()) 9830 return nullptr; 9831 Allocator = PerformImplicitConversion(Allocator.get(), 9832 DSAStack->getOMPAllocatorHandleT(), 9833 Sema::AA_Initializing, 9834 /*AllowExplicit=*/true); 9835 if (Allocator.isInvalid()) 9836 return nullptr; 9837 return new (Context) 9838 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 9839 } 9840 9841 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 9842 SourceLocation StartLoc, 9843 SourceLocation LParenLoc, 9844 SourceLocation EndLoc) { 9845 // OpenMP [2.7.1, loop construct, Description] 9846 // OpenMP [2.8.1, simd construct, Description] 9847 // OpenMP [2.9.6, distribute construct, Description] 9848 // The parameter of the collapse clause must be a constant 9849 // positive integer expression. 9850 ExprResult NumForLoopsResult = 9851 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 9852 if (NumForLoopsResult.isInvalid()) 9853 return nullptr; 9854 return new (Context) 9855 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 9856 } 9857 9858 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 9859 SourceLocation EndLoc, 9860 SourceLocation LParenLoc, 9861 Expr *NumForLoops) { 9862 // OpenMP [2.7.1, loop construct, Description] 9863 // OpenMP [2.8.1, simd construct, Description] 9864 // OpenMP [2.9.6, distribute construct, Description] 9865 // The parameter of the ordered clause must be a constant 9866 // positive integer expression if any. 9867 if (NumForLoops && LParenLoc.isValid()) { 9868 ExprResult NumForLoopsResult = 9869 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 9870 if (NumForLoopsResult.isInvalid()) 9871 return nullptr; 9872 NumForLoops = NumForLoopsResult.get(); 9873 } else { 9874 NumForLoops = nullptr; 9875 } 9876 auto *Clause = OMPOrderedClause::Create( 9877 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 9878 StartLoc, LParenLoc, EndLoc); 9879 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 9880 return Clause; 9881 } 9882 9883 OMPClause *Sema::ActOnOpenMPSimpleClause( 9884 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 9885 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9886 OMPClause *Res = nullptr; 9887 switch (Kind) { 9888 case OMPC_default: 9889 Res = 9890 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 9891 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9892 break; 9893 case OMPC_proc_bind: 9894 Res = ActOnOpenMPProcBindClause( 9895 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 9896 LParenLoc, EndLoc); 9897 break; 9898 case OMPC_atomic_default_mem_order: 9899 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 9900 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 9901 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9902 break; 9903 case OMPC_if: 9904 case OMPC_final: 9905 case OMPC_num_threads: 9906 case OMPC_safelen: 9907 case OMPC_simdlen: 9908 case OMPC_allocator: 9909 case OMPC_collapse: 9910 case OMPC_schedule: 9911 case OMPC_private: 9912 case OMPC_firstprivate: 9913 case OMPC_lastprivate: 9914 case OMPC_shared: 9915 case OMPC_reduction: 9916 case OMPC_task_reduction: 9917 case OMPC_in_reduction: 9918 case OMPC_linear: 9919 case OMPC_aligned: 9920 case OMPC_copyin: 9921 case OMPC_copyprivate: 9922 case OMPC_ordered: 9923 case OMPC_nowait: 9924 case OMPC_untied: 9925 case OMPC_mergeable: 9926 case OMPC_threadprivate: 9927 case OMPC_allocate: 9928 case OMPC_flush: 9929 case OMPC_read: 9930 case OMPC_write: 9931 case OMPC_update: 9932 case OMPC_capture: 9933 case OMPC_seq_cst: 9934 case OMPC_depend: 9935 case OMPC_device: 9936 case OMPC_threads: 9937 case OMPC_simd: 9938 case OMPC_map: 9939 case OMPC_num_teams: 9940 case OMPC_thread_limit: 9941 case OMPC_priority: 9942 case OMPC_grainsize: 9943 case OMPC_nogroup: 9944 case OMPC_num_tasks: 9945 case OMPC_hint: 9946 case OMPC_dist_schedule: 9947 case OMPC_defaultmap: 9948 case OMPC_unknown: 9949 case OMPC_uniform: 9950 case OMPC_to: 9951 case OMPC_from: 9952 case OMPC_use_device_ptr: 9953 case OMPC_is_device_ptr: 9954 case OMPC_unified_address: 9955 case OMPC_unified_shared_memory: 9956 case OMPC_reverse_offload: 9957 case OMPC_dynamic_allocators: 9958 llvm_unreachable("Clause is not allowed."); 9959 } 9960 return Res; 9961 } 9962 9963 static std::string 9964 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 9965 ArrayRef<unsigned> Exclude = llvm::None) { 9966 SmallString<256> Buffer; 9967 llvm::raw_svector_ostream Out(Buffer); 9968 unsigned Bound = Last >= 2 ? Last - 2 : 0; 9969 unsigned Skipped = Exclude.size(); 9970 auto S = Exclude.begin(), E = Exclude.end(); 9971 for (unsigned I = First; I < Last; ++I) { 9972 if (std::find(S, E, I) != E) { 9973 --Skipped; 9974 continue; 9975 } 9976 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 9977 if (I == Bound - Skipped) 9978 Out << " or "; 9979 else if (I != Bound + 1 - Skipped) 9980 Out << ", "; 9981 } 9982 return Out.str(); 9983 } 9984 9985 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 9986 SourceLocation KindKwLoc, 9987 SourceLocation StartLoc, 9988 SourceLocation LParenLoc, 9989 SourceLocation EndLoc) { 9990 if (Kind == OMPC_DEFAULT_unknown) { 9991 static_assert(OMPC_DEFAULT_unknown > 0, 9992 "OMPC_DEFAULT_unknown not greater than 0"); 9993 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9994 << getListOfPossibleValues(OMPC_default, /*First=*/0, 9995 /*Last=*/OMPC_DEFAULT_unknown) 9996 << getOpenMPClauseName(OMPC_default); 9997 return nullptr; 9998 } 9999 switch (Kind) { 10000 case OMPC_DEFAULT_none: 10001 DSAStack->setDefaultDSANone(KindKwLoc); 10002 break; 10003 case OMPC_DEFAULT_shared: 10004 DSAStack->setDefaultDSAShared(KindKwLoc); 10005 break; 10006 case OMPC_DEFAULT_unknown: 10007 llvm_unreachable("Clause kind is not allowed."); 10008 break; 10009 } 10010 return new (Context) 10011 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10012 } 10013 10014 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10015 SourceLocation KindKwLoc, 10016 SourceLocation StartLoc, 10017 SourceLocation LParenLoc, 10018 SourceLocation EndLoc) { 10019 if (Kind == OMPC_PROC_BIND_unknown) { 10020 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10021 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10022 /*Last=*/OMPC_PROC_BIND_unknown) 10023 << getOpenMPClauseName(OMPC_proc_bind); 10024 return nullptr; 10025 } 10026 return new (Context) 10027 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10028 } 10029 10030 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10031 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10032 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10033 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10034 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10035 << getListOfPossibleValues( 10036 OMPC_atomic_default_mem_order, /*First=*/0, 10037 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10038 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10039 return nullptr; 10040 } 10041 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10042 LParenLoc, EndLoc); 10043 } 10044 10045 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10046 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10047 SourceLocation StartLoc, SourceLocation LParenLoc, 10048 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10049 SourceLocation EndLoc) { 10050 OMPClause *Res = nullptr; 10051 switch (Kind) { 10052 case OMPC_schedule: 10053 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10054 assert(Argument.size() == NumberOfElements && 10055 ArgumentLoc.size() == NumberOfElements); 10056 Res = ActOnOpenMPScheduleClause( 10057 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10058 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10059 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10060 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10061 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10062 break; 10063 case OMPC_if: 10064 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10065 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10066 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10067 DelimLoc, EndLoc); 10068 break; 10069 case OMPC_dist_schedule: 10070 Res = ActOnOpenMPDistScheduleClause( 10071 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10072 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10073 break; 10074 case OMPC_defaultmap: 10075 enum { Modifier, DefaultmapKind }; 10076 Res = ActOnOpenMPDefaultmapClause( 10077 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10078 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10079 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10080 EndLoc); 10081 break; 10082 case OMPC_final: 10083 case OMPC_num_threads: 10084 case OMPC_safelen: 10085 case OMPC_simdlen: 10086 case OMPC_allocator: 10087 case OMPC_collapse: 10088 case OMPC_default: 10089 case OMPC_proc_bind: 10090 case OMPC_private: 10091 case OMPC_firstprivate: 10092 case OMPC_lastprivate: 10093 case OMPC_shared: 10094 case OMPC_reduction: 10095 case OMPC_task_reduction: 10096 case OMPC_in_reduction: 10097 case OMPC_linear: 10098 case OMPC_aligned: 10099 case OMPC_copyin: 10100 case OMPC_copyprivate: 10101 case OMPC_ordered: 10102 case OMPC_nowait: 10103 case OMPC_untied: 10104 case OMPC_mergeable: 10105 case OMPC_threadprivate: 10106 case OMPC_allocate: 10107 case OMPC_flush: 10108 case OMPC_read: 10109 case OMPC_write: 10110 case OMPC_update: 10111 case OMPC_capture: 10112 case OMPC_seq_cst: 10113 case OMPC_depend: 10114 case OMPC_device: 10115 case OMPC_threads: 10116 case OMPC_simd: 10117 case OMPC_map: 10118 case OMPC_num_teams: 10119 case OMPC_thread_limit: 10120 case OMPC_priority: 10121 case OMPC_grainsize: 10122 case OMPC_nogroup: 10123 case OMPC_num_tasks: 10124 case OMPC_hint: 10125 case OMPC_unknown: 10126 case OMPC_uniform: 10127 case OMPC_to: 10128 case OMPC_from: 10129 case OMPC_use_device_ptr: 10130 case OMPC_is_device_ptr: 10131 case OMPC_unified_address: 10132 case OMPC_unified_shared_memory: 10133 case OMPC_reverse_offload: 10134 case OMPC_dynamic_allocators: 10135 case OMPC_atomic_default_mem_order: 10136 llvm_unreachable("Clause is not allowed."); 10137 } 10138 return Res; 10139 } 10140 10141 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10142 OpenMPScheduleClauseModifier M2, 10143 SourceLocation M1Loc, SourceLocation M2Loc) { 10144 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10145 SmallVector<unsigned, 2> Excluded; 10146 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10147 Excluded.push_back(M2); 10148 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10149 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10150 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10151 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10152 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10153 << getListOfPossibleValues(OMPC_schedule, 10154 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10155 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10156 Excluded) 10157 << getOpenMPClauseName(OMPC_schedule); 10158 return true; 10159 } 10160 return false; 10161 } 10162 10163 OMPClause *Sema::ActOnOpenMPScheduleClause( 10164 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10165 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10166 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10167 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10168 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10169 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10170 return nullptr; 10171 // OpenMP, 2.7.1, Loop Construct, Restrictions 10172 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10173 // but not both. 10174 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10175 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10176 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10177 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10178 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10179 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10180 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10181 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10182 return nullptr; 10183 } 10184 if (Kind == OMPC_SCHEDULE_unknown) { 10185 std::string Values; 10186 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10187 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10188 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10189 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10190 Exclude); 10191 } else { 10192 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10193 /*Last=*/OMPC_SCHEDULE_unknown); 10194 } 10195 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10196 << Values << getOpenMPClauseName(OMPC_schedule); 10197 return nullptr; 10198 } 10199 // OpenMP, 2.7.1, Loop Construct, Restrictions 10200 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10201 // schedule(guided). 10202 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10203 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10204 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10205 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10206 diag::err_omp_schedule_nonmonotonic_static); 10207 return nullptr; 10208 } 10209 Expr *ValExpr = ChunkSize; 10210 Stmt *HelperValStmt = nullptr; 10211 if (ChunkSize) { 10212 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10213 !ChunkSize->isInstantiationDependent() && 10214 !ChunkSize->containsUnexpandedParameterPack()) { 10215 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10216 ExprResult Val = 10217 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10218 if (Val.isInvalid()) 10219 return nullptr; 10220 10221 ValExpr = Val.get(); 10222 10223 // OpenMP [2.7.1, Restrictions] 10224 // chunk_size must be a loop invariant integer expression with a positive 10225 // value. 10226 llvm::APSInt Result; 10227 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10228 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10229 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10230 << "schedule" << 1 << ChunkSize->getSourceRange(); 10231 return nullptr; 10232 } 10233 } else if (getOpenMPCaptureRegionForClause( 10234 DSAStack->getCurrentDirective(), OMPC_schedule) != 10235 OMPD_unknown && 10236 !CurContext->isDependentContext()) { 10237 ValExpr = MakeFullExpr(ValExpr).get(); 10238 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10239 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10240 HelperValStmt = buildPreInits(Context, Captures); 10241 } 10242 } 10243 } 10244 10245 return new (Context) 10246 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10247 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10248 } 10249 10250 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10251 SourceLocation StartLoc, 10252 SourceLocation EndLoc) { 10253 OMPClause *Res = nullptr; 10254 switch (Kind) { 10255 case OMPC_ordered: 10256 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10257 break; 10258 case OMPC_nowait: 10259 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10260 break; 10261 case OMPC_untied: 10262 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10263 break; 10264 case OMPC_mergeable: 10265 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10266 break; 10267 case OMPC_read: 10268 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10269 break; 10270 case OMPC_write: 10271 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10272 break; 10273 case OMPC_update: 10274 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10275 break; 10276 case OMPC_capture: 10277 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10278 break; 10279 case OMPC_seq_cst: 10280 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10281 break; 10282 case OMPC_threads: 10283 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10284 break; 10285 case OMPC_simd: 10286 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10287 break; 10288 case OMPC_nogroup: 10289 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10290 break; 10291 case OMPC_unified_address: 10292 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10293 break; 10294 case OMPC_unified_shared_memory: 10295 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10296 break; 10297 case OMPC_reverse_offload: 10298 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10299 break; 10300 case OMPC_dynamic_allocators: 10301 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10302 break; 10303 case OMPC_if: 10304 case OMPC_final: 10305 case OMPC_num_threads: 10306 case OMPC_safelen: 10307 case OMPC_simdlen: 10308 case OMPC_allocator: 10309 case OMPC_collapse: 10310 case OMPC_schedule: 10311 case OMPC_private: 10312 case OMPC_firstprivate: 10313 case OMPC_lastprivate: 10314 case OMPC_shared: 10315 case OMPC_reduction: 10316 case OMPC_task_reduction: 10317 case OMPC_in_reduction: 10318 case OMPC_linear: 10319 case OMPC_aligned: 10320 case OMPC_copyin: 10321 case OMPC_copyprivate: 10322 case OMPC_default: 10323 case OMPC_proc_bind: 10324 case OMPC_threadprivate: 10325 case OMPC_allocate: 10326 case OMPC_flush: 10327 case OMPC_depend: 10328 case OMPC_device: 10329 case OMPC_map: 10330 case OMPC_num_teams: 10331 case OMPC_thread_limit: 10332 case OMPC_priority: 10333 case OMPC_grainsize: 10334 case OMPC_num_tasks: 10335 case OMPC_hint: 10336 case OMPC_dist_schedule: 10337 case OMPC_defaultmap: 10338 case OMPC_unknown: 10339 case OMPC_uniform: 10340 case OMPC_to: 10341 case OMPC_from: 10342 case OMPC_use_device_ptr: 10343 case OMPC_is_device_ptr: 10344 case OMPC_atomic_default_mem_order: 10345 llvm_unreachable("Clause is not allowed."); 10346 } 10347 return Res; 10348 } 10349 10350 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10351 SourceLocation EndLoc) { 10352 DSAStack->setNowaitRegion(); 10353 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10354 } 10355 10356 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10357 SourceLocation EndLoc) { 10358 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10359 } 10360 10361 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10362 SourceLocation EndLoc) { 10363 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10364 } 10365 10366 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10367 SourceLocation EndLoc) { 10368 return new (Context) OMPReadClause(StartLoc, EndLoc); 10369 } 10370 10371 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10372 SourceLocation EndLoc) { 10373 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10374 } 10375 10376 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10377 SourceLocation EndLoc) { 10378 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10379 } 10380 10381 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10382 SourceLocation EndLoc) { 10383 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10384 } 10385 10386 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10387 SourceLocation EndLoc) { 10388 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10389 } 10390 10391 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10392 SourceLocation EndLoc) { 10393 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10394 } 10395 10396 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 10397 SourceLocation EndLoc) { 10398 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 10399 } 10400 10401 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 10402 SourceLocation EndLoc) { 10403 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 10404 } 10405 10406 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 10407 SourceLocation EndLoc) { 10408 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 10409 } 10410 10411 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 10412 SourceLocation EndLoc) { 10413 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10414 } 10415 10416 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 10417 SourceLocation EndLoc) { 10418 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 10419 } 10420 10421 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 10422 SourceLocation EndLoc) { 10423 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 10424 } 10425 10426 OMPClause *Sema::ActOnOpenMPVarListClause( 10427 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 10428 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 10429 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 10430 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 10431 OpenMPLinearClauseKind LinKind, 10432 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 10433 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 10434 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 10435 SourceLocation StartLoc = Locs.StartLoc; 10436 SourceLocation LParenLoc = Locs.LParenLoc; 10437 SourceLocation EndLoc = Locs.EndLoc; 10438 OMPClause *Res = nullptr; 10439 switch (Kind) { 10440 case OMPC_private: 10441 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10442 break; 10443 case OMPC_firstprivate: 10444 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10445 break; 10446 case OMPC_lastprivate: 10447 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10448 break; 10449 case OMPC_shared: 10450 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10451 break; 10452 case OMPC_reduction: 10453 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10454 EndLoc, ReductionOrMapperIdScopeSpec, 10455 ReductionOrMapperId); 10456 break; 10457 case OMPC_task_reduction: 10458 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10459 EndLoc, ReductionOrMapperIdScopeSpec, 10460 ReductionOrMapperId); 10461 break; 10462 case OMPC_in_reduction: 10463 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10464 EndLoc, ReductionOrMapperIdScopeSpec, 10465 ReductionOrMapperId); 10466 break; 10467 case OMPC_linear: 10468 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10469 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10470 break; 10471 case OMPC_aligned: 10472 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10473 ColonLoc, EndLoc); 10474 break; 10475 case OMPC_copyin: 10476 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10477 break; 10478 case OMPC_copyprivate: 10479 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10480 break; 10481 case OMPC_flush: 10482 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10483 break; 10484 case OMPC_depend: 10485 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10486 StartLoc, LParenLoc, EndLoc); 10487 break; 10488 case OMPC_map: 10489 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10490 ReductionOrMapperIdScopeSpec, 10491 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10492 DepLinMapLoc, ColonLoc, VarList, Locs); 10493 break; 10494 case OMPC_to: 10495 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10496 ReductionOrMapperId, Locs); 10497 break; 10498 case OMPC_from: 10499 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10500 ReductionOrMapperId, Locs); 10501 break; 10502 case OMPC_use_device_ptr: 10503 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10504 break; 10505 case OMPC_is_device_ptr: 10506 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10507 break; 10508 case OMPC_allocate: 10509 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 10510 ColonLoc, EndLoc); 10511 break; 10512 case OMPC_if: 10513 case OMPC_final: 10514 case OMPC_num_threads: 10515 case OMPC_safelen: 10516 case OMPC_simdlen: 10517 case OMPC_allocator: 10518 case OMPC_collapse: 10519 case OMPC_default: 10520 case OMPC_proc_bind: 10521 case OMPC_schedule: 10522 case OMPC_ordered: 10523 case OMPC_nowait: 10524 case OMPC_untied: 10525 case OMPC_mergeable: 10526 case OMPC_threadprivate: 10527 case OMPC_read: 10528 case OMPC_write: 10529 case OMPC_update: 10530 case OMPC_capture: 10531 case OMPC_seq_cst: 10532 case OMPC_device: 10533 case OMPC_threads: 10534 case OMPC_simd: 10535 case OMPC_num_teams: 10536 case OMPC_thread_limit: 10537 case OMPC_priority: 10538 case OMPC_grainsize: 10539 case OMPC_nogroup: 10540 case OMPC_num_tasks: 10541 case OMPC_hint: 10542 case OMPC_dist_schedule: 10543 case OMPC_defaultmap: 10544 case OMPC_unknown: 10545 case OMPC_uniform: 10546 case OMPC_unified_address: 10547 case OMPC_unified_shared_memory: 10548 case OMPC_reverse_offload: 10549 case OMPC_dynamic_allocators: 10550 case OMPC_atomic_default_mem_order: 10551 llvm_unreachable("Clause is not allowed."); 10552 } 10553 return Res; 10554 } 10555 10556 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10557 ExprObjectKind OK, SourceLocation Loc) { 10558 ExprResult Res = BuildDeclRefExpr( 10559 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10560 if (!Res.isUsable()) 10561 return ExprError(); 10562 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10563 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10564 if (!Res.isUsable()) 10565 return ExprError(); 10566 } 10567 if (VK != VK_LValue && Res.get()->isGLValue()) { 10568 Res = DefaultLvalueConversion(Res.get()); 10569 if (!Res.isUsable()) 10570 return ExprError(); 10571 } 10572 return Res; 10573 } 10574 10575 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10576 SourceLocation StartLoc, 10577 SourceLocation LParenLoc, 10578 SourceLocation EndLoc) { 10579 SmallVector<Expr *, 8> Vars; 10580 SmallVector<Expr *, 8> PrivateCopies; 10581 for (Expr *RefExpr : VarList) { 10582 assert(RefExpr && "NULL expr in OpenMP private clause."); 10583 SourceLocation ELoc; 10584 SourceRange ERange; 10585 Expr *SimpleRefExpr = RefExpr; 10586 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10587 if (Res.second) { 10588 // It will be analyzed later. 10589 Vars.push_back(RefExpr); 10590 PrivateCopies.push_back(nullptr); 10591 } 10592 ValueDecl *D = Res.first; 10593 if (!D) 10594 continue; 10595 10596 QualType Type = D->getType(); 10597 auto *VD = dyn_cast<VarDecl>(D); 10598 10599 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10600 // A variable that appears in a private clause must not have an incomplete 10601 // type or a reference type. 10602 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10603 continue; 10604 Type = Type.getNonReferenceType(); 10605 10606 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10607 // A variable that is privatized must not have a const-qualified type 10608 // unless it is of class type with a mutable member. This restriction does 10609 // not apply to the firstprivate clause. 10610 // 10611 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10612 // A variable that appears in a private clause must not have a 10613 // const-qualified type unless it is of class type with a mutable member. 10614 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10615 continue; 10616 10617 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10618 // in a Construct] 10619 // Variables with the predetermined data-sharing attributes may not be 10620 // listed in data-sharing attributes clauses, except for the cases 10621 // listed below. For these exceptions only, listing a predetermined 10622 // variable in a data-sharing attribute clause is allowed and overrides 10623 // the variable's predetermined data-sharing attributes. 10624 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10625 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10626 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10627 << getOpenMPClauseName(OMPC_private); 10628 reportOriginalDsa(*this, DSAStack, D, DVar); 10629 continue; 10630 } 10631 10632 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10633 // Variably modified types are not supported for tasks. 10634 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10635 isOpenMPTaskingDirective(CurrDir)) { 10636 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10637 << getOpenMPClauseName(OMPC_private) << Type 10638 << getOpenMPDirectiveName(CurrDir); 10639 bool IsDecl = 10640 !VD || 10641 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10642 Diag(D->getLocation(), 10643 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10644 << D; 10645 continue; 10646 } 10647 10648 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10649 // A list item cannot appear in both a map clause and a data-sharing 10650 // attribute clause on the same construct 10651 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10652 OpenMPClauseKind ConflictKind; 10653 if (DSAStack->checkMappableExprComponentListsForDecl( 10654 VD, /*CurrentRegionOnly=*/true, 10655 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10656 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10657 ConflictKind = WhereFoundClauseKind; 10658 return true; 10659 })) { 10660 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10661 << getOpenMPClauseName(OMPC_private) 10662 << getOpenMPClauseName(ConflictKind) 10663 << getOpenMPDirectiveName(CurrDir); 10664 reportOriginalDsa(*this, DSAStack, D, DVar); 10665 continue; 10666 } 10667 } 10668 10669 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10670 // A variable of class type (or array thereof) that appears in a private 10671 // clause requires an accessible, unambiguous default constructor for the 10672 // class type. 10673 // Generate helper private variable and initialize it with the default 10674 // value. The address of the original variable is replaced by the address of 10675 // the new private variable in CodeGen. This new variable is not added to 10676 // IdResolver, so the code in the OpenMP region uses original variable for 10677 // proper diagnostics. 10678 Type = Type.getUnqualifiedType(); 10679 VarDecl *VDPrivate = 10680 buildVarDecl(*this, ELoc, Type, D->getName(), 10681 D->hasAttrs() ? &D->getAttrs() : nullptr, 10682 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10683 ActOnUninitializedDecl(VDPrivate); 10684 if (VDPrivate->isInvalidDecl()) 10685 continue; 10686 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10687 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10688 10689 DeclRefExpr *Ref = nullptr; 10690 if (!VD && !CurContext->isDependentContext()) 10691 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10692 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10693 Vars.push_back((VD || CurContext->isDependentContext()) 10694 ? RefExpr->IgnoreParens() 10695 : Ref); 10696 PrivateCopies.push_back(VDPrivateRefExpr); 10697 } 10698 10699 if (Vars.empty()) 10700 return nullptr; 10701 10702 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10703 PrivateCopies); 10704 } 10705 10706 namespace { 10707 class DiagsUninitializedSeveretyRAII { 10708 private: 10709 DiagnosticsEngine &Diags; 10710 SourceLocation SavedLoc; 10711 bool IsIgnored = false; 10712 10713 public: 10714 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10715 bool IsIgnored) 10716 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10717 if (!IsIgnored) { 10718 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10719 /*Map*/ diag::Severity::Ignored, Loc); 10720 } 10721 } 10722 ~DiagsUninitializedSeveretyRAII() { 10723 if (!IsIgnored) 10724 Diags.popMappings(SavedLoc); 10725 } 10726 }; 10727 } 10728 10729 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10730 SourceLocation StartLoc, 10731 SourceLocation LParenLoc, 10732 SourceLocation EndLoc) { 10733 SmallVector<Expr *, 8> Vars; 10734 SmallVector<Expr *, 8> PrivateCopies; 10735 SmallVector<Expr *, 8> Inits; 10736 SmallVector<Decl *, 4> ExprCaptures; 10737 bool IsImplicitClause = 10738 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10739 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10740 10741 for (Expr *RefExpr : VarList) { 10742 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10743 SourceLocation ELoc; 10744 SourceRange ERange; 10745 Expr *SimpleRefExpr = RefExpr; 10746 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10747 if (Res.second) { 10748 // It will be analyzed later. 10749 Vars.push_back(RefExpr); 10750 PrivateCopies.push_back(nullptr); 10751 Inits.push_back(nullptr); 10752 } 10753 ValueDecl *D = Res.first; 10754 if (!D) 10755 continue; 10756 10757 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10758 QualType Type = D->getType(); 10759 auto *VD = dyn_cast<VarDecl>(D); 10760 10761 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10762 // A variable that appears in a private clause must not have an incomplete 10763 // type or a reference type. 10764 if (RequireCompleteType(ELoc, Type, 10765 diag::err_omp_firstprivate_incomplete_type)) 10766 continue; 10767 Type = Type.getNonReferenceType(); 10768 10769 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10770 // A variable of class type (or array thereof) that appears in a private 10771 // clause requires an accessible, unambiguous copy constructor for the 10772 // class type. 10773 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10774 10775 // If an implicit firstprivate variable found it was checked already. 10776 DSAStackTy::DSAVarData TopDVar; 10777 if (!IsImplicitClause) { 10778 DSAStackTy::DSAVarData DVar = 10779 DSAStack->getTopDSA(D, /*FromParent=*/false); 10780 TopDVar = DVar; 10781 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10782 bool IsConstant = ElemType.isConstant(Context); 10783 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10784 // A list item that specifies a given variable may not appear in more 10785 // than one clause on the same directive, except that a variable may be 10786 // specified in both firstprivate and lastprivate clauses. 10787 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10788 // A list item may appear in a firstprivate or lastprivate clause but not 10789 // both. 10790 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10791 (isOpenMPDistributeDirective(CurrDir) || 10792 DVar.CKind != OMPC_lastprivate) && 10793 DVar.RefExpr) { 10794 Diag(ELoc, diag::err_omp_wrong_dsa) 10795 << getOpenMPClauseName(DVar.CKind) 10796 << getOpenMPClauseName(OMPC_firstprivate); 10797 reportOriginalDsa(*this, DSAStack, D, DVar); 10798 continue; 10799 } 10800 10801 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10802 // in a Construct] 10803 // Variables with the predetermined data-sharing attributes may not be 10804 // listed in data-sharing attributes clauses, except for the cases 10805 // listed below. For these exceptions only, listing a predetermined 10806 // variable in a data-sharing attribute clause is allowed and overrides 10807 // the variable's predetermined data-sharing attributes. 10808 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10809 // in a Construct, C/C++, p.2] 10810 // Variables with const-qualified type having no mutable member may be 10811 // listed in a firstprivate clause, even if they are static data members. 10812 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 10813 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 10814 Diag(ELoc, diag::err_omp_wrong_dsa) 10815 << getOpenMPClauseName(DVar.CKind) 10816 << getOpenMPClauseName(OMPC_firstprivate); 10817 reportOriginalDsa(*this, DSAStack, D, DVar); 10818 continue; 10819 } 10820 10821 // OpenMP [2.9.3.4, Restrictions, p.2] 10822 // A list item that is private within a parallel region must not appear 10823 // in a firstprivate clause on a worksharing construct if any of the 10824 // worksharing regions arising from the worksharing construct ever bind 10825 // to any of the parallel regions arising from the parallel construct. 10826 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10827 // A list item that is private within a teams region must not appear in a 10828 // firstprivate clause on a distribute construct if any of the distribute 10829 // regions arising from the distribute construct ever bind to any of the 10830 // teams regions arising from the teams construct. 10831 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10832 // A list item that appears in a reduction clause of a teams construct 10833 // must not appear in a firstprivate clause on a distribute construct if 10834 // any of the distribute regions arising from the distribute construct 10835 // ever bind to any of the teams regions arising from the teams construct. 10836 if ((isOpenMPWorksharingDirective(CurrDir) || 10837 isOpenMPDistributeDirective(CurrDir)) && 10838 !isOpenMPParallelDirective(CurrDir) && 10839 !isOpenMPTeamsDirective(CurrDir)) { 10840 DVar = DSAStack->getImplicitDSA(D, true); 10841 if (DVar.CKind != OMPC_shared && 10842 (isOpenMPParallelDirective(DVar.DKind) || 10843 isOpenMPTeamsDirective(DVar.DKind) || 10844 DVar.DKind == OMPD_unknown)) { 10845 Diag(ELoc, diag::err_omp_required_access) 10846 << getOpenMPClauseName(OMPC_firstprivate) 10847 << getOpenMPClauseName(OMPC_shared); 10848 reportOriginalDsa(*this, DSAStack, D, DVar); 10849 continue; 10850 } 10851 } 10852 // OpenMP [2.9.3.4, Restrictions, p.3] 10853 // A list item that appears in a reduction clause of a parallel construct 10854 // must not appear in a firstprivate clause on a worksharing or task 10855 // construct if any of the worksharing or task regions arising from the 10856 // worksharing or task construct ever bind to any of the parallel regions 10857 // arising from the parallel construct. 10858 // OpenMP [2.9.3.4, Restrictions, p.4] 10859 // A list item that appears in a reduction clause in worksharing 10860 // construct must not appear in a firstprivate clause in a task construct 10861 // encountered during execution of any of the worksharing regions arising 10862 // from the worksharing construct. 10863 if (isOpenMPTaskingDirective(CurrDir)) { 10864 DVar = DSAStack->hasInnermostDSA( 10865 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 10866 [](OpenMPDirectiveKind K) { 10867 return isOpenMPParallelDirective(K) || 10868 isOpenMPWorksharingDirective(K) || 10869 isOpenMPTeamsDirective(K); 10870 }, 10871 /*FromParent=*/true); 10872 if (DVar.CKind == OMPC_reduction && 10873 (isOpenMPParallelDirective(DVar.DKind) || 10874 isOpenMPWorksharingDirective(DVar.DKind) || 10875 isOpenMPTeamsDirective(DVar.DKind))) { 10876 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 10877 << getOpenMPDirectiveName(DVar.DKind); 10878 reportOriginalDsa(*this, DSAStack, D, DVar); 10879 continue; 10880 } 10881 } 10882 10883 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10884 // A list item cannot appear in both a map clause and a data-sharing 10885 // attribute clause on the same construct 10886 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10887 OpenMPClauseKind ConflictKind; 10888 if (DSAStack->checkMappableExprComponentListsForDecl( 10889 VD, /*CurrentRegionOnly=*/true, 10890 [&ConflictKind]( 10891 OMPClauseMappableExprCommon::MappableExprComponentListRef, 10892 OpenMPClauseKind WhereFoundClauseKind) { 10893 ConflictKind = WhereFoundClauseKind; 10894 return true; 10895 })) { 10896 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10897 << getOpenMPClauseName(OMPC_firstprivate) 10898 << getOpenMPClauseName(ConflictKind) 10899 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10900 reportOriginalDsa(*this, DSAStack, D, DVar); 10901 continue; 10902 } 10903 } 10904 } 10905 10906 // Variably modified types are not supported for tasks. 10907 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10908 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 10909 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10910 << getOpenMPClauseName(OMPC_firstprivate) << Type 10911 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10912 bool IsDecl = 10913 !VD || 10914 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10915 Diag(D->getLocation(), 10916 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10917 << D; 10918 continue; 10919 } 10920 10921 Type = Type.getUnqualifiedType(); 10922 VarDecl *VDPrivate = 10923 buildVarDecl(*this, ELoc, Type, D->getName(), 10924 D->hasAttrs() ? &D->getAttrs() : nullptr, 10925 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10926 // Generate helper private variable and initialize it with the value of the 10927 // original variable. The address of the original variable is replaced by 10928 // the address of the new private variable in the CodeGen. This new variable 10929 // is not added to IdResolver, so the code in the OpenMP region uses 10930 // original variable for proper diagnostics and variable capturing. 10931 Expr *VDInitRefExpr = nullptr; 10932 // For arrays generate initializer for single element and replace it by the 10933 // original array element in CodeGen. 10934 if (Type->isArrayType()) { 10935 VarDecl *VDInit = 10936 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 10937 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 10938 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 10939 ElemType = ElemType.getUnqualifiedType(); 10940 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 10941 ".firstprivate.temp"); 10942 InitializedEntity Entity = 10943 InitializedEntity::InitializeVariable(VDInitTemp); 10944 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 10945 10946 InitializationSequence InitSeq(*this, Entity, Kind, Init); 10947 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 10948 if (Result.isInvalid()) 10949 VDPrivate->setInvalidDecl(); 10950 else 10951 VDPrivate->setInit(Result.getAs<Expr>()); 10952 // Remove temp variable declaration. 10953 Context.Deallocate(VDInitTemp); 10954 } else { 10955 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 10956 ".firstprivate.temp"); 10957 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 10958 RefExpr->getExprLoc()); 10959 AddInitializerToDecl(VDPrivate, 10960 DefaultLvalueConversion(VDInitRefExpr).get(), 10961 /*DirectInit=*/false); 10962 } 10963 if (VDPrivate->isInvalidDecl()) { 10964 if (IsImplicitClause) { 10965 Diag(RefExpr->getExprLoc(), 10966 diag::note_omp_task_predetermined_firstprivate_here); 10967 } 10968 continue; 10969 } 10970 CurContext->addDecl(VDPrivate); 10971 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10972 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 10973 RefExpr->getExprLoc()); 10974 DeclRefExpr *Ref = nullptr; 10975 if (!VD && !CurContext->isDependentContext()) { 10976 if (TopDVar.CKind == OMPC_lastprivate) { 10977 Ref = TopDVar.PrivateCopy; 10978 } else { 10979 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10980 if (!isOpenMPCapturedDecl(D)) 10981 ExprCaptures.push_back(Ref->getDecl()); 10982 } 10983 } 10984 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 10985 Vars.push_back((VD || CurContext->isDependentContext()) 10986 ? RefExpr->IgnoreParens() 10987 : Ref); 10988 PrivateCopies.push_back(VDPrivateRefExpr); 10989 Inits.push_back(VDInitRefExpr); 10990 } 10991 10992 if (Vars.empty()) 10993 return nullptr; 10994 10995 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10996 Vars, PrivateCopies, Inits, 10997 buildPreInits(Context, ExprCaptures)); 10998 } 10999 11000 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11001 SourceLocation StartLoc, 11002 SourceLocation LParenLoc, 11003 SourceLocation EndLoc) { 11004 SmallVector<Expr *, 8> Vars; 11005 SmallVector<Expr *, 8> SrcExprs; 11006 SmallVector<Expr *, 8> DstExprs; 11007 SmallVector<Expr *, 8> AssignmentOps; 11008 SmallVector<Decl *, 4> ExprCaptures; 11009 SmallVector<Expr *, 4> ExprPostUpdates; 11010 for (Expr *RefExpr : VarList) { 11011 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11012 SourceLocation ELoc; 11013 SourceRange ERange; 11014 Expr *SimpleRefExpr = RefExpr; 11015 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11016 if (Res.second) { 11017 // It will be analyzed later. 11018 Vars.push_back(RefExpr); 11019 SrcExprs.push_back(nullptr); 11020 DstExprs.push_back(nullptr); 11021 AssignmentOps.push_back(nullptr); 11022 } 11023 ValueDecl *D = Res.first; 11024 if (!D) 11025 continue; 11026 11027 QualType Type = D->getType(); 11028 auto *VD = dyn_cast<VarDecl>(D); 11029 11030 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11031 // A variable that appears in a lastprivate clause must not have an 11032 // incomplete type or a reference type. 11033 if (RequireCompleteType(ELoc, Type, 11034 diag::err_omp_lastprivate_incomplete_type)) 11035 continue; 11036 Type = Type.getNonReferenceType(); 11037 11038 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11039 // A variable that is privatized must not have a const-qualified type 11040 // unless it is of class type with a mutable member. This restriction does 11041 // not apply to the firstprivate clause. 11042 // 11043 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11044 // A variable that appears in a lastprivate clause must not have a 11045 // const-qualified type unless it is of class type with a mutable member. 11046 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11047 continue; 11048 11049 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11050 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11051 // in a Construct] 11052 // Variables with the predetermined data-sharing attributes may not be 11053 // listed in data-sharing attributes clauses, except for the cases 11054 // listed below. 11055 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11056 // A list item may appear in a firstprivate or lastprivate clause but not 11057 // both. 11058 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11059 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11060 (isOpenMPDistributeDirective(CurrDir) || 11061 DVar.CKind != OMPC_firstprivate) && 11062 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11063 Diag(ELoc, diag::err_omp_wrong_dsa) 11064 << getOpenMPClauseName(DVar.CKind) 11065 << getOpenMPClauseName(OMPC_lastprivate); 11066 reportOriginalDsa(*this, DSAStack, D, DVar); 11067 continue; 11068 } 11069 11070 // OpenMP [2.14.3.5, Restrictions, p.2] 11071 // A list item that is private within a parallel region, or that appears in 11072 // the reduction clause of a parallel construct, must not appear in a 11073 // lastprivate clause on a worksharing construct if any of the corresponding 11074 // worksharing regions ever binds to any of the corresponding parallel 11075 // regions. 11076 DSAStackTy::DSAVarData TopDVar = DVar; 11077 if (isOpenMPWorksharingDirective(CurrDir) && 11078 !isOpenMPParallelDirective(CurrDir) && 11079 !isOpenMPTeamsDirective(CurrDir)) { 11080 DVar = DSAStack->getImplicitDSA(D, true); 11081 if (DVar.CKind != OMPC_shared) { 11082 Diag(ELoc, diag::err_omp_required_access) 11083 << getOpenMPClauseName(OMPC_lastprivate) 11084 << getOpenMPClauseName(OMPC_shared); 11085 reportOriginalDsa(*this, DSAStack, D, DVar); 11086 continue; 11087 } 11088 } 11089 11090 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11091 // A variable of class type (or array thereof) that appears in a 11092 // lastprivate clause requires an accessible, unambiguous default 11093 // constructor for the class type, unless the list item is also specified 11094 // in a firstprivate clause. 11095 // A variable of class type (or array thereof) that appears in a 11096 // lastprivate clause requires an accessible, unambiguous copy assignment 11097 // operator for the class type. 11098 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11099 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11100 Type.getUnqualifiedType(), ".lastprivate.src", 11101 D->hasAttrs() ? &D->getAttrs() : nullptr); 11102 DeclRefExpr *PseudoSrcExpr = 11103 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11104 VarDecl *DstVD = 11105 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11106 D->hasAttrs() ? &D->getAttrs() : nullptr); 11107 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11108 // For arrays generate assignment operation for single element and replace 11109 // it by the original array element in CodeGen. 11110 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11111 PseudoDstExpr, PseudoSrcExpr); 11112 if (AssignmentOp.isInvalid()) 11113 continue; 11114 AssignmentOp = 11115 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11116 if (AssignmentOp.isInvalid()) 11117 continue; 11118 11119 DeclRefExpr *Ref = nullptr; 11120 if (!VD && !CurContext->isDependentContext()) { 11121 if (TopDVar.CKind == OMPC_firstprivate) { 11122 Ref = TopDVar.PrivateCopy; 11123 } else { 11124 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11125 if (!isOpenMPCapturedDecl(D)) 11126 ExprCaptures.push_back(Ref->getDecl()); 11127 } 11128 if (TopDVar.CKind == OMPC_firstprivate || 11129 (!isOpenMPCapturedDecl(D) && 11130 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11131 ExprResult RefRes = DefaultLvalueConversion(Ref); 11132 if (!RefRes.isUsable()) 11133 continue; 11134 ExprResult PostUpdateRes = 11135 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11136 RefRes.get()); 11137 if (!PostUpdateRes.isUsable()) 11138 continue; 11139 ExprPostUpdates.push_back( 11140 IgnoredValueConversions(PostUpdateRes.get()).get()); 11141 } 11142 } 11143 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11144 Vars.push_back((VD || CurContext->isDependentContext()) 11145 ? RefExpr->IgnoreParens() 11146 : Ref); 11147 SrcExprs.push_back(PseudoSrcExpr); 11148 DstExprs.push_back(PseudoDstExpr); 11149 AssignmentOps.push_back(AssignmentOp.get()); 11150 } 11151 11152 if (Vars.empty()) 11153 return nullptr; 11154 11155 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11156 Vars, SrcExprs, DstExprs, AssignmentOps, 11157 buildPreInits(Context, ExprCaptures), 11158 buildPostUpdate(*this, ExprPostUpdates)); 11159 } 11160 11161 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11162 SourceLocation StartLoc, 11163 SourceLocation LParenLoc, 11164 SourceLocation EndLoc) { 11165 SmallVector<Expr *, 8> Vars; 11166 for (Expr *RefExpr : VarList) { 11167 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11168 SourceLocation ELoc; 11169 SourceRange ERange; 11170 Expr *SimpleRefExpr = RefExpr; 11171 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11172 if (Res.second) { 11173 // It will be analyzed later. 11174 Vars.push_back(RefExpr); 11175 } 11176 ValueDecl *D = Res.first; 11177 if (!D) 11178 continue; 11179 11180 auto *VD = dyn_cast<VarDecl>(D); 11181 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11182 // in a Construct] 11183 // Variables with the predetermined data-sharing attributes may not be 11184 // listed in data-sharing attributes clauses, except for the cases 11185 // listed below. For these exceptions only, listing a predetermined 11186 // variable in a data-sharing attribute clause is allowed and overrides 11187 // the variable's predetermined data-sharing attributes. 11188 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11189 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11190 DVar.RefExpr) { 11191 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11192 << getOpenMPClauseName(OMPC_shared); 11193 reportOriginalDsa(*this, DSAStack, D, DVar); 11194 continue; 11195 } 11196 11197 DeclRefExpr *Ref = nullptr; 11198 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11199 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11200 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11201 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11202 ? RefExpr->IgnoreParens() 11203 : Ref); 11204 } 11205 11206 if (Vars.empty()) 11207 return nullptr; 11208 11209 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11210 } 11211 11212 namespace { 11213 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11214 DSAStackTy *Stack; 11215 11216 public: 11217 bool VisitDeclRefExpr(DeclRefExpr *E) { 11218 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11219 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11220 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11221 return false; 11222 if (DVar.CKind != OMPC_unknown) 11223 return true; 11224 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11225 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11226 /*FromParent=*/true); 11227 return DVarPrivate.CKind != OMPC_unknown; 11228 } 11229 return false; 11230 } 11231 bool VisitStmt(Stmt *S) { 11232 for (Stmt *Child : S->children()) { 11233 if (Child && Visit(Child)) 11234 return true; 11235 } 11236 return false; 11237 } 11238 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11239 }; 11240 } // namespace 11241 11242 namespace { 11243 // Transform MemberExpression for specified FieldDecl of current class to 11244 // DeclRefExpr to specified OMPCapturedExprDecl. 11245 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11246 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11247 ValueDecl *Field = nullptr; 11248 DeclRefExpr *CapturedExpr = nullptr; 11249 11250 public: 11251 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11252 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11253 11254 ExprResult TransformMemberExpr(MemberExpr *E) { 11255 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11256 E->getMemberDecl() == Field) { 11257 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11258 return CapturedExpr; 11259 } 11260 return BaseTransform::TransformMemberExpr(E); 11261 } 11262 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11263 }; 11264 } // namespace 11265 11266 template <typename T, typename U> 11267 static T filterLookupForUDReductionAndMapper( 11268 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11269 for (U &Set : Lookups) { 11270 for (auto *D : Set) { 11271 if (T Res = Gen(cast<ValueDecl>(D))) 11272 return Res; 11273 } 11274 } 11275 return T(); 11276 } 11277 11278 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11279 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11280 11281 for (auto RD : D->redecls()) { 11282 // Don't bother with extra checks if we already know this one isn't visible. 11283 if (RD == D) 11284 continue; 11285 11286 auto ND = cast<NamedDecl>(RD); 11287 if (LookupResult::isVisible(SemaRef, ND)) 11288 return ND; 11289 } 11290 11291 return nullptr; 11292 } 11293 11294 static void 11295 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11296 SourceLocation Loc, QualType Ty, 11297 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11298 // Find all of the associated namespaces and classes based on the 11299 // arguments we have. 11300 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11301 Sema::AssociatedClassSet AssociatedClasses; 11302 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11303 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11304 AssociatedClasses); 11305 11306 // C++ [basic.lookup.argdep]p3: 11307 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11308 // and let Y be the lookup set produced by argument dependent 11309 // lookup (defined as follows). If X contains [...] then Y is 11310 // empty. Otherwise Y is the set of declarations found in the 11311 // namespaces associated with the argument types as described 11312 // below. The set of declarations found by the lookup of the name 11313 // is the union of X and Y. 11314 // 11315 // Here, we compute Y and add its members to the overloaded 11316 // candidate set. 11317 for (auto *NS : AssociatedNamespaces) { 11318 // When considering an associated namespace, the lookup is the 11319 // same as the lookup performed when the associated namespace is 11320 // used as a qualifier (3.4.3.2) except that: 11321 // 11322 // -- Any using-directives in the associated namespace are 11323 // ignored. 11324 // 11325 // -- Any namespace-scope friend functions declared in 11326 // associated classes are visible within their respective 11327 // namespaces even if they are not visible during an ordinary 11328 // lookup (11.4). 11329 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11330 for (auto *D : R) { 11331 auto *Underlying = D; 11332 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11333 Underlying = USD->getTargetDecl(); 11334 11335 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11336 !isa<OMPDeclareMapperDecl>(Underlying)) 11337 continue; 11338 11339 if (!SemaRef.isVisible(D)) { 11340 D = findAcceptableDecl(SemaRef, D); 11341 if (!D) 11342 continue; 11343 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11344 Underlying = USD->getTargetDecl(); 11345 } 11346 Lookups.emplace_back(); 11347 Lookups.back().addDecl(Underlying); 11348 } 11349 } 11350 } 11351 11352 static ExprResult 11353 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11354 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11355 const DeclarationNameInfo &ReductionId, QualType Ty, 11356 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11357 if (ReductionIdScopeSpec.isInvalid()) 11358 return ExprError(); 11359 SmallVector<UnresolvedSet<8>, 4> Lookups; 11360 if (S) { 11361 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11362 Lookup.suppressDiagnostics(); 11363 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11364 NamedDecl *D = Lookup.getRepresentativeDecl(); 11365 do { 11366 S = S->getParent(); 11367 } while (S && !S->isDeclScope(D)); 11368 if (S) 11369 S = S->getParent(); 11370 Lookups.emplace_back(); 11371 Lookups.back().append(Lookup.begin(), Lookup.end()); 11372 Lookup.clear(); 11373 } 11374 } else if (auto *ULE = 11375 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11376 Lookups.push_back(UnresolvedSet<8>()); 11377 Decl *PrevD = nullptr; 11378 for (NamedDecl *D : ULE->decls()) { 11379 if (D == PrevD) 11380 Lookups.push_back(UnresolvedSet<8>()); 11381 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11382 Lookups.back().addDecl(DRD); 11383 PrevD = D; 11384 } 11385 } 11386 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11387 Ty->isInstantiationDependentType() || 11388 Ty->containsUnexpandedParameterPack() || 11389 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11390 return !D->isInvalidDecl() && 11391 (D->getType()->isDependentType() || 11392 D->getType()->isInstantiationDependentType() || 11393 D->getType()->containsUnexpandedParameterPack()); 11394 })) { 11395 UnresolvedSet<8> ResSet; 11396 for (const UnresolvedSet<8> &Set : Lookups) { 11397 if (Set.empty()) 11398 continue; 11399 ResSet.append(Set.begin(), Set.end()); 11400 // The last item marks the end of all declarations at the specified scope. 11401 ResSet.addDecl(Set[Set.size() - 1]); 11402 } 11403 return UnresolvedLookupExpr::Create( 11404 SemaRef.Context, /*NamingClass=*/nullptr, 11405 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11406 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11407 } 11408 // Lookup inside the classes. 11409 // C++ [over.match.oper]p3: 11410 // For a unary operator @ with an operand of a type whose 11411 // cv-unqualified version is T1, and for a binary operator @ with 11412 // a left operand of a type whose cv-unqualified version is T1 and 11413 // a right operand of a type whose cv-unqualified version is T2, 11414 // three sets of candidate functions, designated member 11415 // candidates, non-member candidates and built-in candidates, are 11416 // constructed as follows: 11417 // -- If T1 is a complete class type or a class currently being 11418 // defined, the set of member candidates is the result of the 11419 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11420 // the set of member candidates is empty. 11421 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11422 Lookup.suppressDiagnostics(); 11423 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11424 // Complete the type if it can be completed. 11425 // If the type is neither complete nor being defined, bail out now. 11426 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11427 TyRec->getDecl()->getDefinition()) { 11428 Lookup.clear(); 11429 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11430 if (Lookup.empty()) { 11431 Lookups.emplace_back(); 11432 Lookups.back().append(Lookup.begin(), Lookup.end()); 11433 } 11434 } 11435 } 11436 // Perform ADL. 11437 if (SemaRef.getLangOpts().CPlusPlus) 11438 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11439 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11440 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11441 if (!D->isInvalidDecl() && 11442 SemaRef.Context.hasSameType(D->getType(), Ty)) 11443 return D; 11444 return nullptr; 11445 })) 11446 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11447 VK_LValue, Loc); 11448 if (SemaRef.getLangOpts().CPlusPlus) { 11449 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11450 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11451 if (!D->isInvalidDecl() && 11452 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11453 !Ty.isMoreQualifiedThan(D->getType())) 11454 return D; 11455 return nullptr; 11456 })) { 11457 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11458 /*DetectVirtual=*/false); 11459 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11460 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11461 VD->getType().getUnqualifiedType()))) { 11462 if (SemaRef.CheckBaseClassAccess( 11463 Loc, VD->getType(), Ty, Paths.front(), 11464 /*DiagID=*/0) != Sema::AR_inaccessible) { 11465 SemaRef.BuildBasePathArray(Paths, BasePath); 11466 return SemaRef.BuildDeclRefExpr( 11467 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11468 } 11469 } 11470 } 11471 } 11472 } 11473 if (ReductionIdScopeSpec.isSet()) { 11474 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11475 return ExprError(); 11476 } 11477 return ExprEmpty(); 11478 } 11479 11480 namespace { 11481 /// Data for the reduction-based clauses. 11482 struct ReductionData { 11483 /// List of original reduction items. 11484 SmallVector<Expr *, 8> Vars; 11485 /// List of private copies of the reduction items. 11486 SmallVector<Expr *, 8> Privates; 11487 /// LHS expressions for the reduction_op expressions. 11488 SmallVector<Expr *, 8> LHSs; 11489 /// RHS expressions for the reduction_op expressions. 11490 SmallVector<Expr *, 8> RHSs; 11491 /// Reduction operation expression. 11492 SmallVector<Expr *, 8> ReductionOps; 11493 /// Taskgroup descriptors for the corresponding reduction items in 11494 /// in_reduction clauses. 11495 SmallVector<Expr *, 8> TaskgroupDescriptors; 11496 /// List of captures for clause. 11497 SmallVector<Decl *, 4> ExprCaptures; 11498 /// List of postupdate expressions. 11499 SmallVector<Expr *, 4> ExprPostUpdates; 11500 ReductionData() = delete; 11501 /// Reserves required memory for the reduction data. 11502 ReductionData(unsigned Size) { 11503 Vars.reserve(Size); 11504 Privates.reserve(Size); 11505 LHSs.reserve(Size); 11506 RHSs.reserve(Size); 11507 ReductionOps.reserve(Size); 11508 TaskgroupDescriptors.reserve(Size); 11509 ExprCaptures.reserve(Size); 11510 ExprPostUpdates.reserve(Size); 11511 } 11512 /// Stores reduction item and reduction operation only (required for dependent 11513 /// reduction item). 11514 void push(Expr *Item, Expr *ReductionOp) { 11515 Vars.emplace_back(Item); 11516 Privates.emplace_back(nullptr); 11517 LHSs.emplace_back(nullptr); 11518 RHSs.emplace_back(nullptr); 11519 ReductionOps.emplace_back(ReductionOp); 11520 TaskgroupDescriptors.emplace_back(nullptr); 11521 } 11522 /// Stores reduction data. 11523 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11524 Expr *TaskgroupDescriptor) { 11525 Vars.emplace_back(Item); 11526 Privates.emplace_back(Private); 11527 LHSs.emplace_back(LHS); 11528 RHSs.emplace_back(RHS); 11529 ReductionOps.emplace_back(ReductionOp); 11530 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11531 } 11532 }; 11533 } // namespace 11534 11535 static bool checkOMPArraySectionConstantForReduction( 11536 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11537 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11538 const Expr *Length = OASE->getLength(); 11539 if (Length == nullptr) { 11540 // For array sections of the form [1:] or [:], we would need to analyze 11541 // the lower bound... 11542 if (OASE->getColonLoc().isValid()) 11543 return false; 11544 11545 // This is an array subscript which has implicit length 1! 11546 SingleElement = true; 11547 ArraySizes.push_back(llvm::APSInt::get(1)); 11548 } else { 11549 Expr::EvalResult Result; 11550 if (!Length->EvaluateAsInt(Result, Context)) 11551 return false; 11552 11553 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11554 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11555 ArraySizes.push_back(ConstantLengthValue); 11556 } 11557 11558 // Get the base of this array section and walk up from there. 11559 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11560 11561 // We require length = 1 for all array sections except the right-most to 11562 // guarantee that the memory region is contiguous and has no holes in it. 11563 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11564 Length = TempOASE->getLength(); 11565 if (Length == nullptr) { 11566 // For array sections of the form [1:] or [:], we would need to analyze 11567 // the lower bound... 11568 if (OASE->getColonLoc().isValid()) 11569 return false; 11570 11571 // This is an array subscript which has implicit length 1! 11572 ArraySizes.push_back(llvm::APSInt::get(1)); 11573 } else { 11574 Expr::EvalResult Result; 11575 if (!Length->EvaluateAsInt(Result, Context)) 11576 return false; 11577 11578 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11579 if (ConstantLengthValue.getSExtValue() != 1) 11580 return false; 11581 11582 ArraySizes.push_back(ConstantLengthValue); 11583 } 11584 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11585 } 11586 11587 // If we have a single element, we don't need to add the implicit lengths. 11588 if (!SingleElement) { 11589 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11590 // Has implicit length 1! 11591 ArraySizes.push_back(llvm::APSInt::get(1)); 11592 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11593 } 11594 } 11595 11596 // This array section can be privatized as a single value or as a constant 11597 // sized array. 11598 return true; 11599 } 11600 11601 static bool actOnOMPReductionKindClause( 11602 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11603 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11604 SourceLocation ColonLoc, SourceLocation EndLoc, 11605 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11606 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11607 DeclarationName DN = ReductionId.getName(); 11608 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11609 BinaryOperatorKind BOK = BO_Comma; 11610 11611 ASTContext &Context = S.Context; 11612 // OpenMP [2.14.3.6, reduction clause] 11613 // C 11614 // reduction-identifier is either an identifier or one of the following 11615 // operators: +, -, *, &, |, ^, && and || 11616 // C++ 11617 // reduction-identifier is either an id-expression or one of the following 11618 // operators: +, -, *, &, |, ^, && and || 11619 switch (OOK) { 11620 case OO_Plus: 11621 case OO_Minus: 11622 BOK = BO_Add; 11623 break; 11624 case OO_Star: 11625 BOK = BO_Mul; 11626 break; 11627 case OO_Amp: 11628 BOK = BO_And; 11629 break; 11630 case OO_Pipe: 11631 BOK = BO_Or; 11632 break; 11633 case OO_Caret: 11634 BOK = BO_Xor; 11635 break; 11636 case OO_AmpAmp: 11637 BOK = BO_LAnd; 11638 break; 11639 case OO_PipePipe: 11640 BOK = BO_LOr; 11641 break; 11642 case OO_New: 11643 case OO_Delete: 11644 case OO_Array_New: 11645 case OO_Array_Delete: 11646 case OO_Slash: 11647 case OO_Percent: 11648 case OO_Tilde: 11649 case OO_Exclaim: 11650 case OO_Equal: 11651 case OO_Less: 11652 case OO_Greater: 11653 case OO_LessEqual: 11654 case OO_GreaterEqual: 11655 case OO_PlusEqual: 11656 case OO_MinusEqual: 11657 case OO_StarEqual: 11658 case OO_SlashEqual: 11659 case OO_PercentEqual: 11660 case OO_CaretEqual: 11661 case OO_AmpEqual: 11662 case OO_PipeEqual: 11663 case OO_LessLess: 11664 case OO_GreaterGreater: 11665 case OO_LessLessEqual: 11666 case OO_GreaterGreaterEqual: 11667 case OO_EqualEqual: 11668 case OO_ExclaimEqual: 11669 case OO_Spaceship: 11670 case OO_PlusPlus: 11671 case OO_MinusMinus: 11672 case OO_Comma: 11673 case OO_ArrowStar: 11674 case OO_Arrow: 11675 case OO_Call: 11676 case OO_Subscript: 11677 case OO_Conditional: 11678 case OO_Coawait: 11679 case NUM_OVERLOADED_OPERATORS: 11680 llvm_unreachable("Unexpected reduction identifier"); 11681 case OO_None: 11682 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11683 if (II->isStr("max")) 11684 BOK = BO_GT; 11685 else if (II->isStr("min")) 11686 BOK = BO_LT; 11687 } 11688 break; 11689 } 11690 SourceRange ReductionIdRange; 11691 if (ReductionIdScopeSpec.isValid()) 11692 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11693 else 11694 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11695 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11696 11697 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11698 bool FirstIter = true; 11699 for (Expr *RefExpr : VarList) { 11700 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11701 // OpenMP [2.1, C/C++] 11702 // A list item is a variable or array section, subject to the restrictions 11703 // specified in Section 2.4 on page 42 and in each of the sections 11704 // describing clauses and directives for which a list appears. 11705 // OpenMP [2.14.3.3, Restrictions, p.1] 11706 // A variable that is part of another variable (as an array or 11707 // structure element) cannot appear in a private clause. 11708 if (!FirstIter && IR != ER) 11709 ++IR; 11710 FirstIter = false; 11711 SourceLocation ELoc; 11712 SourceRange ERange; 11713 Expr *SimpleRefExpr = RefExpr; 11714 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11715 /*AllowArraySection=*/true); 11716 if (Res.second) { 11717 // Try to find 'declare reduction' corresponding construct before using 11718 // builtin/overloaded operators. 11719 QualType Type = Context.DependentTy; 11720 CXXCastPath BasePath; 11721 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11722 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11723 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11724 Expr *ReductionOp = nullptr; 11725 if (S.CurContext->isDependentContext() && 11726 (DeclareReductionRef.isUnset() || 11727 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11728 ReductionOp = DeclareReductionRef.get(); 11729 // It will be analyzed later. 11730 RD.push(RefExpr, ReductionOp); 11731 } 11732 ValueDecl *D = Res.first; 11733 if (!D) 11734 continue; 11735 11736 Expr *TaskgroupDescriptor = nullptr; 11737 QualType Type; 11738 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11739 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11740 if (ASE) { 11741 Type = ASE->getType().getNonReferenceType(); 11742 } else if (OASE) { 11743 QualType BaseType = 11744 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11745 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11746 Type = ATy->getElementType(); 11747 else 11748 Type = BaseType->getPointeeType(); 11749 Type = Type.getNonReferenceType(); 11750 } else { 11751 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11752 } 11753 auto *VD = dyn_cast<VarDecl>(D); 11754 11755 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11756 // A variable that appears in a private clause must not have an incomplete 11757 // type or a reference type. 11758 if (S.RequireCompleteType(ELoc, D->getType(), 11759 diag::err_omp_reduction_incomplete_type)) 11760 continue; 11761 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11762 // A list item that appears in a reduction clause must not be 11763 // const-qualified. 11764 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11765 /*AcceptIfMutable*/ false, ASE || OASE)) 11766 continue; 11767 11768 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11769 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11770 // If a list-item is a reference type then it must bind to the same object 11771 // for all threads of the team. 11772 if (!ASE && !OASE) { 11773 if (VD) { 11774 VarDecl *VDDef = VD->getDefinition(); 11775 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11776 DSARefChecker Check(Stack); 11777 if (Check.Visit(VDDef->getInit())) { 11778 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11779 << getOpenMPClauseName(ClauseKind) << ERange; 11780 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11781 continue; 11782 } 11783 } 11784 } 11785 11786 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11787 // in a Construct] 11788 // Variables with the predetermined data-sharing attributes may not be 11789 // listed in data-sharing attributes clauses, except for the cases 11790 // listed below. For these exceptions only, listing a predetermined 11791 // variable in a data-sharing attribute clause is allowed and overrides 11792 // the variable's predetermined data-sharing attributes. 11793 // OpenMP [2.14.3.6, Restrictions, p.3] 11794 // Any number of reduction clauses can be specified on the directive, 11795 // but a list item can appear only once in the reduction clauses for that 11796 // directive. 11797 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11798 if (DVar.CKind == OMPC_reduction) { 11799 S.Diag(ELoc, diag::err_omp_once_referenced) 11800 << getOpenMPClauseName(ClauseKind); 11801 if (DVar.RefExpr) 11802 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 11803 continue; 11804 } 11805 if (DVar.CKind != OMPC_unknown) { 11806 S.Diag(ELoc, diag::err_omp_wrong_dsa) 11807 << getOpenMPClauseName(DVar.CKind) 11808 << getOpenMPClauseName(OMPC_reduction); 11809 reportOriginalDsa(S, Stack, D, DVar); 11810 continue; 11811 } 11812 11813 // OpenMP [2.14.3.6, Restrictions, p.1] 11814 // A list item that appears in a reduction clause of a worksharing 11815 // construct must be shared in the parallel regions to which any of the 11816 // worksharing regions arising from the worksharing construct bind. 11817 if (isOpenMPWorksharingDirective(CurrDir) && 11818 !isOpenMPParallelDirective(CurrDir) && 11819 !isOpenMPTeamsDirective(CurrDir)) { 11820 DVar = Stack->getImplicitDSA(D, true); 11821 if (DVar.CKind != OMPC_shared) { 11822 S.Diag(ELoc, diag::err_omp_required_access) 11823 << getOpenMPClauseName(OMPC_reduction) 11824 << getOpenMPClauseName(OMPC_shared); 11825 reportOriginalDsa(S, Stack, D, DVar); 11826 continue; 11827 } 11828 } 11829 } 11830 11831 // Try to find 'declare reduction' corresponding construct before using 11832 // builtin/overloaded operators. 11833 CXXCastPath BasePath; 11834 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11835 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11836 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11837 if (DeclareReductionRef.isInvalid()) 11838 continue; 11839 if (S.CurContext->isDependentContext() && 11840 (DeclareReductionRef.isUnset() || 11841 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 11842 RD.push(RefExpr, DeclareReductionRef.get()); 11843 continue; 11844 } 11845 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 11846 // Not allowed reduction identifier is found. 11847 S.Diag(ReductionId.getBeginLoc(), 11848 diag::err_omp_unknown_reduction_identifier) 11849 << Type << ReductionIdRange; 11850 continue; 11851 } 11852 11853 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11854 // The type of a list item that appears in a reduction clause must be valid 11855 // for the reduction-identifier. For a max or min reduction in C, the type 11856 // of the list item must be an allowed arithmetic data type: char, int, 11857 // float, double, or _Bool, possibly modified with long, short, signed, or 11858 // unsigned. For a max or min reduction in C++, the type of the list item 11859 // must be an allowed arithmetic data type: char, wchar_t, int, float, 11860 // double, or bool, possibly modified with long, short, signed, or unsigned. 11861 if (DeclareReductionRef.isUnset()) { 11862 if ((BOK == BO_GT || BOK == BO_LT) && 11863 !(Type->isScalarType() || 11864 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 11865 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 11866 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 11867 if (!ASE && !OASE) { 11868 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11869 VarDecl::DeclarationOnly; 11870 S.Diag(D->getLocation(), 11871 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11872 << D; 11873 } 11874 continue; 11875 } 11876 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 11877 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 11878 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 11879 << getOpenMPClauseName(ClauseKind); 11880 if (!ASE && !OASE) { 11881 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11882 VarDecl::DeclarationOnly; 11883 S.Diag(D->getLocation(), 11884 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11885 << D; 11886 } 11887 continue; 11888 } 11889 } 11890 11891 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 11892 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 11893 D->hasAttrs() ? &D->getAttrs() : nullptr); 11894 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 11895 D->hasAttrs() ? &D->getAttrs() : nullptr); 11896 QualType PrivateTy = Type; 11897 11898 // Try if we can determine constant lengths for all array sections and avoid 11899 // the VLA. 11900 bool ConstantLengthOASE = false; 11901 if (OASE) { 11902 bool SingleElement; 11903 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 11904 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 11905 Context, OASE, SingleElement, ArraySizes); 11906 11907 // If we don't have a single element, we must emit a constant array type. 11908 if (ConstantLengthOASE && !SingleElement) { 11909 for (llvm::APSInt &Size : ArraySizes) 11910 PrivateTy = Context.getConstantArrayType( 11911 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 11912 } 11913 } 11914 11915 if ((OASE && !ConstantLengthOASE) || 11916 (!OASE && !ASE && 11917 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 11918 if (!Context.getTargetInfo().isVLASupported() && 11919 S.shouldDiagnoseTargetSupportFromOpenMP()) { 11920 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 11921 S.Diag(ELoc, diag::note_vla_unsupported); 11922 continue; 11923 } 11924 // For arrays/array sections only: 11925 // Create pseudo array type for private copy. The size for this array will 11926 // be generated during codegen. 11927 // For array subscripts or single variables Private Ty is the same as Type 11928 // (type of the variable or single array element). 11929 PrivateTy = Context.getVariableArrayType( 11930 Type, 11931 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 11932 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 11933 } else if (!ASE && !OASE && 11934 Context.getAsArrayType(D->getType().getNonReferenceType())) { 11935 PrivateTy = D->getType().getNonReferenceType(); 11936 } 11937 // Private copy. 11938 VarDecl *PrivateVD = 11939 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 11940 D->hasAttrs() ? &D->getAttrs() : nullptr, 11941 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11942 // Add initializer for private variable. 11943 Expr *Init = nullptr; 11944 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 11945 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 11946 if (DeclareReductionRef.isUsable()) { 11947 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 11948 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 11949 if (DRD->getInitializer()) { 11950 Init = DRDRef; 11951 RHSVD->setInit(DRDRef); 11952 RHSVD->setInitStyle(VarDecl::CallInit); 11953 } 11954 } else { 11955 switch (BOK) { 11956 case BO_Add: 11957 case BO_Xor: 11958 case BO_Or: 11959 case BO_LOr: 11960 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 11961 if (Type->isScalarType() || Type->isAnyComplexType()) 11962 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 11963 break; 11964 case BO_Mul: 11965 case BO_LAnd: 11966 if (Type->isScalarType() || Type->isAnyComplexType()) { 11967 // '*' and '&&' reduction ops - initializer is '1'. 11968 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 11969 } 11970 break; 11971 case BO_And: { 11972 // '&' reduction op - initializer is '~0'. 11973 QualType OrigType = Type; 11974 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 11975 Type = ComplexTy->getElementType(); 11976 if (Type->isRealFloatingType()) { 11977 llvm::APFloat InitValue = 11978 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 11979 /*isIEEE=*/true); 11980 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11981 Type, ELoc); 11982 } else if (Type->isScalarType()) { 11983 uint64_t Size = Context.getTypeSize(Type); 11984 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 11985 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 11986 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11987 } 11988 if (Init && OrigType->isAnyComplexType()) { 11989 // Init = 0xFFFF + 0xFFFFi; 11990 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 11991 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 11992 } 11993 Type = OrigType; 11994 break; 11995 } 11996 case BO_LT: 11997 case BO_GT: { 11998 // 'min' reduction op - initializer is 'Largest representable number in 11999 // the reduction list item type'. 12000 // 'max' reduction op - initializer is 'Least representable number in 12001 // the reduction list item type'. 12002 if (Type->isIntegerType() || Type->isPointerType()) { 12003 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12004 uint64_t Size = Context.getTypeSize(Type); 12005 QualType IntTy = 12006 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12007 llvm::APInt InitValue = 12008 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12009 : llvm::APInt::getMinValue(Size) 12010 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12011 : llvm::APInt::getMaxValue(Size); 12012 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12013 if (Type->isPointerType()) { 12014 // Cast to pointer type. 12015 ExprResult CastExpr = S.BuildCStyleCastExpr( 12016 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12017 if (CastExpr.isInvalid()) 12018 continue; 12019 Init = CastExpr.get(); 12020 } 12021 } else if (Type->isRealFloatingType()) { 12022 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12023 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12024 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12025 Type, ELoc); 12026 } 12027 break; 12028 } 12029 case BO_PtrMemD: 12030 case BO_PtrMemI: 12031 case BO_MulAssign: 12032 case BO_Div: 12033 case BO_Rem: 12034 case BO_Sub: 12035 case BO_Shl: 12036 case BO_Shr: 12037 case BO_LE: 12038 case BO_GE: 12039 case BO_EQ: 12040 case BO_NE: 12041 case BO_Cmp: 12042 case BO_AndAssign: 12043 case BO_XorAssign: 12044 case BO_OrAssign: 12045 case BO_Assign: 12046 case BO_AddAssign: 12047 case BO_SubAssign: 12048 case BO_DivAssign: 12049 case BO_RemAssign: 12050 case BO_ShlAssign: 12051 case BO_ShrAssign: 12052 case BO_Comma: 12053 llvm_unreachable("Unexpected reduction operation"); 12054 } 12055 } 12056 if (Init && DeclareReductionRef.isUnset()) 12057 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12058 else if (!Init) 12059 S.ActOnUninitializedDecl(RHSVD); 12060 if (RHSVD->isInvalidDecl()) 12061 continue; 12062 if (!RHSVD->hasInit() && 12063 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12064 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12065 << Type << ReductionIdRange; 12066 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12067 VarDecl::DeclarationOnly; 12068 S.Diag(D->getLocation(), 12069 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12070 << D; 12071 continue; 12072 } 12073 // Store initializer for single element in private copy. Will be used during 12074 // codegen. 12075 PrivateVD->setInit(RHSVD->getInit()); 12076 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12077 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12078 ExprResult ReductionOp; 12079 if (DeclareReductionRef.isUsable()) { 12080 QualType RedTy = DeclareReductionRef.get()->getType(); 12081 QualType PtrRedTy = Context.getPointerType(RedTy); 12082 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12083 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12084 if (!BasePath.empty()) { 12085 LHS = S.DefaultLvalueConversion(LHS.get()); 12086 RHS = S.DefaultLvalueConversion(RHS.get()); 12087 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12088 CK_UncheckedDerivedToBase, LHS.get(), 12089 &BasePath, LHS.get()->getValueKind()); 12090 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12091 CK_UncheckedDerivedToBase, RHS.get(), 12092 &BasePath, RHS.get()->getValueKind()); 12093 } 12094 FunctionProtoType::ExtProtoInfo EPI; 12095 QualType Params[] = {PtrRedTy, PtrRedTy}; 12096 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12097 auto *OVE = new (Context) OpaqueValueExpr( 12098 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12099 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12100 Expr *Args[] = {LHS.get(), RHS.get()}; 12101 ReductionOp = 12102 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12103 } else { 12104 ReductionOp = S.BuildBinOp( 12105 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12106 if (ReductionOp.isUsable()) { 12107 if (BOK != BO_LT && BOK != BO_GT) { 12108 ReductionOp = 12109 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12110 BO_Assign, LHSDRE, ReductionOp.get()); 12111 } else { 12112 auto *ConditionalOp = new (Context) 12113 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12114 Type, VK_LValue, OK_Ordinary); 12115 ReductionOp = 12116 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12117 BO_Assign, LHSDRE, ConditionalOp); 12118 } 12119 if (ReductionOp.isUsable()) 12120 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12121 /*DiscardedValue*/ false); 12122 } 12123 if (!ReductionOp.isUsable()) 12124 continue; 12125 } 12126 12127 // OpenMP [2.15.4.6, Restrictions, p.2] 12128 // A list item that appears in an in_reduction clause of a task construct 12129 // must appear in a task_reduction clause of a construct associated with a 12130 // taskgroup region that includes the participating task in its taskgroup 12131 // set. The construct associated with the innermost region that meets this 12132 // condition must specify the same reduction-identifier as the in_reduction 12133 // clause. 12134 if (ClauseKind == OMPC_in_reduction) { 12135 SourceRange ParentSR; 12136 BinaryOperatorKind ParentBOK; 12137 const Expr *ParentReductionOp; 12138 Expr *ParentBOKTD, *ParentReductionOpTD; 12139 DSAStackTy::DSAVarData ParentBOKDSA = 12140 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12141 ParentBOKTD); 12142 DSAStackTy::DSAVarData ParentReductionOpDSA = 12143 Stack->getTopMostTaskgroupReductionData( 12144 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12145 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12146 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12147 if (!IsParentBOK && !IsParentReductionOp) { 12148 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12149 continue; 12150 } 12151 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12152 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12153 IsParentReductionOp) { 12154 bool EmitError = true; 12155 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12156 llvm::FoldingSetNodeID RedId, ParentRedId; 12157 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12158 DeclareReductionRef.get()->Profile(RedId, Context, 12159 /*Canonical=*/true); 12160 EmitError = RedId != ParentRedId; 12161 } 12162 if (EmitError) { 12163 S.Diag(ReductionId.getBeginLoc(), 12164 diag::err_omp_reduction_identifier_mismatch) 12165 << ReductionIdRange << RefExpr->getSourceRange(); 12166 S.Diag(ParentSR.getBegin(), 12167 diag::note_omp_previous_reduction_identifier) 12168 << ParentSR 12169 << (IsParentBOK ? ParentBOKDSA.RefExpr 12170 : ParentReductionOpDSA.RefExpr) 12171 ->getSourceRange(); 12172 continue; 12173 } 12174 } 12175 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12176 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12177 } 12178 12179 DeclRefExpr *Ref = nullptr; 12180 Expr *VarsExpr = RefExpr->IgnoreParens(); 12181 if (!VD && !S.CurContext->isDependentContext()) { 12182 if (ASE || OASE) { 12183 TransformExprToCaptures RebuildToCapture(S, D); 12184 VarsExpr = 12185 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12186 Ref = RebuildToCapture.getCapturedExpr(); 12187 } else { 12188 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12189 } 12190 if (!S.isOpenMPCapturedDecl(D)) { 12191 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12192 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12193 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12194 if (!RefRes.isUsable()) 12195 continue; 12196 ExprResult PostUpdateRes = 12197 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12198 RefRes.get()); 12199 if (!PostUpdateRes.isUsable()) 12200 continue; 12201 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12202 Stack->getCurrentDirective() == OMPD_taskgroup) { 12203 S.Diag(RefExpr->getExprLoc(), 12204 diag::err_omp_reduction_non_addressable_expression) 12205 << RefExpr->getSourceRange(); 12206 continue; 12207 } 12208 RD.ExprPostUpdates.emplace_back( 12209 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12210 } 12211 } 12212 } 12213 // All reduction items are still marked as reduction (to do not increase 12214 // code base size). 12215 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12216 if (CurrDir == OMPD_taskgroup) { 12217 if (DeclareReductionRef.isUsable()) 12218 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12219 DeclareReductionRef.get()); 12220 else 12221 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12222 } 12223 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12224 TaskgroupDescriptor); 12225 } 12226 return RD.Vars.empty(); 12227 } 12228 12229 OMPClause *Sema::ActOnOpenMPReductionClause( 12230 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12231 SourceLocation ColonLoc, SourceLocation EndLoc, 12232 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12233 ArrayRef<Expr *> UnresolvedReductions) { 12234 ReductionData RD(VarList.size()); 12235 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12236 StartLoc, LParenLoc, ColonLoc, EndLoc, 12237 ReductionIdScopeSpec, ReductionId, 12238 UnresolvedReductions, RD)) 12239 return nullptr; 12240 12241 return OMPReductionClause::Create( 12242 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12243 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12244 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12245 buildPreInits(Context, RD.ExprCaptures), 12246 buildPostUpdate(*this, RD.ExprPostUpdates)); 12247 } 12248 12249 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12250 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12251 SourceLocation ColonLoc, SourceLocation EndLoc, 12252 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12253 ArrayRef<Expr *> UnresolvedReductions) { 12254 ReductionData RD(VarList.size()); 12255 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12256 StartLoc, LParenLoc, ColonLoc, EndLoc, 12257 ReductionIdScopeSpec, ReductionId, 12258 UnresolvedReductions, RD)) 12259 return nullptr; 12260 12261 return OMPTaskReductionClause::Create( 12262 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12263 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12264 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12265 buildPreInits(Context, RD.ExprCaptures), 12266 buildPostUpdate(*this, RD.ExprPostUpdates)); 12267 } 12268 12269 OMPClause *Sema::ActOnOpenMPInReductionClause( 12270 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12271 SourceLocation ColonLoc, SourceLocation EndLoc, 12272 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12273 ArrayRef<Expr *> UnresolvedReductions) { 12274 ReductionData RD(VarList.size()); 12275 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12276 StartLoc, LParenLoc, ColonLoc, EndLoc, 12277 ReductionIdScopeSpec, ReductionId, 12278 UnresolvedReductions, RD)) 12279 return nullptr; 12280 12281 return OMPInReductionClause::Create( 12282 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12283 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12284 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12285 buildPreInits(Context, RD.ExprCaptures), 12286 buildPostUpdate(*this, RD.ExprPostUpdates)); 12287 } 12288 12289 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12290 SourceLocation LinLoc) { 12291 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12292 LinKind == OMPC_LINEAR_unknown) { 12293 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12294 return true; 12295 } 12296 return false; 12297 } 12298 12299 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12300 OpenMPLinearClauseKind LinKind, 12301 QualType Type) { 12302 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12303 // A variable must not have an incomplete type or a reference type. 12304 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12305 return true; 12306 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12307 !Type->isReferenceType()) { 12308 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12309 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12310 return true; 12311 } 12312 Type = Type.getNonReferenceType(); 12313 12314 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12315 // A variable that is privatized must not have a const-qualified type 12316 // unless it is of class type with a mutable member. This restriction does 12317 // not apply to the firstprivate clause. 12318 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12319 return true; 12320 12321 // A list item must be of integral or pointer type. 12322 Type = Type.getUnqualifiedType().getCanonicalType(); 12323 const auto *Ty = Type.getTypePtrOrNull(); 12324 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12325 !Ty->isPointerType())) { 12326 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12327 if (D) { 12328 bool IsDecl = 12329 !VD || 12330 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12331 Diag(D->getLocation(), 12332 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12333 << D; 12334 } 12335 return true; 12336 } 12337 return false; 12338 } 12339 12340 OMPClause *Sema::ActOnOpenMPLinearClause( 12341 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12342 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12343 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12344 SmallVector<Expr *, 8> Vars; 12345 SmallVector<Expr *, 8> Privates; 12346 SmallVector<Expr *, 8> Inits; 12347 SmallVector<Decl *, 4> ExprCaptures; 12348 SmallVector<Expr *, 4> ExprPostUpdates; 12349 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12350 LinKind = OMPC_LINEAR_val; 12351 for (Expr *RefExpr : VarList) { 12352 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12353 SourceLocation ELoc; 12354 SourceRange ERange; 12355 Expr *SimpleRefExpr = RefExpr; 12356 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12357 if (Res.second) { 12358 // It will be analyzed later. 12359 Vars.push_back(RefExpr); 12360 Privates.push_back(nullptr); 12361 Inits.push_back(nullptr); 12362 } 12363 ValueDecl *D = Res.first; 12364 if (!D) 12365 continue; 12366 12367 QualType Type = D->getType(); 12368 auto *VD = dyn_cast<VarDecl>(D); 12369 12370 // OpenMP [2.14.3.7, linear clause] 12371 // A list-item cannot appear in more than one linear clause. 12372 // A list-item that appears in a linear clause cannot appear in any 12373 // other data-sharing attribute clause. 12374 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12375 if (DVar.RefExpr) { 12376 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12377 << getOpenMPClauseName(OMPC_linear); 12378 reportOriginalDsa(*this, DSAStack, D, DVar); 12379 continue; 12380 } 12381 12382 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12383 continue; 12384 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12385 12386 // Build private copy of original var. 12387 VarDecl *Private = 12388 buildVarDecl(*this, ELoc, Type, D->getName(), 12389 D->hasAttrs() ? &D->getAttrs() : nullptr, 12390 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12391 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12392 // Build var to save initial value. 12393 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12394 Expr *InitExpr; 12395 DeclRefExpr *Ref = nullptr; 12396 if (!VD && !CurContext->isDependentContext()) { 12397 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12398 if (!isOpenMPCapturedDecl(D)) { 12399 ExprCaptures.push_back(Ref->getDecl()); 12400 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12401 ExprResult RefRes = DefaultLvalueConversion(Ref); 12402 if (!RefRes.isUsable()) 12403 continue; 12404 ExprResult PostUpdateRes = 12405 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12406 SimpleRefExpr, RefRes.get()); 12407 if (!PostUpdateRes.isUsable()) 12408 continue; 12409 ExprPostUpdates.push_back( 12410 IgnoredValueConversions(PostUpdateRes.get()).get()); 12411 } 12412 } 12413 } 12414 if (LinKind == OMPC_LINEAR_uval) 12415 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12416 else 12417 InitExpr = VD ? SimpleRefExpr : Ref; 12418 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12419 /*DirectInit=*/false); 12420 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12421 12422 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12423 Vars.push_back((VD || CurContext->isDependentContext()) 12424 ? RefExpr->IgnoreParens() 12425 : Ref); 12426 Privates.push_back(PrivateRef); 12427 Inits.push_back(InitRef); 12428 } 12429 12430 if (Vars.empty()) 12431 return nullptr; 12432 12433 Expr *StepExpr = Step; 12434 Expr *CalcStepExpr = nullptr; 12435 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12436 !Step->isInstantiationDependent() && 12437 !Step->containsUnexpandedParameterPack()) { 12438 SourceLocation StepLoc = Step->getBeginLoc(); 12439 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12440 if (Val.isInvalid()) 12441 return nullptr; 12442 StepExpr = Val.get(); 12443 12444 // Build var to save the step value. 12445 VarDecl *SaveVar = 12446 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12447 ExprResult SaveRef = 12448 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12449 ExprResult CalcStep = 12450 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12451 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12452 12453 // Warn about zero linear step (it would be probably better specified as 12454 // making corresponding variables 'const'). 12455 llvm::APSInt Result; 12456 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12457 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12458 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12459 << (Vars.size() > 1); 12460 if (!IsConstant && CalcStep.isUsable()) { 12461 // Calculate the step beforehand instead of doing this on each iteration. 12462 // (This is not used if the number of iterations may be kfold-ed). 12463 CalcStepExpr = CalcStep.get(); 12464 } 12465 } 12466 12467 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12468 ColonLoc, EndLoc, Vars, Privates, Inits, 12469 StepExpr, CalcStepExpr, 12470 buildPreInits(Context, ExprCaptures), 12471 buildPostUpdate(*this, ExprPostUpdates)); 12472 } 12473 12474 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12475 Expr *NumIterations, Sema &SemaRef, 12476 Scope *S, DSAStackTy *Stack) { 12477 // Walk the vars and build update/final expressions for the CodeGen. 12478 SmallVector<Expr *, 8> Updates; 12479 SmallVector<Expr *, 8> Finals; 12480 Expr *Step = Clause.getStep(); 12481 Expr *CalcStep = Clause.getCalcStep(); 12482 // OpenMP [2.14.3.7, linear clause] 12483 // If linear-step is not specified it is assumed to be 1. 12484 if (!Step) 12485 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12486 else if (CalcStep) 12487 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12488 bool HasErrors = false; 12489 auto CurInit = Clause.inits().begin(); 12490 auto CurPrivate = Clause.privates().begin(); 12491 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12492 for (Expr *RefExpr : Clause.varlists()) { 12493 SourceLocation ELoc; 12494 SourceRange ERange; 12495 Expr *SimpleRefExpr = RefExpr; 12496 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12497 ValueDecl *D = Res.first; 12498 if (Res.second || !D) { 12499 Updates.push_back(nullptr); 12500 Finals.push_back(nullptr); 12501 HasErrors = true; 12502 continue; 12503 } 12504 auto &&Info = Stack->isLoopControlVariable(D); 12505 // OpenMP [2.15.11, distribute simd Construct] 12506 // A list item may not appear in a linear clause, unless it is the loop 12507 // iteration variable. 12508 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12509 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12510 SemaRef.Diag(ELoc, 12511 diag::err_omp_linear_distribute_var_non_loop_iteration); 12512 Updates.push_back(nullptr); 12513 Finals.push_back(nullptr); 12514 HasErrors = true; 12515 continue; 12516 } 12517 Expr *InitExpr = *CurInit; 12518 12519 // Build privatized reference to the current linear var. 12520 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12521 Expr *CapturedRef; 12522 if (LinKind == OMPC_LINEAR_uval) 12523 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12524 else 12525 CapturedRef = 12526 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12527 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12528 /*RefersToCapture=*/true); 12529 12530 // Build update: Var = InitExpr + IV * Step 12531 ExprResult Update; 12532 if (!Info.first) 12533 Update = 12534 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12535 InitExpr, IV, Step, /* Subtract */ false); 12536 else 12537 Update = *CurPrivate; 12538 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12539 /*DiscardedValue*/ false); 12540 12541 // Build final: Var = InitExpr + NumIterations * Step 12542 ExprResult Final; 12543 if (!Info.first) 12544 Final = 12545 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12546 InitExpr, NumIterations, Step, /*Subtract=*/false); 12547 else 12548 Final = *CurPrivate; 12549 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12550 /*DiscardedValue*/ false); 12551 12552 if (!Update.isUsable() || !Final.isUsable()) { 12553 Updates.push_back(nullptr); 12554 Finals.push_back(nullptr); 12555 HasErrors = true; 12556 } else { 12557 Updates.push_back(Update.get()); 12558 Finals.push_back(Final.get()); 12559 } 12560 ++CurInit; 12561 ++CurPrivate; 12562 } 12563 Clause.setUpdates(Updates); 12564 Clause.setFinals(Finals); 12565 return HasErrors; 12566 } 12567 12568 OMPClause *Sema::ActOnOpenMPAlignedClause( 12569 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12570 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12571 SmallVector<Expr *, 8> Vars; 12572 for (Expr *RefExpr : VarList) { 12573 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12574 SourceLocation ELoc; 12575 SourceRange ERange; 12576 Expr *SimpleRefExpr = RefExpr; 12577 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12578 if (Res.second) { 12579 // It will be analyzed later. 12580 Vars.push_back(RefExpr); 12581 } 12582 ValueDecl *D = Res.first; 12583 if (!D) 12584 continue; 12585 12586 QualType QType = D->getType(); 12587 auto *VD = dyn_cast<VarDecl>(D); 12588 12589 // OpenMP [2.8.1, simd construct, Restrictions] 12590 // The type of list items appearing in the aligned clause must be 12591 // array, pointer, reference to array, or reference to pointer. 12592 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12593 const Type *Ty = QType.getTypePtrOrNull(); 12594 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12595 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12596 << QType << getLangOpts().CPlusPlus << ERange; 12597 bool IsDecl = 12598 !VD || 12599 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12600 Diag(D->getLocation(), 12601 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12602 << D; 12603 continue; 12604 } 12605 12606 // OpenMP [2.8.1, simd construct, Restrictions] 12607 // A list-item cannot appear in more than one aligned clause. 12608 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12609 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12610 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12611 << getOpenMPClauseName(OMPC_aligned); 12612 continue; 12613 } 12614 12615 DeclRefExpr *Ref = nullptr; 12616 if (!VD && isOpenMPCapturedDecl(D)) 12617 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12618 Vars.push_back(DefaultFunctionArrayConversion( 12619 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12620 .get()); 12621 } 12622 12623 // OpenMP [2.8.1, simd construct, Description] 12624 // The parameter of the aligned clause, alignment, must be a constant 12625 // positive integer expression. 12626 // If no optional parameter is specified, implementation-defined default 12627 // alignments for SIMD instructions on the target platforms are assumed. 12628 if (Alignment != nullptr) { 12629 ExprResult AlignResult = 12630 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12631 if (AlignResult.isInvalid()) 12632 return nullptr; 12633 Alignment = AlignResult.get(); 12634 } 12635 if (Vars.empty()) 12636 return nullptr; 12637 12638 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12639 EndLoc, Vars, Alignment); 12640 } 12641 12642 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12643 SourceLocation StartLoc, 12644 SourceLocation LParenLoc, 12645 SourceLocation EndLoc) { 12646 SmallVector<Expr *, 8> Vars; 12647 SmallVector<Expr *, 8> SrcExprs; 12648 SmallVector<Expr *, 8> DstExprs; 12649 SmallVector<Expr *, 8> AssignmentOps; 12650 for (Expr *RefExpr : VarList) { 12651 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12652 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12653 // It will be analyzed later. 12654 Vars.push_back(RefExpr); 12655 SrcExprs.push_back(nullptr); 12656 DstExprs.push_back(nullptr); 12657 AssignmentOps.push_back(nullptr); 12658 continue; 12659 } 12660 12661 SourceLocation ELoc = RefExpr->getExprLoc(); 12662 // OpenMP [2.1, C/C++] 12663 // A list item is a variable name. 12664 // OpenMP [2.14.4.1, Restrictions, p.1] 12665 // A list item that appears in a copyin clause must be threadprivate. 12666 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12667 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12668 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12669 << 0 << RefExpr->getSourceRange(); 12670 continue; 12671 } 12672 12673 Decl *D = DE->getDecl(); 12674 auto *VD = cast<VarDecl>(D); 12675 12676 QualType Type = VD->getType(); 12677 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12678 // It will be analyzed later. 12679 Vars.push_back(DE); 12680 SrcExprs.push_back(nullptr); 12681 DstExprs.push_back(nullptr); 12682 AssignmentOps.push_back(nullptr); 12683 continue; 12684 } 12685 12686 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12687 // A list item that appears in a copyin clause must be threadprivate. 12688 if (!DSAStack->isThreadPrivate(VD)) { 12689 Diag(ELoc, diag::err_omp_required_access) 12690 << getOpenMPClauseName(OMPC_copyin) 12691 << getOpenMPDirectiveName(OMPD_threadprivate); 12692 continue; 12693 } 12694 12695 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12696 // A variable of class type (or array thereof) that appears in a 12697 // copyin clause requires an accessible, unambiguous copy assignment 12698 // operator for the class type. 12699 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12700 VarDecl *SrcVD = 12701 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12702 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12703 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12704 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12705 VarDecl *DstVD = 12706 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12707 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12708 DeclRefExpr *PseudoDstExpr = 12709 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12710 // For arrays generate assignment operation for single element and replace 12711 // it by the original array element in CodeGen. 12712 ExprResult AssignmentOp = 12713 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12714 PseudoSrcExpr); 12715 if (AssignmentOp.isInvalid()) 12716 continue; 12717 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12718 /*DiscardedValue*/ false); 12719 if (AssignmentOp.isInvalid()) 12720 continue; 12721 12722 DSAStack->addDSA(VD, DE, OMPC_copyin); 12723 Vars.push_back(DE); 12724 SrcExprs.push_back(PseudoSrcExpr); 12725 DstExprs.push_back(PseudoDstExpr); 12726 AssignmentOps.push_back(AssignmentOp.get()); 12727 } 12728 12729 if (Vars.empty()) 12730 return nullptr; 12731 12732 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12733 SrcExprs, DstExprs, AssignmentOps); 12734 } 12735 12736 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12737 SourceLocation StartLoc, 12738 SourceLocation LParenLoc, 12739 SourceLocation EndLoc) { 12740 SmallVector<Expr *, 8> Vars; 12741 SmallVector<Expr *, 8> SrcExprs; 12742 SmallVector<Expr *, 8> DstExprs; 12743 SmallVector<Expr *, 8> AssignmentOps; 12744 for (Expr *RefExpr : VarList) { 12745 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12746 SourceLocation ELoc; 12747 SourceRange ERange; 12748 Expr *SimpleRefExpr = RefExpr; 12749 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12750 if (Res.second) { 12751 // It will be analyzed later. 12752 Vars.push_back(RefExpr); 12753 SrcExprs.push_back(nullptr); 12754 DstExprs.push_back(nullptr); 12755 AssignmentOps.push_back(nullptr); 12756 } 12757 ValueDecl *D = Res.first; 12758 if (!D) 12759 continue; 12760 12761 QualType Type = D->getType(); 12762 auto *VD = dyn_cast<VarDecl>(D); 12763 12764 // OpenMP [2.14.4.2, Restrictions, p.2] 12765 // A list item that appears in a copyprivate clause may not appear in a 12766 // private or firstprivate clause on the single construct. 12767 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12768 DSAStackTy::DSAVarData DVar = 12769 DSAStack->getTopDSA(D, /*FromParent=*/false); 12770 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12771 DVar.RefExpr) { 12772 Diag(ELoc, diag::err_omp_wrong_dsa) 12773 << getOpenMPClauseName(DVar.CKind) 12774 << getOpenMPClauseName(OMPC_copyprivate); 12775 reportOriginalDsa(*this, DSAStack, D, DVar); 12776 continue; 12777 } 12778 12779 // OpenMP [2.11.4.2, Restrictions, p.1] 12780 // All list items that appear in a copyprivate clause must be either 12781 // threadprivate or private in the enclosing context. 12782 if (DVar.CKind == OMPC_unknown) { 12783 DVar = DSAStack->getImplicitDSA(D, false); 12784 if (DVar.CKind == OMPC_shared) { 12785 Diag(ELoc, diag::err_omp_required_access) 12786 << getOpenMPClauseName(OMPC_copyprivate) 12787 << "threadprivate or private in the enclosing context"; 12788 reportOriginalDsa(*this, DSAStack, D, DVar); 12789 continue; 12790 } 12791 } 12792 } 12793 12794 // Variably modified types are not supported. 12795 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12796 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12797 << getOpenMPClauseName(OMPC_copyprivate) << Type 12798 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12799 bool IsDecl = 12800 !VD || 12801 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12802 Diag(D->getLocation(), 12803 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12804 << D; 12805 continue; 12806 } 12807 12808 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12809 // A variable of class type (or array thereof) that appears in a 12810 // copyin clause requires an accessible, unambiguous copy assignment 12811 // operator for the class type. 12812 Type = Context.getBaseElementType(Type.getNonReferenceType()) 12813 .getUnqualifiedType(); 12814 VarDecl *SrcVD = 12815 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 12816 D->hasAttrs() ? &D->getAttrs() : nullptr); 12817 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 12818 VarDecl *DstVD = 12819 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 12820 D->hasAttrs() ? &D->getAttrs() : nullptr); 12821 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12822 ExprResult AssignmentOp = BuildBinOp( 12823 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 12824 if (AssignmentOp.isInvalid()) 12825 continue; 12826 AssignmentOp = 12827 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12828 if (AssignmentOp.isInvalid()) 12829 continue; 12830 12831 // No need to mark vars as copyprivate, they are already threadprivate or 12832 // implicitly private. 12833 assert(VD || isOpenMPCapturedDecl(D)); 12834 Vars.push_back( 12835 VD ? RefExpr->IgnoreParens() 12836 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 12837 SrcExprs.push_back(PseudoSrcExpr); 12838 DstExprs.push_back(PseudoDstExpr); 12839 AssignmentOps.push_back(AssignmentOp.get()); 12840 } 12841 12842 if (Vars.empty()) 12843 return nullptr; 12844 12845 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12846 Vars, SrcExprs, DstExprs, AssignmentOps); 12847 } 12848 12849 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 12850 SourceLocation StartLoc, 12851 SourceLocation LParenLoc, 12852 SourceLocation EndLoc) { 12853 if (VarList.empty()) 12854 return nullptr; 12855 12856 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 12857 } 12858 12859 OMPClause * 12860 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 12861 SourceLocation DepLoc, SourceLocation ColonLoc, 12862 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12863 SourceLocation LParenLoc, SourceLocation EndLoc) { 12864 if (DSAStack->getCurrentDirective() == OMPD_ordered && 12865 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 12866 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12867 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 12868 return nullptr; 12869 } 12870 if (DSAStack->getCurrentDirective() != OMPD_ordered && 12871 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 12872 DepKind == OMPC_DEPEND_sink)) { 12873 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 12874 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12875 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12876 /*Last=*/OMPC_DEPEND_unknown, Except) 12877 << getOpenMPClauseName(OMPC_depend); 12878 return nullptr; 12879 } 12880 SmallVector<Expr *, 8> Vars; 12881 DSAStackTy::OperatorOffsetTy OpsOffs; 12882 llvm::APSInt DepCounter(/*BitWidth=*/32); 12883 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 12884 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 12885 if (const Expr *OrderedCountExpr = 12886 DSAStack->getParentOrderedRegionParam().first) { 12887 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 12888 TotalDepCount.setIsUnsigned(/*Val=*/true); 12889 } 12890 } 12891 for (Expr *RefExpr : VarList) { 12892 assert(RefExpr && "NULL expr in OpenMP shared clause."); 12893 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12894 // It will be analyzed later. 12895 Vars.push_back(RefExpr); 12896 continue; 12897 } 12898 12899 SourceLocation ELoc = RefExpr->getExprLoc(); 12900 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 12901 if (DepKind == OMPC_DEPEND_sink) { 12902 if (DSAStack->getParentOrderedRegionParam().first && 12903 DepCounter >= TotalDepCount) { 12904 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 12905 continue; 12906 } 12907 ++DepCounter; 12908 // OpenMP [2.13.9, Summary] 12909 // depend(dependence-type : vec), where dependence-type is: 12910 // 'sink' and where vec is the iteration vector, which has the form: 12911 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 12912 // where n is the value specified by the ordered clause in the loop 12913 // directive, xi denotes the loop iteration variable of the i-th nested 12914 // loop associated with the loop directive, and di is a constant 12915 // non-negative integer. 12916 if (CurContext->isDependentContext()) { 12917 // It will be analyzed later. 12918 Vars.push_back(RefExpr); 12919 continue; 12920 } 12921 SimpleExpr = SimpleExpr->IgnoreImplicit(); 12922 OverloadedOperatorKind OOK = OO_None; 12923 SourceLocation OOLoc; 12924 Expr *LHS = SimpleExpr; 12925 Expr *RHS = nullptr; 12926 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 12927 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 12928 OOLoc = BO->getOperatorLoc(); 12929 LHS = BO->getLHS()->IgnoreParenImpCasts(); 12930 RHS = BO->getRHS()->IgnoreParenImpCasts(); 12931 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 12932 OOK = OCE->getOperator(); 12933 OOLoc = OCE->getOperatorLoc(); 12934 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12935 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 12936 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 12937 OOK = MCE->getMethodDecl() 12938 ->getNameInfo() 12939 .getName() 12940 .getCXXOverloadedOperator(); 12941 OOLoc = MCE->getCallee()->getExprLoc(); 12942 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 12943 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12944 } 12945 SourceLocation ELoc; 12946 SourceRange ERange; 12947 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 12948 if (Res.second) { 12949 // It will be analyzed later. 12950 Vars.push_back(RefExpr); 12951 } 12952 ValueDecl *D = Res.first; 12953 if (!D) 12954 continue; 12955 12956 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 12957 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 12958 continue; 12959 } 12960 if (RHS) { 12961 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 12962 RHS, OMPC_depend, /*StrictlyPositive=*/false); 12963 if (RHSRes.isInvalid()) 12964 continue; 12965 } 12966 if (!CurContext->isDependentContext() && 12967 DSAStack->getParentOrderedRegionParam().first && 12968 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 12969 const ValueDecl *VD = 12970 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 12971 if (VD) 12972 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 12973 << 1 << VD; 12974 else 12975 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 12976 continue; 12977 } 12978 OpsOffs.emplace_back(RHS, OOK); 12979 } else { 12980 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 12981 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 12982 (ASE && 12983 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 12984 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 12985 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12986 << RefExpr->getSourceRange(); 12987 continue; 12988 } 12989 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 12990 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 12991 ExprResult Res = 12992 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 12993 getDiagnostics().setSuppressAllDiagnostics(Suppress); 12994 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 12995 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12996 << RefExpr->getSourceRange(); 12997 continue; 12998 } 12999 } 13000 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13001 } 13002 13003 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13004 TotalDepCount > VarList.size() && 13005 DSAStack->getParentOrderedRegionParam().first && 13006 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13007 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13008 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13009 } 13010 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13011 Vars.empty()) 13012 return nullptr; 13013 13014 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13015 DepKind, DepLoc, ColonLoc, Vars, 13016 TotalDepCount.getZExtValue()); 13017 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13018 DSAStack->isParentOrderedRegion()) 13019 DSAStack->addDoacrossDependClause(C, OpsOffs); 13020 return C; 13021 } 13022 13023 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13024 SourceLocation LParenLoc, 13025 SourceLocation EndLoc) { 13026 Expr *ValExpr = Device; 13027 Stmt *HelperValStmt = nullptr; 13028 13029 // OpenMP [2.9.1, Restrictions] 13030 // The device expression must evaluate to a non-negative integer value. 13031 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13032 /*StrictlyPositive=*/false)) 13033 return nullptr; 13034 13035 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13036 OpenMPDirectiveKind CaptureRegion = 13037 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13038 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13039 ValExpr = MakeFullExpr(ValExpr).get(); 13040 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13041 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13042 HelperValStmt = buildPreInits(Context, Captures); 13043 } 13044 13045 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13046 StartLoc, LParenLoc, EndLoc); 13047 } 13048 13049 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13050 DSAStackTy *Stack, QualType QTy, 13051 bool FullCheck = true) { 13052 NamedDecl *ND; 13053 if (QTy->isIncompleteType(&ND)) { 13054 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13055 return false; 13056 } 13057 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13058 !QTy.isTrivialType(SemaRef.Context)) 13059 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13060 return true; 13061 } 13062 13063 /// Return true if it can be proven that the provided array expression 13064 /// (array section or array subscript) does NOT specify the whole size of the 13065 /// array whose base type is \a BaseQTy. 13066 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13067 const Expr *E, 13068 QualType BaseQTy) { 13069 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13070 13071 // If this is an array subscript, it refers to the whole size if the size of 13072 // the dimension is constant and equals 1. Also, an array section assumes the 13073 // format of an array subscript if no colon is used. 13074 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13075 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13076 return ATy->getSize().getSExtValue() != 1; 13077 // Size can't be evaluated statically. 13078 return false; 13079 } 13080 13081 assert(OASE && "Expecting array section if not an array subscript."); 13082 const Expr *LowerBound = OASE->getLowerBound(); 13083 const Expr *Length = OASE->getLength(); 13084 13085 // If there is a lower bound that does not evaluates to zero, we are not 13086 // covering the whole dimension. 13087 if (LowerBound) { 13088 Expr::EvalResult Result; 13089 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13090 return false; // Can't get the integer value as a constant. 13091 13092 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13093 if (ConstLowerBound.getSExtValue()) 13094 return true; 13095 } 13096 13097 // If we don't have a length we covering the whole dimension. 13098 if (!Length) 13099 return false; 13100 13101 // If the base is a pointer, we don't have a way to get the size of the 13102 // pointee. 13103 if (BaseQTy->isPointerType()) 13104 return false; 13105 13106 // We can only check if the length is the same as the size of the dimension 13107 // if we have a constant array. 13108 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13109 if (!CATy) 13110 return false; 13111 13112 Expr::EvalResult Result; 13113 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13114 return false; // Can't get the integer value as a constant. 13115 13116 llvm::APSInt ConstLength = Result.Val.getInt(); 13117 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13118 } 13119 13120 // Return true if it can be proven that the provided array expression (array 13121 // section or array subscript) does NOT specify a single element of the array 13122 // whose base type is \a BaseQTy. 13123 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13124 const Expr *E, 13125 QualType BaseQTy) { 13126 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13127 13128 // An array subscript always refer to a single element. Also, an array section 13129 // assumes the format of an array subscript if no colon is used. 13130 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13131 return false; 13132 13133 assert(OASE && "Expecting array section if not an array subscript."); 13134 const Expr *Length = OASE->getLength(); 13135 13136 // If we don't have a length we have to check if the array has unitary size 13137 // for this dimension. Also, we should always expect a length if the base type 13138 // is pointer. 13139 if (!Length) { 13140 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13141 return ATy->getSize().getSExtValue() != 1; 13142 // We cannot assume anything. 13143 return false; 13144 } 13145 13146 // Check if the length evaluates to 1. 13147 Expr::EvalResult Result; 13148 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13149 return false; // Can't get the integer value as a constant. 13150 13151 llvm::APSInt ConstLength = Result.Val.getInt(); 13152 return ConstLength.getSExtValue() != 1; 13153 } 13154 13155 // Return the expression of the base of the mappable expression or null if it 13156 // cannot be determined and do all the necessary checks to see if the expression 13157 // is valid as a standalone mappable expression. In the process, record all the 13158 // components of the expression. 13159 static const Expr *checkMapClauseExpressionBase( 13160 Sema &SemaRef, Expr *E, 13161 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13162 OpenMPClauseKind CKind, bool NoDiagnose) { 13163 SourceLocation ELoc = E->getExprLoc(); 13164 SourceRange ERange = E->getSourceRange(); 13165 13166 // The base of elements of list in a map clause have to be either: 13167 // - a reference to variable or field. 13168 // - a member expression. 13169 // - an array expression. 13170 // 13171 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13172 // reference to 'r'. 13173 // 13174 // If we have: 13175 // 13176 // struct SS { 13177 // Bla S; 13178 // foo() { 13179 // #pragma omp target map (S.Arr[:12]); 13180 // } 13181 // } 13182 // 13183 // We want to retrieve the member expression 'this->S'; 13184 13185 const Expr *RelevantExpr = nullptr; 13186 13187 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13188 // If a list item is an array section, it must specify contiguous storage. 13189 // 13190 // For this restriction it is sufficient that we make sure only references 13191 // to variables or fields and array expressions, and that no array sections 13192 // exist except in the rightmost expression (unless they cover the whole 13193 // dimension of the array). E.g. these would be invalid: 13194 // 13195 // r.ArrS[3:5].Arr[6:7] 13196 // 13197 // r.ArrS[3:5].x 13198 // 13199 // but these would be valid: 13200 // r.ArrS[3].Arr[6:7] 13201 // 13202 // r.ArrS[3].x 13203 13204 bool AllowUnitySizeArraySection = true; 13205 bool AllowWholeSizeArraySection = true; 13206 13207 while (!RelevantExpr) { 13208 E = E->IgnoreParenImpCasts(); 13209 13210 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13211 if (!isa<VarDecl>(CurE->getDecl())) 13212 return nullptr; 13213 13214 RelevantExpr = CurE; 13215 13216 // If we got a reference to a declaration, we should not expect any array 13217 // section before that. 13218 AllowUnitySizeArraySection = false; 13219 AllowWholeSizeArraySection = false; 13220 13221 // Record the component. 13222 CurComponents.emplace_back(CurE, CurE->getDecl()); 13223 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13224 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13225 13226 if (isa<CXXThisExpr>(BaseE)) 13227 // We found a base expression: this->Val. 13228 RelevantExpr = CurE; 13229 else 13230 E = BaseE; 13231 13232 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13233 if (!NoDiagnose) { 13234 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13235 << CurE->getSourceRange(); 13236 return nullptr; 13237 } 13238 if (RelevantExpr) 13239 return nullptr; 13240 continue; 13241 } 13242 13243 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13244 13245 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13246 // A bit-field cannot appear in a map clause. 13247 // 13248 if (FD->isBitField()) { 13249 if (!NoDiagnose) { 13250 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13251 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13252 return nullptr; 13253 } 13254 if (RelevantExpr) 13255 return nullptr; 13256 continue; 13257 } 13258 13259 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13260 // If the type of a list item is a reference to a type T then the type 13261 // will be considered to be T for all purposes of this clause. 13262 QualType CurType = BaseE->getType().getNonReferenceType(); 13263 13264 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13265 // A list item cannot be a variable that is a member of a structure with 13266 // a union type. 13267 // 13268 if (CurType->isUnionType()) { 13269 if (!NoDiagnose) { 13270 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13271 << CurE->getSourceRange(); 13272 return nullptr; 13273 } 13274 continue; 13275 } 13276 13277 // If we got a member expression, we should not expect any array section 13278 // before that: 13279 // 13280 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13281 // If a list item is an element of a structure, only the rightmost symbol 13282 // of the variable reference can be an array section. 13283 // 13284 AllowUnitySizeArraySection = false; 13285 AllowWholeSizeArraySection = false; 13286 13287 // Record the component. 13288 CurComponents.emplace_back(CurE, FD); 13289 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13290 E = CurE->getBase()->IgnoreParenImpCasts(); 13291 13292 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13293 if (!NoDiagnose) { 13294 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13295 << 0 << CurE->getSourceRange(); 13296 return nullptr; 13297 } 13298 continue; 13299 } 13300 13301 // If we got an array subscript that express the whole dimension we 13302 // can have any array expressions before. If it only expressing part of 13303 // the dimension, we can only have unitary-size array expressions. 13304 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13305 E->getType())) 13306 AllowWholeSizeArraySection = false; 13307 13308 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13309 Expr::EvalResult Result; 13310 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13311 if (!Result.Val.getInt().isNullValue()) { 13312 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13313 diag::err_omp_invalid_map_this_expr); 13314 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13315 diag::note_omp_invalid_subscript_on_this_ptr_map); 13316 } 13317 } 13318 RelevantExpr = TE; 13319 } 13320 13321 // Record the component - we don't have any declaration associated. 13322 CurComponents.emplace_back(CurE, nullptr); 13323 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13324 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13325 E = CurE->getBase()->IgnoreParenImpCasts(); 13326 13327 QualType CurType = 13328 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13329 13330 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13331 // If the type of a list item is a reference to a type T then the type 13332 // will be considered to be T for all purposes of this clause. 13333 if (CurType->isReferenceType()) 13334 CurType = CurType->getPointeeType(); 13335 13336 bool IsPointer = CurType->isAnyPointerType(); 13337 13338 if (!IsPointer && !CurType->isArrayType()) { 13339 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13340 << 0 << CurE->getSourceRange(); 13341 return nullptr; 13342 } 13343 13344 bool NotWhole = 13345 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13346 bool NotUnity = 13347 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13348 13349 if (AllowWholeSizeArraySection) { 13350 // Any array section is currently allowed. Allowing a whole size array 13351 // section implies allowing a unity array section as well. 13352 // 13353 // If this array section refers to the whole dimension we can still 13354 // accept other array sections before this one, except if the base is a 13355 // pointer. Otherwise, only unitary sections are accepted. 13356 if (NotWhole || IsPointer) 13357 AllowWholeSizeArraySection = false; 13358 } else if (AllowUnitySizeArraySection && NotUnity) { 13359 // A unity or whole array section is not allowed and that is not 13360 // compatible with the properties of the current array section. 13361 SemaRef.Diag( 13362 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13363 << CurE->getSourceRange(); 13364 return nullptr; 13365 } 13366 13367 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13368 Expr::EvalResult ResultR; 13369 Expr::EvalResult ResultL; 13370 if (CurE->getLength()->EvaluateAsInt(ResultR, 13371 SemaRef.getASTContext())) { 13372 if (!ResultR.Val.getInt().isOneValue()) { 13373 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13374 diag::err_omp_invalid_map_this_expr); 13375 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13376 diag::note_omp_invalid_length_on_this_ptr_mapping); 13377 } 13378 } 13379 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13380 ResultL, SemaRef.getASTContext())) { 13381 if (!ResultL.Val.getInt().isNullValue()) { 13382 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13383 diag::err_omp_invalid_map_this_expr); 13384 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13385 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13386 } 13387 } 13388 RelevantExpr = TE; 13389 } 13390 13391 // Record the component - we don't have any declaration associated. 13392 CurComponents.emplace_back(CurE, nullptr); 13393 } else { 13394 if (!NoDiagnose) { 13395 // If nothing else worked, this is not a valid map clause expression. 13396 SemaRef.Diag( 13397 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13398 << ERange; 13399 } 13400 return nullptr; 13401 } 13402 } 13403 13404 return RelevantExpr; 13405 } 13406 13407 // Return true if expression E associated with value VD has conflicts with other 13408 // map information. 13409 static bool checkMapConflicts( 13410 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13411 bool CurrentRegionOnly, 13412 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13413 OpenMPClauseKind CKind) { 13414 assert(VD && E); 13415 SourceLocation ELoc = E->getExprLoc(); 13416 SourceRange ERange = E->getSourceRange(); 13417 13418 // In order to easily check the conflicts we need to match each component of 13419 // the expression under test with the components of the expressions that are 13420 // already in the stack. 13421 13422 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13423 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13424 "Map clause expression with unexpected base!"); 13425 13426 // Variables to help detecting enclosing problems in data environment nests. 13427 bool IsEnclosedByDataEnvironmentExpr = false; 13428 const Expr *EnclosingExpr = nullptr; 13429 13430 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13431 VD, CurrentRegionOnly, 13432 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13433 ERange, CKind, &EnclosingExpr, 13434 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13435 StackComponents, 13436 OpenMPClauseKind) { 13437 assert(!StackComponents.empty() && 13438 "Map clause expression with no components!"); 13439 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13440 "Map clause expression with unexpected base!"); 13441 (void)VD; 13442 13443 // The whole expression in the stack. 13444 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13445 13446 // Expressions must start from the same base. Here we detect at which 13447 // point both expressions diverge from each other and see if we can 13448 // detect if the memory referred to both expressions is contiguous and 13449 // do not overlap. 13450 auto CI = CurComponents.rbegin(); 13451 auto CE = CurComponents.rend(); 13452 auto SI = StackComponents.rbegin(); 13453 auto SE = StackComponents.rend(); 13454 for (; CI != CE && SI != SE; ++CI, ++SI) { 13455 13456 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13457 // At most one list item can be an array item derived from a given 13458 // variable in map clauses of the same construct. 13459 if (CurrentRegionOnly && 13460 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13461 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13462 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13463 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13464 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13465 diag::err_omp_multiple_array_items_in_map_clause) 13466 << CI->getAssociatedExpression()->getSourceRange(); 13467 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13468 diag::note_used_here) 13469 << SI->getAssociatedExpression()->getSourceRange(); 13470 return true; 13471 } 13472 13473 // Do both expressions have the same kind? 13474 if (CI->getAssociatedExpression()->getStmtClass() != 13475 SI->getAssociatedExpression()->getStmtClass()) 13476 break; 13477 13478 // Are we dealing with different variables/fields? 13479 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13480 break; 13481 } 13482 // Check if the extra components of the expressions in the enclosing 13483 // data environment are redundant for the current base declaration. 13484 // If they are, the maps completely overlap, which is legal. 13485 for (; SI != SE; ++SI) { 13486 QualType Type; 13487 if (const auto *ASE = 13488 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13489 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13490 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13491 SI->getAssociatedExpression())) { 13492 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13493 Type = 13494 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13495 } 13496 if (Type.isNull() || Type->isAnyPointerType() || 13497 checkArrayExpressionDoesNotReferToWholeSize( 13498 SemaRef, SI->getAssociatedExpression(), Type)) 13499 break; 13500 } 13501 13502 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13503 // List items of map clauses in the same construct must not share 13504 // original storage. 13505 // 13506 // If the expressions are exactly the same or one is a subset of the 13507 // other, it means they are sharing storage. 13508 if (CI == CE && SI == SE) { 13509 if (CurrentRegionOnly) { 13510 if (CKind == OMPC_map) { 13511 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13512 } else { 13513 assert(CKind == OMPC_to || CKind == OMPC_from); 13514 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13515 << ERange; 13516 } 13517 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13518 << RE->getSourceRange(); 13519 return true; 13520 } 13521 // If we find the same expression in the enclosing data environment, 13522 // that is legal. 13523 IsEnclosedByDataEnvironmentExpr = true; 13524 return false; 13525 } 13526 13527 QualType DerivedType = 13528 std::prev(CI)->getAssociatedDeclaration()->getType(); 13529 SourceLocation DerivedLoc = 13530 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13531 13532 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13533 // If the type of a list item is a reference to a type T then the type 13534 // will be considered to be T for all purposes of this clause. 13535 DerivedType = DerivedType.getNonReferenceType(); 13536 13537 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13538 // A variable for which the type is pointer and an array section 13539 // derived from that variable must not appear as list items of map 13540 // clauses of the same construct. 13541 // 13542 // Also, cover one of the cases in: 13543 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13544 // If any part of the original storage of a list item has corresponding 13545 // storage in the device data environment, all of the original storage 13546 // must have corresponding storage in the device data environment. 13547 // 13548 if (DerivedType->isAnyPointerType()) { 13549 if (CI == CE || SI == SE) { 13550 SemaRef.Diag( 13551 DerivedLoc, 13552 diag::err_omp_pointer_mapped_along_with_derived_section) 13553 << DerivedLoc; 13554 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13555 << RE->getSourceRange(); 13556 return true; 13557 } 13558 if (CI->getAssociatedExpression()->getStmtClass() != 13559 SI->getAssociatedExpression()->getStmtClass() || 13560 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13561 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13562 assert(CI != CE && SI != SE); 13563 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13564 << DerivedLoc; 13565 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13566 << RE->getSourceRange(); 13567 return true; 13568 } 13569 } 13570 13571 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13572 // List items of map clauses in the same construct must not share 13573 // original storage. 13574 // 13575 // An expression is a subset of the other. 13576 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13577 if (CKind == OMPC_map) { 13578 if (CI != CE || SI != SE) { 13579 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13580 // a pointer. 13581 auto Begin = 13582 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13583 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13584 auto It = Begin; 13585 while (It != End && !It->getAssociatedDeclaration()) 13586 std::advance(It, 1); 13587 assert(It != End && 13588 "Expected at least one component with the declaration."); 13589 if (It != Begin && It->getAssociatedDeclaration() 13590 ->getType() 13591 .getCanonicalType() 13592 ->isAnyPointerType()) { 13593 IsEnclosedByDataEnvironmentExpr = false; 13594 EnclosingExpr = nullptr; 13595 return false; 13596 } 13597 } 13598 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13599 } else { 13600 assert(CKind == OMPC_to || CKind == OMPC_from); 13601 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13602 << ERange; 13603 } 13604 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13605 << RE->getSourceRange(); 13606 return true; 13607 } 13608 13609 // The current expression uses the same base as other expression in the 13610 // data environment but does not contain it completely. 13611 if (!CurrentRegionOnly && SI != SE) 13612 EnclosingExpr = RE; 13613 13614 // The current expression is a subset of the expression in the data 13615 // environment. 13616 IsEnclosedByDataEnvironmentExpr |= 13617 (!CurrentRegionOnly && CI != CE && SI == SE); 13618 13619 return false; 13620 }); 13621 13622 if (CurrentRegionOnly) 13623 return FoundError; 13624 13625 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13626 // If any part of the original storage of a list item has corresponding 13627 // storage in the device data environment, all of the original storage must 13628 // have corresponding storage in the device data environment. 13629 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13630 // If a list item is an element of a structure, and a different element of 13631 // the structure has a corresponding list item in the device data environment 13632 // prior to a task encountering the construct associated with the map clause, 13633 // then the list item must also have a corresponding list item in the device 13634 // data environment prior to the task encountering the construct. 13635 // 13636 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13637 SemaRef.Diag(ELoc, 13638 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13639 << ERange; 13640 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13641 << EnclosingExpr->getSourceRange(); 13642 return true; 13643 } 13644 13645 return FoundError; 13646 } 13647 13648 // Look up the user-defined mapper given the mapper name and mapped type, and 13649 // build a reference to it. 13650 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13651 CXXScopeSpec &MapperIdScopeSpec, 13652 const DeclarationNameInfo &MapperId, 13653 QualType Type, 13654 Expr *UnresolvedMapper) { 13655 if (MapperIdScopeSpec.isInvalid()) 13656 return ExprError(); 13657 // Find all user-defined mappers with the given MapperId. 13658 SmallVector<UnresolvedSet<8>, 4> Lookups; 13659 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13660 Lookup.suppressDiagnostics(); 13661 if (S) { 13662 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13663 NamedDecl *D = Lookup.getRepresentativeDecl(); 13664 while (S && !S->isDeclScope(D)) 13665 S = S->getParent(); 13666 if (S) 13667 S = S->getParent(); 13668 Lookups.emplace_back(); 13669 Lookups.back().append(Lookup.begin(), Lookup.end()); 13670 Lookup.clear(); 13671 } 13672 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13673 // Extract the user-defined mappers with the given MapperId. 13674 Lookups.push_back(UnresolvedSet<8>()); 13675 for (NamedDecl *D : ULE->decls()) { 13676 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13677 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13678 Lookups.back().addDecl(DMD); 13679 } 13680 } 13681 // Defer the lookup for dependent types. The results will be passed through 13682 // UnresolvedMapper on instantiation. 13683 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13684 Type->isInstantiationDependentType() || 13685 Type->containsUnexpandedParameterPack() || 13686 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13687 return !D->isInvalidDecl() && 13688 (D->getType()->isDependentType() || 13689 D->getType()->isInstantiationDependentType() || 13690 D->getType()->containsUnexpandedParameterPack()); 13691 })) { 13692 UnresolvedSet<8> URS; 13693 for (const UnresolvedSet<8> &Set : Lookups) { 13694 if (Set.empty()) 13695 continue; 13696 URS.append(Set.begin(), Set.end()); 13697 } 13698 return UnresolvedLookupExpr::Create( 13699 SemaRef.Context, /*NamingClass=*/nullptr, 13700 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13701 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13702 } 13703 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13704 // The type must be of struct, union or class type in C and C++ 13705 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13706 return ExprEmpty(); 13707 SourceLocation Loc = MapperId.getLoc(); 13708 // Perform argument dependent lookup. 13709 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13710 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13711 // Return the first user-defined mapper with the desired type. 13712 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13713 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13714 if (!D->isInvalidDecl() && 13715 SemaRef.Context.hasSameType(D->getType(), Type)) 13716 return D; 13717 return nullptr; 13718 })) 13719 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13720 // Find the first user-defined mapper with a type derived from the desired 13721 // type. 13722 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13723 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13724 if (!D->isInvalidDecl() && 13725 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13726 !Type.isMoreQualifiedThan(D->getType())) 13727 return D; 13728 return nullptr; 13729 })) { 13730 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13731 /*DetectVirtual=*/false); 13732 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13733 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13734 VD->getType().getUnqualifiedType()))) { 13735 if (SemaRef.CheckBaseClassAccess( 13736 Loc, VD->getType(), Type, Paths.front(), 13737 /*DiagID=*/0) != Sema::AR_inaccessible) { 13738 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13739 } 13740 } 13741 } 13742 } 13743 // Report error if a mapper is specified, but cannot be found. 13744 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13745 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13746 << Type << MapperId.getName(); 13747 return ExprError(); 13748 } 13749 return ExprEmpty(); 13750 } 13751 13752 namespace { 13753 // Utility struct that gathers all the related lists associated with a mappable 13754 // expression. 13755 struct MappableVarListInfo { 13756 // The list of expressions. 13757 ArrayRef<Expr *> VarList; 13758 // The list of processed expressions. 13759 SmallVector<Expr *, 16> ProcessedVarList; 13760 // The mappble components for each expression. 13761 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13762 // The base declaration of the variable. 13763 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13764 // The reference to the user-defined mapper associated with every expression. 13765 SmallVector<Expr *, 16> UDMapperList; 13766 13767 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13768 // We have a list of components and base declarations for each entry in the 13769 // variable list. 13770 VarComponents.reserve(VarList.size()); 13771 VarBaseDeclarations.reserve(VarList.size()); 13772 } 13773 }; 13774 } 13775 13776 // Check the validity of the provided variable list for the provided clause kind 13777 // \a CKind. In the check process the valid expressions, mappable expression 13778 // components, variables, and user-defined mappers are extracted and used to 13779 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13780 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13781 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13782 static void checkMappableExpressionList( 13783 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13784 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13785 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13786 ArrayRef<Expr *> UnresolvedMappers, 13787 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13788 bool IsMapTypeImplicit = false) { 13789 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13790 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13791 "Unexpected clause kind with mappable expressions!"); 13792 13793 // If the identifier of user-defined mapper is not specified, it is "default". 13794 // We do not change the actual name in this clause to distinguish whether a 13795 // mapper is specified explicitly, i.e., it is not explicitly specified when 13796 // MapperId.getName() is empty. 13797 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13798 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 13799 MapperId.setName(DeclNames.getIdentifier( 13800 &SemaRef.getASTContext().Idents.get("default"))); 13801 } 13802 13803 // Iterators to find the current unresolved mapper expression. 13804 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 13805 bool UpdateUMIt = false; 13806 Expr *UnresolvedMapper = nullptr; 13807 13808 // Keep track of the mappable components and base declarations in this clause. 13809 // Each entry in the list is going to have a list of components associated. We 13810 // record each set of the components so that we can build the clause later on. 13811 // In the end we should have the same amount of declarations and component 13812 // lists. 13813 13814 for (Expr *RE : MVLI.VarList) { 13815 assert(RE && "Null expr in omp to/from/map clause"); 13816 SourceLocation ELoc = RE->getExprLoc(); 13817 13818 // Find the current unresolved mapper expression. 13819 if (UpdateUMIt && UMIt != UMEnd) { 13820 UMIt++; 13821 assert( 13822 UMIt != UMEnd && 13823 "Expect the size of UnresolvedMappers to match with that of VarList"); 13824 } 13825 UpdateUMIt = true; 13826 if (UMIt != UMEnd) 13827 UnresolvedMapper = *UMIt; 13828 13829 const Expr *VE = RE->IgnoreParenLValueCasts(); 13830 13831 if (VE->isValueDependent() || VE->isTypeDependent() || 13832 VE->isInstantiationDependent() || 13833 VE->containsUnexpandedParameterPack()) { 13834 // Try to find the associated user-defined mapper. 13835 ExprResult ER = buildUserDefinedMapperRef( 13836 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13837 VE->getType().getCanonicalType(), UnresolvedMapper); 13838 if (ER.isInvalid()) 13839 continue; 13840 MVLI.UDMapperList.push_back(ER.get()); 13841 // We can only analyze this information once the missing information is 13842 // resolved. 13843 MVLI.ProcessedVarList.push_back(RE); 13844 continue; 13845 } 13846 13847 Expr *SimpleExpr = RE->IgnoreParenCasts(); 13848 13849 if (!RE->IgnoreParenImpCasts()->isLValue()) { 13850 SemaRef.Diag(ELoc, 13851 diag::err_omp_expected_named_var_member_or_array_expression) 13852 << RE->getSourceRange(); 13853 continue; 13854 } 13855 13856 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 13857 ValueDecl *CurDeclaration = nullptr; 13858 13859 // Obtain the array or member expression bases if required. Also, fill the 13860 // components array with all the components identified in the process. 13861 const Expr *BE = checkMapClauseExpressionBase( 13862 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 13863 if (!BE) 13864 continue; 13865 13866 assert(!CurComponents.empty() && 13867 "Invalid mappable expression information."); 13868 13869 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 13870 // Add store "this" pointer to class in DSAStackTy for future checking 13871 DSAS->addMappedClassesQualTypes(TE->getType()); 13872 // Try to find the associated user-defined mapper. 13873 ExprResult ER = buildUserDefinedMapperRef( 13874 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13875 VE->getType().getCanonicalType(), UnresolvedMapper); 13876 if (ER.isInvalid()) 13877 continue; 13878 MVLI.UDMapperList.push_back(ER.get()); 13879 // Skip restriction checking for variable or field declarations 13880 MVLI.ProcessedVarList.push_back(RE); 13881 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13882 MVLI.VarComponents.back().append(CurComponents.begin(), 13883 CurComponents.end()); 13884 MVLI.VarBaseDeclarations.push_back(nullptr); 13885 continue; 13886 } 13887 13888 // For the following checks, we rely on the base declaration which is 13889 // expected to be associated with the last component. The declaration is 13890 // expected to be a variable or a field (if 'this' is being mapped). 13891 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 13892 assert(CurDeclaration && "Null decl on map clause."); 13893 assert( 13894 CurDeclaration->isCanonicalDecl() && 13895 "Expecting components to have associated only canonical declarations."); 13896 13897 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 13898 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 13899 13900 assert((VD || FD) && "Only variables or fields are expected here!"); 13901 (void)FD; 13902 13903 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 13904 // threadprivate variables cannot appear in a map clause. 13905 // OpenMP 4.5 [2.10.5, target update Construct] 13906 // threadprivate variables cannot appear in a from clause. 13907 if (VD && DSAS->isThreadPrivate(VD)) { 13908 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13909 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 13910 << getOpenMPClauseName(CKind); 13911 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 13912 continue; 13913 } 13914 13915 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13916 // A list item cannot appear in both a map clause and a data-sharing 13917 // attribute clause on the same construct. 13918 13919 // Check conflicts with other map clause expressions. We check the conflicts 13920 // with the current construct separately from the enclosing data 13921 // environment, because the restrictions are different. We only have to 13922 // check conflicts across regions for the map clauses. 13923 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13924 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 13925 break; 13926 if (CKind == OMPC_map && 13927 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13928 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 13929 break; 13930 13931 // OpenMP 4.5 [2.10.5, target update Construct] 13932 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13933 // If the type of a list item is a reference to a type T then the type will 13934 // be considered to be T for all purposes of this clause. 13935 auto I = llvm::find_if( 13936 CurComponents, 13937 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 13938 return MC.getAssociatedDeclaration(); 13939 }); 13940 assert(I != CurComponents.end() && "Null decl on map clause."); 13941 QualType Type = 13942 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 13943 13944 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 13945 // A list item in a to or from clause must have a mappable type. 13946 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13947 // A list item must have a mappable type. 13948 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 13949 DSAS, Type)) 13950 continue; 13951 13952 if (CKind == OMPC_map) { 13953 // target enter data 13954 // OpenMP [2.10.2, Restrictions, p. 99] 13955 // A map-type must be specified in all map clauses and must be either 13956 // to or alloc. 13957 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 13958 if (DKind == OMPD_target_enter_data && 13959 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 13960 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13961 << (IsMapTypeImplicit ? 1 : 0) 13962 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13963 << getOpenMPDirectiveName(DKind); 13964 continue; 13965 } 13966 13967 // target exit_data 13968 // OpenMP [2.10.3, Restrictions, p. 102] 13969 // A map-type must be specified in all map clauses and must be either 13970 // from, release, or delete. 13971 if (DKind == OMPD_target_exit_data && 13972 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 13973 MapType == OMPC_MAP_delete)) { 13974 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13975 << (IsMapTypeImplicit ? 1 : 0) 13976 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13977 << getOpenMPDirectiveName(DKind); 13978 continue; 13979 } 13980 13981 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13982 // A list item cannot appear in both a map clause and a data-sharing 13983 // attribute clause on the same construct 13984 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 13985 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13986 if (isOpenMPPrivate(DVar.CKind)) { 13987 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13988 << getOpenMPClauseName(DVar.CKind) 13989 << getOpenMPClauseName(OMPC_map) 13990 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 13991 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 13992 continue; 13993 } 13994 } 13995 } 13996 13997 // Try to find the associated user-defined mapper. 13998 ExprResult ER = buildUserDefinedMapperRef( 13999 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14000 Type.getCanonicalType(), UnresolvedMapper); 14001 if (ER.isInvalid()) 14002 continue; 14003 MVLI.UDMapperList.push_back(ER.get()); 14004 14005 // Save the current expression. 14006 MVLI.ProcessedVarList.push_back(RE); 14007 14008 // Store the components in the stack so that they can be used to check 14009 // against other clauses later on. 14010 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14011 /*WhereFoundClauseKind=*/OMPC_map); 14012 14013 // Save the components and declaration to create the clause. For purposes of 14014 // the clause creation, any component list that has has base 'this' uses 14015 // null as base declaration. 14016 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14017 MVLI.VarComponents.back().append(CurComponents.begin(), 14018 CurComponents.end()); 14019 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14020 : CurDeclaration); 14021 } 14022 } 14023 14024 OMPClause *Sema::ActOnOpenMPMapClause( 14025 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14026 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14027 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14028 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14029 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14030 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14031 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14032 OMPC_MAP_MODIFIER_unknown, 14033 OMPC_MAP_MODIFIER_unknown}; 14034 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14035 14036 // Process map-type-modifiers, flag errors for duplicate modifiers. 14037 unsigned Count = 0; 14038 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14039 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14040 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14041 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14042 continue; 14043 } 14044 assert(Count < OMPMapClause::NumberOfModifiers && 14045 "Modifiers exceed the allowed number of map type modifiers"); 14046 Modifiers[Count] = MapTypeModifiers[I]; 14047 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14048 ++Count; 14049 } 14050 14051 MappableVarListInfo MVLI(VarList); 14052 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14053 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14054 MapType, IsMapTypeImplicit); 14055 14056 // We need to produce a map clause even if we don't have variables so that 14057 // other diagnostics related with non-existing map clauses are accurate. 14058 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14059 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14060 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14061 MapperIdScopeSpec.getWithLocInContext(Context), 14062 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14063 } 14064 14065 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14066 TypeResult ParsedType) { 14067 assert(ParsedType.isUsable()); 14068 14069 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14070 if (ReductionType.isNull()) 14071 return QualType(); 14072 14073 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14074 // A type name in a declare reduction directive cannot be a function type, an 14075 // array type, a reference type, or a type qualified with const, volatile or 14076 // restrict. 14077 if (ReductionType.hasQualifiers()) { 14078 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14079 return QualType(); 14080 } 14081 14082 if (ReductionType->isFunctionType()) { 14083 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14084 return QualType(); 14085 } 14086 if (ReductionType->isReferenceType()) { 14087 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14088 return QualType(); 14089 } 14090 if (ReductionType->isArrayType()) { 14091 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14092 return QualType(); 14093 } 14094 return ReductionType; 14095 } 14096 14097 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14098 Scope *S, DeclContext *DC, DeclarationName Name, 14099 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14100 AccessSpecifier AS, Decl *PrevDeclInScope) { 14101 SmallVector<Decl *, 8> Decls; 14102 Decls.reserve(ReductionTypes.size()); 14103 14104 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14105 forRedeclarationInCurContext()); 14106 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14107 // A reduction-identifier may not be re-declared in the current scope for the 14108 // same type or for a type that is compatible according to the base language 14109 // rules. 14110 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14111 OMPDeclareReductionDecl *PrevDRD = nullptr; 14112 bool InCompoundScope = true; 14113 if (S != nullptr) { 14114 // Find previous declaration with the same name not referenced in other 14115 // declarations. 14116 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14117 InCompoundScope = 14118 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14119 LookupName(Lookup, S); 14120 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14121 /*AllowInlineNamespace=*/false); 14122 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14123 LookupResult::Filter Filter = Lookup.makeFilter(); 14124 while (Filter.hasNext()) { 14125 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14126 if (InCompoundScope) { 14127 auto I = UsedAsPrevious.find(PrevDecl); 14128 if (I == UsedAsPrevious.end()) 14129 UsedAsPrevious[PrevDecl] = false; 14130 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14131 UsedAsPrevious[D] = true; 14132 } 14133 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14134 PrevDecl->getLocation(); 14135 } 14136 Filter.done(); 14137 if (InCompoundScope) { 14138 for (const auto &PrevData : UsedAsPrevious) { 14139 if (!PrevData.second) { 14140 PrevDRD = PrevData.first; 14141 break; 14142 } 14143 } 14144 } 14145 } else if (PrevDeclInScope != nullptr) { 14146 auto *PrevDRDInScope = PrevDRD = 14147 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14148 do { 14149 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14150 PrevDRDInScope->getLocation(); 14151 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14152 } while (PrevDRDInScope != nullptr); 14153 } 14154 for (const auto &TyData : ReductionTypes) { 14155 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14156 bool Invalid = false; 14157 if (I != PreviousRedeclTypes.end()) { 14158 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14159 << TyData.first; 14160 Diag(I->second, diag::note_previous_definition); 14161 Invalid = true; 14162 } 14163 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14164 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14165 Name, TyData.first, PrevDRD); 14166 DC->addDecl(DRD); 14167 DRD->setAccess(AS); 14168 Decls.push_back(DRD); 14169 if (Invalid) 14170 DRD->setInvalidDecl(); 14171 else 14172 PrevDRD = DRD; 14173 } 14174 14175 return DeclGroupPtrTy::make( 14176 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14177 } 14178 14179 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14180 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14181 14182 // Enter new function scope. 14183 PushFunctionScope(); 14184 setFunctionHasBranchProtectedScope(); 14185 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14186 14187 if (S != nullptr) 14188 PushDeclContext(S, DRD); 14189 else 14190 CurContext = DRD; 14191 14192 PushExpressionEvaluationContext( 14193 ExpressionEvaluationContext::PotentiallyEvaluated); 14194 14195 QualType ReductionType = DRD->getType(); 14196 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14197 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14198 // uses semantics of argument handles by value, but it should be passed by 14199 // reference. C lang does not support references, so pass all parameters as 14200 // pointers. 14201 // Create 'T omp_in;' variable. 14202 VarDecl *OmpInParm = 14203 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14204 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14205 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14206 // uses semantics of argument handles by value, but it should be passed by 14207 // reference. C lang does not support references, so pass all parameters as 14208 // pointers. 14209 // Create 'T omp_out;' variable. 14210 VarDecl *OmpOutParm = 14211 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14212 if (S != nullptr) { 14213 PushOnScopeChains(OmpInParm, S); 14214 PushOnScopeChains(OmpOutParm, S); 14215 } else { 14216 DRD->addDecl(OmpInParm); 14217 DRD->addDecl(OmpOutParm); 14218 } 14219 Expr *InE = 14220 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14221 Expr *OutE = 14222 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14223 DRD->setCombinerData(InE, OutE); 14224 } 14225 14226 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14227 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14228 DiscardCleanupsInEvaluationContext(); 14229 PopExpressionEvaluationContext(); 14230 14231 PopDeclContext(); 14232 PopFunctionScopeInfo(); 14233 14234 if (Combiner != nullptr) 14235 DRD->setCombiner(Combiner); 14236 else 14237 DRD->setInvalidDecl(); 14238 } 14239 14240 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14241 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14242 14243 // Enter new function scope. 14244 PushFunctionScope(); 14245 setFunctionHasBranchProtectedScope(); 14246 14247 if (S != nullptr) 14248 PushDeclContext(S, DRD); 14249 else 14250 CurContext = DRD; 14251 14252 PushExpressionEvaluationContext( 14253 ExpressionEvaluationContext::PotentiallyEvaluated); 14254 14255 QualType ReductionType = DRD->getType(); 14256 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14257 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14258 // uses semantics of argument handles by value, but it should be passed by 14259 // reference. C lang does not support references, so pass all parameters as 14260 // pointers. 14261 // Create 'T omp_priv;' variable. 14262 VarDecl *OmpPrivParm = 14263 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14264 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14265 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14266 // uses semantics of argument handles by value, but it should be passed by 14267 // reference. C lang does not support references, so pass all parameters as 14268 // pointers. 14269 // Create 'T omp_orig;' variable. 14270 VarDecl *OmpOrigParm = 14271 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14272 if (S != nullptr) { 14273 PushOnScopeChains(OmpPrivParm, S); 14274 PushOnScopeChains(OmpOrigParm, S); 14275 } else { 14276 DRD->addDecl(OmpPrivParm); 14277 DRD->addDecl(OmpOrigParm); 14278 } 14279 Expr *OrigE = 14280 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14281 Expr *PrivE = 14282 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14283 DRD->setInitializerData(OrigE, PrivE); 14284 return OmpPrivParm; 14285 } 14286 14287 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14288 VarDecl *OmpPrivParm) { 14289 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14290 DiscardCleanupsInEvaluationContext(); 14291 PopExpressionEvaluationContext(); 14292 14293 PopDeclContext(); 14294 PopFunctionScopeInfo(); 14295 14296 if (Initializer != nullptr) { 14297 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14298 } else if (OmpPrivParm->hasInit()) { 14299 DRD->setInitializer(OmpPrivParm->getInit(), 14300 OmpPrivParm->isDirectInit() 14301 ? OMPDeclareReductionDecl::DirectInit 14302 : OMPDeclareReductionDecl::CopyInit); 14303 } else { 14304 DRD->setInvalidDecl(); 14305 } 14306 } 14307 14308 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14309 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14310 for (Decl *D : DeclReductions.get()) { 14311 if (IsValid) { 14312 if (S) 14313 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14314 /*AddToContext=*/false); 14315 } else { 14316 D->setInvalidDecl(); 14317 } 14318 } 14319 return DeclReductions; 14320 } 14321 14322 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14323 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14324 QualType T = TInfo->getType(); 14325 if (D.isInvalidType()) 14326 return true; 14327 14328 if (getLangOpts().CPlusPlus) { 14329 // Check that there are no default arguments (C++ only). 14330 CheckExtraCXXDefaultArguments(D); 14331 } 14332 14333 return CreateParsedType(T, TInfo); 14334 } 14335 14336 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14337 TypeResult ParsedType) { 14338 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14339 14340 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14341 assert(!MapperType.isNull() && "Expect valid mapper type"); 14342 14343 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14344 // The type must be of struct, union or class type in C and C++ 14345 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14346 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14347 return QualType(); 14348 } 14349 return MapperType; 14350 } 14351 14352 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14353 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14354 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14355 Decl *PrevDeclInScope) { 14356 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14357 forRedeclarationInCurContext()); 14358 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14359 // A mapper-identifier may not be redeclared in the current scope for the 14360 // same type or for a type that is compatible according to the base language 14361 // rules. 14362 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14363 OMPDeclareMapperDecl *PrevDMD = nullptr; 14364 bool InCompoundScope = true; 14365 if (S != nullptr) { 14366 // Find previous declaration with the same name not referenced in other 14367 // declarations. 14368 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14369 InCompoundScope = 14370 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14371 LookupName(Lookup, S); 14372 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14373 /*AllowInlineNamespace=*/false); 14374 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14375 LookupResult::Filter Filter = Lookup.makeFilter(); 14376 while (Filter.hasNext()) { 14377 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14378 if (InCompoundScope) { 14379 auto I = UsedAsPrevious.find(PrevDecl); 14380 if (I == UsedAsPrevious.end()) 14381 UsedAsPrevious[PrevDecl] = false; 14382 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14383 UsedAsPrevious[D] = true; 14384 } 14385 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14386 PrevDecl->getLocation(); 14387 } 14388 Filter.done(); 14389 if (InCompoundScope) { 14390 for (const auto &PrevData : UsedAsPrevious) { 14391 if (!PrevData.second) { 14392 PrevDMD = PrevData.first; 14393 break; 14394 } 14395 } 14396 } 14397 } else if (PrevDeclInScope) { 14398 auto *PrevDMDInScope = PrevDMD = 14399 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14400 do { 14401 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14402 PrevDMDInScope->getLocation(); 14403 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14404 } while (PrevDMDInScope != nullptr); 14405 } 14406 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14407 bool Invalid = false; 14408 if (I != PreviousRedeclTypes.end()) { 14409 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14410 << MapperType << Name; 14411 Diag(I->second, diag::note_previous_definition); 14412 Invalid = true; 14413 } 14414 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14415 MapperType, VN, PrevDMD); 14416 DC->addDecl(DMD); 14417 DMD->setAccess(AS); 14418 if (Invalid) 14419 DMD->setInvalidDecl(); 14420 14421 // Enter new function scope. 14422 PushFunctionScope(); 14423 setFunctionHasBranchProtectedScope(); 14424 14425 CurContext = DMD; 14426 14427 return DMD; 14428 } 14429 14430 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14431 Scope *S, 14432 QualType MapperType, 14433 SourceLocation StartLoc, 14434 DeclarationName VN) { 14435 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14436 if (S) 14437 PushOnScopeChains(VD, S); 14438 else 14439 DMD->addDecl(VD); 14440 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14441 DMD->setMapperVarRef(MapperVarRefExpr); 14442 } 14443 14444 Sema::DeclGroupPtrTy 14445 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14446 ArrayRef<OMPClause *> ClauseList) { 14447 PopDeclContext(); 14448 PopFunctionScopeInfo(); 14449 14450 if (D) { 14451 if (S) 14452 PushOnScopeChains(D, S, /*AddToContext=*/false); 14453 D->CreateClauses(Context, ClauseList); 14454 } 14455 14456 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14457 } 14458 14459 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14460 SourceLocation StartLoc, 14461 SourceLocation LParenLoc, 14462 SourceLocation EndLoc) { 14463 Expr *ValExpr = NumTeams; 14464 Stmt *HelperValStmt = nullptr; 14465 14466 // OpenMP [teams Constrcut, Restrictions] 14467 // The num_teams expression must evaluate to a positive integer value. 14468 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14469 /*StrictlyPositive=*/true)) 14470 return nullptr; 14471 14472 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14473 OpenMPDirectiveKind CaptureRegion = 14474 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14475 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14476 ValExpr = MakeFullExpr(ValExpr).get(); 14477 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14478 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14479 HelperValStmt = buildPreInits(Context, Captures); 14480 } 14481 14482 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14483 StartLoc, LParenLoc, EndLoc); 14484 } 14485 14486 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14487 SourceLocation StartLoc, 14488 SourceLocation LParenLoc, 14489 SourceLocation EndLoc) { 14490 Expr *ValExpr = ThreadLimit; 14491 Stmt *HelperValStmt = nullptr; 14492 14493 // OpenMP [teams Constrcut, Restrictions] 14494 // The thread_limit expression must evaluate to a positive integer value. 14495 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14496 /*StrictlyPositive=*/true)) 14497 return nullptr; 14498 14499 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14500 OpenMPDirectiveKind CaptureRegion = 14501 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14502 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14503 ValExpr = MakeFullExpr(ValExpr).get(); 14504 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14505 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14506 HelperValStmt = buildPreInits(Context, Captures); 14507 } 14508 14509 return new (Context) OMPThreadLimitClause( 14510 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14511 } 14512 14513 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14514 SourceLocation StartLoc, 14515 SourceLocation LParenLoc, 14516 SourceLocation EndLoc) { 14517 Expr *ValExpr = Priority; 14518 14519 // OpenMP [2.9.1, task Constrcut] 14520 // The priority-value is a non-negative numerical scalar expression. 14521 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14522 /*StrictlyPositive=*/false)) 14523 return nullptr; 14524 14525 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14526 } 14527 14528 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14529 SourceLocation StartLoc, 14530 SourceLocation LParenLoc, 14531 SourceLocation EndLoc) { 14532 Expr *ValExpr = Grainsize; 14533 14534 // OpenMP [2.9.2, taskloop Constrcut] 14535 // The parameter of the grainsize clause must be a positive integer 14536 // expression. 14537 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14538 /*StrictlyPositive=*/true)) 14539 return nullptr; 14540 14541 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14542 } 14543 14544 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14545 SourceLocation StartLoc, 14546 SourceLocation LParenLoc, 14547 SourceLocation EndLoc) { 14548 Expr *ValExpr = NumTasks; 14549 14550 // OpenMP [2.9.2, taskloop Constrcut] 14551 // The parameter of the num_tasks clause must be a positive integer 14552 // expression. 14553 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14554 /*StrictlyPositive=*/true)) 14555 return nullptr; 14556 14557 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14558 } 14559 14560 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14561 SourceLocation LParenLoc, 14562 SourceLocation EndLoc) { 14563 // OpenMP [2.13.2, critical construct, Description] 14564 // ... where hint-expression is an integer constant expression that evaluates 14565 // to a valid lock hint. 14566 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14567 if (HintExpr.isInvalid()) 14568 return nullptr; 14569 return new (Context) 14570 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14571 } 14572 14573 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14574 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14575 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14576 SourceLocation EndLoc) { 14577 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14578 std::string Values; 14579 Values += "'"; 14580 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14581 Values += "'"; 14582 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14583 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14584 return nullptr; 14585 } 14586 Expr *ValExpr = ChunkSize; 14587 Stmt *HelperValStmt = nullptr; 14588 if (ChunkSize) { 14589 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14590 !ChunkSize->isInstantiationDependent() && 14591 !ChunkSize->containsUnexpandedParameterPack()) { 14592 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14593 ExprResult Val = 14594 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14595 if (Val.isInvalid()) 14596 return nullptr; 14597 14598 ValExpr = Val.get(); 14599 14600 // OpenMP [2.7.1, Restrictions] 14601 // chunk_size must be a loop invariant integer expression with a positive 14602 // value. 14603 llvm::APSInt Result; 14604 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14605 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14606 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14607 << "dist_schedule" << ChunkSize->getSourceRange(); 14608 return nullptr; 14609 } 14610 } else if (getOpenMPCaptureRegionForClause( 14611 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14612 OMPD_unknown && 14613 !CurContext->isDependentContext()) { 14614 ValExpr = MakeFullExpr(ValExpr).get(); 14615 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14616 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14617 HelperValStmt = buildPreInits(Context, Captures); 14618 } 14619 } 14620 } 14621 14622 return new (Context) 14623 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14624 Kind, ValExpr, HelperValStmt); 14625 } 14626 14627 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14628 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14629 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14630 SourceLocation KindLoc, SourceLocation EndLoc) { 14631 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14632 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14633 std::string Value; 14634 SourceLocation Loc; 14635 Value += "'"; 14636 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14637 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14638 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14639 Loc = MLoc; 14640 } else { 14641 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14642 OMPC_DEFAULTMAP_scalar); 14643 Loc = KindLoc; 14644 } 14645 Value += "'"; 14646 Diag(Loc, diag::err_omp_unexpected_clause_value) 14647 << Value << getOpenMPClauseName(OMPC_defaultmap); 14648 return nullptr; 14649 } 14650 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14651 14652 return new (Context) 14653 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14654 } 14655 14656 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14657 DeclContext *CurLexicalContext = getCurLexicalContext(); 14658 if (!CurLexicalContext->isFileContext() && 14659 !CurLexicalContext->isExternCContext() && 14660 !CurLexicalContext->isExternCXXContext() && 14661 !isa<CXXRecordDecl>(CurLexicalContext) && 14662 !isa<ClassTemplateDecl>(CurLexicalContext) && 14663 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14664 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14665 Diag(Loc, diag::err_omp_region_not_file_context); 14666 return false; 14667 } 14668 ++DeclareTargetNestingLevel; 14669 return true; 14670 } 14671 14672 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14673 assert(DeclareTargetNestingLevel > 0 && 14674 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14675 --DeclareTargetNestingLevel; 14676 } 14677 14678 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14679 CXXScopeSpec &ScopeSpec, 14680 const DeclarationNameInfo &Id, 14681 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14682 NamedDeclSetType &SameDirectiveDecls) { 14683 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14684 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14685 14686 if (Lookup.isAmbiguous()) 14687 return; 14688 Lookup.suppressDiagnostics(); 14689 14690 if (!Lookup.isSingleResult()) { 14691 VarOrFuncDeclFilterCCC CCC(*this); 14692 if (TypoCorrection Corrected = 14693 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 14694 CTK_ErrorRecovery)) { 14695 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14696 << Id.getName()); 14697 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14698 return; 14699 } 14700 14701 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14702 return; 14703 } 14704 14705 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14706 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14707 isa<FunctionTemplateDecl>(ND)) { 14708 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14709 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14710 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14711 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14712 cast<ValueDecl>(ND)); 14713 if (!Res) { 14714 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14715 ND->addAttr(A); 14716 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14717 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14718 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14719 } else if (*Res != MT) { 14720 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14721 << Id.getName(); 14722 } 14723 } else { 14724 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14725 } 14726 } 14727 14728 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14729 Sema &SemaRef, Decl *D) { 14730 if (!D || !isa<VarDecl>(D)) 14731 return; 14732 auto *VD = cast<VarDecl>(D); 14733 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14734 return; 14735 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14736 SemaRef.Diag(SL, diag::note_used_here) << SR; 14737 } 14738 14739 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14740 Sema &SemaRef, DSAStackTy *Stack, 14741 ValueDecl *VD) { 14742 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14743 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14744 /*FullCheck=*/false); 14745 } 14746 14747 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14748 SourceLocation IdLoc) { 14749 if (!D || D->isInvalidDecl()) 14750 return; 14751 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14752 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14753 if (auto *VD = dyn_cast<VarDecl>(D)) { 14754 // Only global variables can be marked as declare target. 14755 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14756 !VD->isStaticDataMember()) 14757 return; 14758 // 2.10.6: threadprivate variable cannot appear in a declare target 14759 // directive. 14760 if (DSAStack->isThreadPrivate(VD)) { 14761 Diag(SL, diag::err_omp_threadprivate_in_target); 14762 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14763 return; 14764 } 14765 } 14766 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14767 D = FTD->getTemplatedDecl(); 14768 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14769 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14770 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14771 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14772 assert(IdLoc.isValid() && "Source location is expected"); 14773 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14774 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14775 return; 14776 } 14777 } 14778 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14779 // Problem if any with var declared with incomplete type will be reported 14780 // as normal, so no need to check it here. 14781 if ((E || !VD->getType()->isIncompleteType()) && 14782 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14783 return; 14784 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14785 // Checking declaration inside declare target region. 14786 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14787 isa<FunctionTemplateDecl>(D)) { 14788 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14789 Context, OMPDeclareTargetDeclAttr::MT_To); 14790 D->addAttr(A); 14791 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14792 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14793 } 14794 return; 14795 } 14796 } 14797 if (!E) 14798 return; 14799 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 14800 } 14801 14802 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 14803 CXXScopeSpec &MapperIdScopeSpec, 14804 DeclarationNameInfo &MapperId, 14805 const OMPVarListLocTy &Locs, 14806 ArrayRef<Expr *> UnresolvedMappers) { 14807 MappableVarListInfo MVLI(VarList); 14808 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 14809 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14810 if (MVLI.ProcessedVarList.empty()) 14811 return nullptr; 14812 14813 return OMPToClause::Create( 14814 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14815 MVLI.VarComponents, MVLI.UDMapperList, 14816 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14817 } 14818 14819 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 14820 CXXScopeSpec &MapperIdScopeSpec, 14821 DeclarationNameInfo &MapperId, 14822 const OMPVarListLocTy &Locs, 14823 ArrayRef<Expr *> UnresolvedMappers) { 14824 MappableVarListInfo MVLI(VarList); 14825 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 14826 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14827 if (MVLI.ProcessedVarList.empty()) 14828 return nullptr; 14829 14830 return OMPFromClause::Create( 14831 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14832 MVLI.VarComponents, MVLI.UDMapperList, 14833 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14834 } 14835 14836 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 14837 const OMPVarListLocTy &Locs) { 14838 MappableVarListInfo MVLI(VarList); 14839 SmallVector<Expr *, 8> PrivateCopies; 14840 SmallVector<Expr *, 8> Inits; 14841 14842 for (Expr *RefExpr : VarList) { 14843 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 14844 SourceLocation ELoc; 14845 SourceRange ERange; 14846 Expr *SimpleRefExpr = RefExpr; 14847 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14848 if (Res.second) { 14849 // It will be analyzed later. 14850 MVLI.ProcessedVarList.push_back(RefExpr); 14851 PrivateCopies.push_back(nullptr); 14852 Inits.push_back(nullptr); 14853 } 14854 ValueDecl *D = Res.first; 14855 if (!D) 14856 continue; 14857 14858 QualType Type = D->getType(); 14859 Type = Type.getNonReferenceType().getUnqualifiedType(); 14860 14861 auto *VD = dyn_cast<VarDecl>(D); 14862 14863 // Item should be a pointer or reference to pointer. 14864 if (!Type->isPointerType()) { 14865 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 14866 << 0 << RefExpr->getSourceRange(); 14867 continue; 14868 } 14869 14870 // Build the private variable and the expression that refers to it. 14871 auto VDPrivate = 14872 buildVarDecl(*this, ELoc, Type, D->getName(), 14873 D->hasAttrs() ? &D->getAttrs() : nullptr, 14874 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14875 if (VDPrivate->isInvalidDecl()) 14876 continue; 14877 14878 CurContext->addDecl(VDPrivate); 14879 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14880 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 14881 14882 // Add temporary variable to initialize the private copy of the pointer. 14883 VarDecl *VDInit = 14884 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 14885 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 14886 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 14887 AddInitializerToDecl(VDPrivate, 14888 DefaultLvalueConversion(VDInitRefExpr).get(), 14889 /*DirectInit=*/false); 14890 14891 // If required, build a capture to implement the privatization initialized 14892 // with the current list item value. 14893 DeclRefExpr *Ref = nullptr; 14894 if (!VD) 14895 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14896 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 14897 PrivateCopies.push_back(VDPrivateRefExpr); 14898 Inits.push_back(VDInitRefExpr); 14899 14900 // We need to add a data sharing attribute for this variable to make sure it 14901 // is correctly captured. A variable that shows up in a use_device_ptr has 14902 // similar properties of a first private variable. 14903 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14904 14905 // Create a mappable component for the list item. List items in this clause 14906 // only need a component. 14907 MVLI.VarBaseDeclarations.push_back(D); 14908 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14909 MVLI.VarComponents.back().push_back( 14910 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 14911 } 14912 14913 if (MVLI.ProcessedVarList.empty()) 14914 return nullptr; 14915 14916 return OMPUseDevicePtrClause::Create( 14917 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 14918 MVLI.VarBaseDeclarations, MVLI.VarComponents); 14919 } 14920 14921 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 14922 const OMPVarListLocTy &Locs) { 14923 MappableVarListInfo MVLI(VarList); 14924 for (Expr *RefExpr : VarList) { 14925 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 14926 SourceLocation ELoc; 14927 SourceRange ERange; 14928 Expr *SimpleRefExpr = RefExpr; 14929 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14930 if (Res.second) { 14931 // It will be analyzed later. 14932 MVLI.ProcessedVarList.push_back(RefExpr); 14933 } 14934 ValueDecl *D = Res.first; 14935 if (!D) 14936 continue; 14937 14938 QualType Type = D->getType(); 14939 // item should be a pointer or array or reference to pointer or array 14940 if (!Type.getNonReferenceType()->isPointerType() && 14941 !Type.getNonReferenceType()->isArrayType()) { 14942 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 14943 << 0 << RefExpr->getSourceRange(); 14944 continue; 14945 } 14946 14947 // Check if the declaration in the clause does not show up in any data 14948 // sharing attribute. 14949 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14950 if (isOpenMPPrivate(DVar.CKind)) { 14951 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14952 << getOpenMPClauseName(DVar.CKind) 14953 << getOpenMPClauseName(OMPC_is_device_ptr) 14954 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14955 reportOriginalDsa(*this, DSAStack, D, DVar); 14956 continue; 14957 } 14958 14959 const Expr *ConflictExpr; 14960 if (DSAStack->checkMappableExprComponentListsForDecl( 14961 D, /*CurrentRegionOnly=*/true, 14962 [&ConflictExpr]( 14963 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 14964 OpenMPClauseKind) -> bool { 14965 ConflictExpr = R.front().getAssociatedExpression(); 14966 return true; 14967 })) { 14968 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 14969 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 14970 << ConflictExpr->getSourceRange(); 14971 continue; 14972 } 14973 14974 // Store the components in the stack so that they can be used to check 14975 // against other clauses later on. 14976 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 14977 DSAStack->addMappableExpressionComponents( 14978 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 14979 14980 // Record the expression we've just processed. 14981 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 14982 14983 // Create a mappable component for the list item. List items in this clause 14984 // only need a component. We use a null declaration to signal fields in 14985 // 'this'. 14986 assert((isa<DeclRefExpr>(SimpleRefExpr) || 14987 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 14988 "Unexpected device pointer expression!"); 14989 MVLI.VarBaseDeclarations.push_back( 14990 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 14991 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14992 MVLI.VarComponents.back().push_back(MC); 14993 } 14994 14995 if (MVLI.ProcessedVarList.empty()) 14996 return nullptr; 14997 14998 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 14999 MVLI.VarBaseDeclarations, 15000 MVLI.VarComponents); 15001 } 15002 15003 OMPClause *Sema::ActOnOpenMPAllocateClause( 15004 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15005 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15006 if (Allocator) { 15007 // OpenMP [2.11.4 allocate Clause, Description] 15008 // allocator is an expression of omp_allocator_handle_t type. 15009 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15010 return nullptr; 15011 15012 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15013 if (AllocatorRes.isInvalid()) 15014 return nullptr; 15015 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15016 DSAStack->getOMPAllocatorHandleT(), 15017 Sema::AA_Initializing, 15018 /*AllowExplicit=*/true); 15019 if (AllocatorRes.isInvalid()) 15020 return nullptr; 15021 Allocator = AllocatorRes.get(); 15022 } else { 15023 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15024 // allocate clauses that appear on a target construct or on constructs in a 15025 // target region must specify an allocator expression unless a requires 15026 // directive with the dynamic_allocators clause is present in the same 15027 // compilation unit. 15028 if (LangOpts.OpenMPIsDevice && 15029 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15030 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15031 } 15032 // Analyze and build list of variables. 15033 SmallVector<Expr *, 8> Vars; 15034 for (Expr *RefExpr : VarList) { 15035 assert(RefExpr && "NULL expr in OpenMP private clause."); 15036 SourceLocation ELoc; 15037 SourceRange ERange; 15038 Expr *SimpleRefExpr = RefExpr; 15039 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15040 if (Res.second) { 15041 // It will be analyzed later. 15042 Vars.push_back(RefExpr); 15043 } 15044 ValueDecl *D = Res.first; 15045 if (!D) 15046 continue; 15047 15048 auto *VD = dyn_cast<VarDecl>(D); 15049 DeclRefExpr *Ref = nullptr; 15050 if (!VD && !CurContext->isDependentContext()) 15051 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15052 Vars.push_back((VD || CurContext->isDependentContext()) 15053 ? RefExpr->IgnoreParens() 15054 : Ref); 15055 } 15056 15057 if (Vars.empty()) 15058 return nullptr; 15059 15060 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15061 ColonLoc, EndLoc, Vars); 15062 } 15063