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) || 754 DKind == OMPD_unknown; 755 } 756 757 } // namespace 758 759 static const Expr *getExprAsWritten(const Expr *E) { 760 if (const auto *FE = dyn_cast<FullExpr>(E)) 761 E = FE->getSubExpr(); 762 763 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 764 E = MTE->GetTemporaryExpr(); 765 766 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 767 E = Binder->getSubExpr(); 768 769 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 770 E = ICE->getSubExprAsWritten(); 771 return E->IgnoreParens(); 772 } 773 774 static Expr *getExprAsWritten(Expr *E) { 775 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 776 } 777 778 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 779 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 780 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 781 D = ME->getMemberDecl(); 782 const auto *VD = dyn_cast<VarDecl>(D); 783 const auto *FD = dyn_cast<FieldDecl>(D); 784 if (VD != nullptr) { 785 VD = VD->getCanonicalDecl(); 786 D = VD; 787 } else { 788 assert(FD); 789 FD = FD->getCanonicalDecl(); 790 D = FD; 791 } 792 return D; 793 } 794 795 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 796 return const_cast<ValueDecl *>( 797 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 798 } 799 800 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 801 ValueDecl *D) const { 802 D = getCanonicalDecl(D); 803 auto *VD = dyn_cast<VarDecl>(D); 804 const auto *FD = dyn_cast<FieldDecl>(D); 805 DSAVarData DVar; 806 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 807 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 808 // in a region but not in construct] 809 // File-scope or namespace-scope variables referenced in called routines 810 // in the region are shared unless they appear in a threadprivate 811 // directive. 812 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 813 DVar.CKind = OMPC_shared; 814 815 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 816 // in a region but not in construct] 817 // Variables with static storage duration that are declared in called 818 // routines in the region are shared. 819 if (VD && VD->hasGlobalStorage()) 820 DVar.CKind = OMPC_shared; 821 822 // Non-static data members are shared by default. 823 if (FD) 824 DVar.CKind = OMPC_shared; 825 826 return DVar; 827 } 828 829 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 830 // in a Construct, C/C++, predetermined, p.1] 831 // Variables with automatic storage duration that are declared in a scope 832 // inside the construct are private. 833 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 834 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 835 DVar.CKind = OMPC_private; 836 return DVar; 837 } 838 839 DVar.DKind = Iter->Directive; 840 // Explicitly specified attributes and local variables with predetermined 841 // attributes. 842 if (Iter->SharingMap.count(D)) { 843 const DSAInfo &Data = Iter->SharingMap.lookup(D); 844 DVar.RefExpr = Data.RefExpr.getPointer(); 845 DVar.PrivateCopy = Data.PrivateCopy; 846 DVar.CKind = Data.Attributes; 847 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 848 return DVar; 849 } 850 851 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 852 // in a Construct, C/C++, implicitly determined, p.1] 853 // In a parallel or task construct, the data-sharing attributes of these 854 // variables are determined by the default clause, if present. 855 switch (Iter->DefaultAttr) { 856 case DSA_shared: 857 DVar.CKind = OMPC_shared; 858 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 859 return DVar; 860 case DSA_none: 861 return DVar; 862 case DSA_unspecified: 863 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 864 // in a Construct, implicitly determined, p.2] 865 // In a parallel construct, if no default clause is present, these 866 // variables are shared. 867 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 868 if (isOpenMPParallelDirective(DVar.DKind) || 869 isOpenMPTeamsDirective(DVar.DKind)) { 870 DVar.CKind = OMPC_shared; 871 return DVar; 872 } 873 874 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 875 // in a Construct, implicitly determined, p.4] 876 // In a task construct, if no default clause is present, a variable that in 877 // the enclosing context is determined to be shared by all implicit tasks 878 // bound to the current team is shared. 879 if (isOpenMPTaskingDirective(DVar.DKind)) { 880 DSAVarData DVarTemp; 881 iterator I = Iter, E = Stack.back().first.rend(); 882 do { 883 ++I; 884 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 885 // Referenced in a Construct, implicitly determined, p.6] 886 // In a task construct, if no default clause is present, a variable 887 // whose data-sharing attribute is not determined by the rules above is 888 // firstprivate. 889 DVarTemp = getDSA(I, D); 890 if (DVarTemp.CKind != OMPC_shared) { 891 DVar.RefExpr = nullptr; 892 DVar.CKind = OMPC_firstprivate; 893 return DVar; 894 } 895 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 896 DVar.CKind = 897 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 898 return DVar; 899 } 900 } 901 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 902 // in a Construct, implicitly determined, p.3] 903 // For constructs other than task, if no default clause is present, these 904 // variables inherit their data-sharing attributes from the enclosing 905 // context. 906 return getDSA(++Iter, D); 907 } 908 909 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 910 const Expr *NewDE) { 911 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 912 D = getCanonicalDecl(D); 913 SharingMapTy &StackElem = Stack.back().first.back(); 914 auto It = StackElem.AlignedMap.find(D); 915 if (It == StackElem.AlignedMap.end()) { 916 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 917 StackElem.AlignedMap[D] = NewDE; 918 return nullptr; 919 } 920 assert(It->second && "Unexpected nullptr expr in the aligned map"); 921 return It->second; 922 } 923 924 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 925 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 926 D = getCanonicalDecl(D); 927 SharingMapTy &StackElem = Stack.back().first.back(); 928 StackElem.LCVMap.try_emplace( 929 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 930 } 931 932 const DSAStackTy::LCDeclInfo 933 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 934 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 935 D = getCanonicalDecl(D); 936 const SharingMapTy &StackElem = Stack.back().first.back(); 937 auto It = StackElem.LCVMap.find(D); 938 if (It != StackElem.LCVMap.end()) 939 return It->second; 940 return {0, nullptr}; 941 } 942 943 const DSAStackTy::LCDeclInfo 944 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 945 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 946 "Data-sharing attributes stack is empty"); 947 D = getCanonicalDecl(D); 948 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 949 auto It = StackElem.LCVMap.find(D); 950 if (It != StackElem.LCVMap.end()) 951 return It->second; 952 return {0, nullptr}; 953 } 954 955 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 956 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 957 "Data-sharing attributes stack is empty"); 958 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 959 if (StackElem.LCVMap.size() < I) 960 return nullptr; 961 for (const auto &Pair : StackElem.LCVMap) 962 if (Pair.second.first == I) 963 return Pair.first; 964 return nullptr; 965 } 966 967 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 968 DeclRefExpr *PrivateCopy) { 969 D = getCanonicalDecl(D); 970 if (A == OMPC_threadprivate) { 971 DSAInfo &Data = Threadprivates[D]; 972 Data.Attributes = A; 973 Data.RefExpr.setPointer(E); 974 Data.PrivateCopy = nullptr; 975 } else { 976 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 977 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 978 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 979 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 980 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 981 (isLoopControlVariable(D).first && A == OMPC_private)); 982 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 983 Data.RefExpr.setInt(/*IntVal=*/true); 984 return; 985 } 986 const bool IsLastprivate = 987 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 988 Data.Attributes = A; 989 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 990 Data.PrivateCopy = PrivateCopy; 991 if (PrivateCopy) { 992 DSAInfo &Data = 993 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 994 Data.Attributes = A; 995 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 996 Data.PrivateCopy = nullptr; 997 } 998 } 999 } 1000 1001 /// Build a variable declaration for OpenMP loop iteration variable. 1002 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1003 StringRef Name, const AttrVec *Attrs = nullptr, 1004 DeclRefExpr *OrigRef = nullptr) { 1005 DeclContext *DC = SemaRef.CurContext; 1006 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1007 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1008 auto *Decl = 1009 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1010 if (Attrs) { 1011 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1012 I != E; ++I) 1013 Decl->addAttr(*I); 1014 } 1015 Decl->setImplicit(); 1016 if (OrigRef) { 1017 Decl->addAttr( 1018 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1019 } 1020 return Decl; 1021 } 1022 1023 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1024 SourceLocation Loc, 1025 bool RefersToCapture = false) { 1026 D->setReferenced(); 1027 D->markUsed(S.Context); 1028 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1029 SourceLocation(), D, RefersToCapture, Loc, Ty, 1030 VK_LValue); 1031 } 1032 1033 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1034 BinaryOperatorKind BOK) { 1035 D = getCanonicalDecl(D); 1036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1037 assert( 1038 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1039 "Additional reduction info may be specified only for reduction items."); 1040 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1041 assert(ReductionData.ReductionRange.isInvalid() && 1042 Stack.back().first.back().Directive == OMPD_taskgroup && 1043 "Additional reduction info may be specified only once for reduction " 1044 "items."); 1045 ReductionData.set(BOK, SR); 1046 Expr *&TaskgroupReductionRef = 1047 Stack.back().first.back().TaskgroupReductionRef; 1048 if (!TaskgroupReductionRef) { 1049 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1050 SemaRef.Context.VoidPtrTy, ".task_red."); 1051 TaskgroupReductionRef = 1052 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1053 } 1054 } 1055 1056 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1057 const Expr *ReductionRef) { 1058 D = getCanonicalDecl(D); 1059 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1060 assert( 1061 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1062 "Additional reduction info may be specified only for reduction items."); 1063 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1064 assert(ReductionData.ReductionRange.isInvalid() && 1065 Stack.back().first.back().Directive == OMPD_taskgroup && 1066 "Additional reduction info may be specified only once for reduction " 1067 "items."); 1068 ReductionData.set(ReductionRef, SR); 1069 Expr *&TaskgroupReductionRef = 1070 Stack.back().first.back().TaskgroupReductionRef; 1071 if (!TaskgroupReductionRef) { 1072 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1073 SemaRef.Context.VoidPtrTy, ".task_red."); 1074 TaskgroupReductionRef = 1075 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1076 } 1077 } 1078 1079 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1080 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1081 Expr *&TaskgroupDescriptor) const { 1082 D = getCanonicalDecl(D); 1083 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1084 if (Stack.back().first.empty()) 1085 return DSAVarData(); 1086 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1087 E = Stack.back().first.rend(); 1088 I != E; std::advance(I, 1)) { 1089 const DSAInfo &Data = I->SharingMap.lookup(D); 1090 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1091 continue; 1092 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1093 if (!ReductionData.ReductionOp || 1094 ReductionData.ReductionOp.is<const Expr *>()) 1095 return DSAVarData(); 1096 SR = ReductionData.ReductionRange; 1097 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1098 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1099 "expression for the descriptor is not " 1100 "set."); 1101 TaskgroupDescriptor = I->TaskgroupReductionRef; 1102 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1103 Data.PrivateCopy, I->DefaultAttrLoc); 1104 } 1105 return DSAVarData(); 1106 } 1107 1108 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1109 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1110 Expr *&TaskgroupDescriptor) const { 1111 D = getCanonicalDecl(D); 1112 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1113 if (Stack.back().first.empty()) 1114 return DSAVarData(); 1115 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1116 E = Stack.back().first.rend(); 1117 I != E; std::advance(I, 1)) { 1118 const DSAInfo &Data = I->SharingMap.lookup(D); 1119 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1120 continue; 1121 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1122 if (!ReductionData.ReductionOp || 1123 !ReductionData.ReductionOp.is<const Expr *>()) 1124 return DSAVarData(); 1125 SR = ReductionData.ReductionRange; 1126 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1127 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1128 "expression for the descriptor is not " 1129 "set."); 1130 TaskgroupDescriptor = I->TaskgroupReductionRef; 1131 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1132 Data.PrivateCopy, I->DefaultAttrLoc); 1133 } 1134 return DSAVarData(); 1135 } 1136 1137 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 1138 D = D->getCanonicalDecl(); 1139 if (!isStackEmpty()) { 1140 iterator I = Iter, E = Stack.back().first.rend(); 1141 Scope *TopScope = nullptr; 1142 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) && 1143 !isOpenMPTargetExecutionDirective(I->Directive)) 1144 ++I; 1145 if (I == E) 1146 return false; 1147 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1148 Scope *CurScope = getCurScope(); 1149 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1150 CurScope = CurScope->getParent(); 1151 return CurScope != TopScope; 1152 } 1153 return false; 1154 } 1155 1156 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1157 bool AcceptIfMutable = true, 1158 bool *IsClassType = nullptr) { 1159 ASTContext &Context = SemaRef.getASTContext(); 1160 Type = Type.getNonReferenceType().getCanonicalType(); 1161 bool IsConstant = Type.isConstant(Context); 1162 Type = Context.getBaseElementType(Type); 1163 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1164 ? Type->getAsCXXRecordDecl() 1165 : nullptr; 1166 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1167 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1168 RD = CTD->getTemplatedDecl(); 1169 if (IsClassType) 1170 *IsClassType = RD; 1171 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1172 RD->hasDefinition() && RD->hasMutableFields()); 1173 } 1174 1175 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1176 QualType Type, OpenMPClauseKind CKind, 1177 SourceLocation ELoc, 1178 bool AcceptIfMutable = true, 1179 bool ListItemNotVar = false) { 1180 ASTContext &Context = SemaRef.getASTContext(); 1181 bool IsClassType; 1182 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1183 unsigned Diag = ListItemNotVar 1184 ? diag::err_omp_const_list_item 1185 : IsClassType ? diag::err_omp_const_not_mutable_variable 1186 : diag::err_omp_const_variable; 1187 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1188 if (!ListItemNotVar && D) { 1189 const VarDecl *VD = dyn_cast<VarDecl>(D); 1190 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1191 VarDecl::DeclarationOnly; 1192 SemaRef.Diag(D->getLocation(), 1193 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1194 << D; 1195 } 1196 return true; 1197 } 1198 return false; 1199 } 1200 1201 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1202 bool FromParent) { 1203 D = getCanonicalDecl(D); 1204 DSAVarData DVar; 1205 1206 auto *VD = dyn_cast<VarDecl>(D); 1207 auto TI = Threadprivates.find(D); 1208 if (TI != Threadprivates.end()) { 1209 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1210 DVar.CKind = OMPC_threadprivate; 1211 return DVar; 1212 } 1213 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1214 DVar.RefExpr = buildDeclRefExpr( 1215 SemaRef, VD, D->getType().getNonReferenceType(), 1216 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1217 DVar.CKind = OMPC_threadprivate; 1218 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1219 return DVar; 1220 } 1221 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1222 // in a Construct, C/C++, predetermined, p.1] 1223 // Variables appearing in threadprivate directives are threadprivate. 1224 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1225 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1226 SemaRef.getLangOpts().OpenMPUseTLS && 1227 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1228 (VD && VD->getStorageClass() == SC_Register && 1229 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1230 DVar.RefExpr = buildDeclRefExpr( 1231 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1232 DVar.CKind = OMPC_threadprivate; 1233 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1234 return DVar; 1235 } 1236 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1237 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1238 !isLoopControlVariable(D).first) { 1239 iterator IterTarget = 1240 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1241 [](const SharingMapTy &Data) { 1242 return isOpenMPTargetExecutionDirective(Data.Directive); 1243 }); 1244 if (IterTarget != Stack.back().first.rend()) { 1245 iterator ParentIterTarget = std::next(IterTarget, 1); 1246 for (iterator Iter = Stack.back().first.rbegin(); 1247 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1248 if (isOpenMPLocal(VD, Iter)) { 1249 DVar.RefExpr = 1250 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1251 D->getLocation()); 1252 DVar.CKind = OMPC_threadprivate; 1253 return DVar; 1254 } 1255 } 1256 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1257 auto DSAIter = IterTarget->SharingMap.find(D); 1258 if (DSAIter != IterTarget->SharingMap.end() && 1259 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1260 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1261 DVar.CKind = OMPC_threadprivate; 1262 return DVar; 1263 } 1264 iterator End = Stack.back().first.rend(); 1265 if (!SemaRef.isOpenMPCapturedByRef( 1266 D, std::distance(ParentIterTarget, End))) { 1267 DVar.RefExpr = 1268 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1269 IterTarget->ConstructLoc); 1270 DVar.CKind = OMPC_threadprivate; 1271 return DVar; 1272 } 1273 } 1274 } 1275 } 1276 1277 if (isStackEmpty()) 1278 // Not in OpenMP execution region and top scope was already checked. 1279 return DVar; 1280 1281 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1282 // in a Construct, C/C++, predetermined, p.4] 1283 // Static data members are shared. 1284 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1285 // in a Construct, C/C++, predetermined, p.7] 1286 // Variables with static storage duration that are declared in a scope 1287 // inside the construct are shared. 1288 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1289 if (VD && VD->isStaticDataMember()) { 1290 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1291 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1292 return DVar; 1293 1294 DVar.CKind = OMPC_shared; 1295 return DVar; 1296 } 1297 1298 // The predetermined shared attribute for const-qualified types having no 1299 // mutable members was removed after OpenMP 3.1. 1300 if (SemaRef.LangOpts.OpenMP <= 31) { 1301 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1302 // in a Construct, C/C++, predetermined, p.6] 1303 // Variables with const qualified type having no mutable member are 1304 // shared. 1305 if (isConstNotMutableType(SemaRef, D->getType())) { 1306 // Variables with const-qualified type having no mutable member may be 1307 // listed in a firstprivate clause, even if they are static data members. 1308 DSAVarData DVarTemp = hasInnermostDSA( 1309 D, 1310 [](OpenMPClauseKind C) { 1311 return C == OMPC_firstprivate || C == OMPC_shared; 1312 }, 1313 MatchesAlways, FromParent); 1314 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1315 return DVarTemp; 1316 1317 DVar.CKind = OMPC_shared; 1318 return DVar; 1319 } 1320 } 1321 1322 // Explicitly specified attributes and local variables with predetermined 1323 // attributes. 1324 iterator I = Stack.back().first.rbegin(); 1325 iterator EndI = Stack.back().first.rend(); 1326 if (FromParent && I != EndI) 1327 std::advance(I, 1); 1328 auto It = I->SharingMap.find(D); 1329 if (It != I->SharingMap.end()) { 1330 const DSAInfo &Data = It->getSecond(); 1331 DVar.RefExpr = Data.RefExpr.getPointer(); 1332 DVar.PrivateCopy = Data.PrivateCopy; 1333 DVar.CKind = Data.Attributes; 1334 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1335 DVar.DKind = I->Directive; 1336 } 1337 1338 return DVar; 1339 } 1340 1341 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1342 bool FromParent) const { 1343 if (isStackEmpty()) { 1344 iterator I; 1345 return getDSA(I, D); 1346 } 1347 D = getCanonicalDecl(D); 1348 iterator StartI = Stack.back().first.rbegin(); 1349 iterator EndI = Stack.back().first.rend(); 1350 if (FromParent && StartI != EndI) 1351 std::advance(StartI, 1); 1352 return getDSA(StartI, D); 1353 } 1354 1355 const DSAStackTy::DSAVarData 1356 DSAStackTy::hasDSA(ValueDecl *D, 1357 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1358 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1359 bool FromParent) const { 1360 if (isStackEmpty()) 1361 return {}; 1362 D = getCanonicalDecl(D); 1363 iterator I = Stack.back().first.rbegin(); 1364 iterator EndI = Stack.back().first.rend(); 1365 if (FromParent && I != EndI) 1366 std::advance(I, 1); 1367 for (; I != EndI; std::advance(I, 1)) { 1368 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive)) 1369 continue; 1370 iterator NewI = I; 1371 DSAVarData DVar = getDSA(NewI, D); 1372 if (I == NewI && CPred(DVar.CKind)) 1373 return DVar; 1374 } 1375 return {}; 1376 } 1377 1378 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1379 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1380 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1381 bool FromParent) const { 1382 if (isStackEmpty()) 1383 return {}; 1384 D = getCanonicalDecl(D); 1385 iterator StartI = Stack.back().first.rbegin(); 1386 iterator EndI = Stack.back().first.rend(); 1387 if (FromParent && StartI != EndI) 1388 std::advance(StartI, 1); 1389 if (StartI == EndI || !DPred(StartI->Directive)) 1390 return {}; 1391 iterator NewI = StartI; 1392 DSAVarData DVar = getDSA(NewI, D); 1393 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1394 } 1395 1396 bool DSAStackTy::hasExplicitDSA( 1397 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1398 unsigned Level, bool NotLastprivate) const { 1399 if (isStackEmpty()) 1400 return false; 1401 D = getCanonicalDecl(D); 1402 auto StartI = Stack.back().first.begin(); 1403 auto EndI = Stack.back().first.end(); 1404 if (std::distance(StartI, EndI) <= (int)Level) 1405 return false; 1406 std::advance(StartI, Level); 1407 auto I = StartI->SharingMap.find(D); 1408 if ((I != StartI->SharingMap.end()) && 1409 I->getSecond().RefExpr.getPointer() && 1410 CPred(I->getSecond().Attributes) && 1411 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1412 return true; 1413 // Check predetermined rules for the loop control variables. 1414 auto LI = StartI->LCVMap.find(D); 1415 if (LI != StartI->LCVMap.end()) 1416 return CPred(OMPC_private); 1417 return false; 1418 } 1419 1420 bool DSAStackTy::hasExplicitDirective( 1421 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1422 unsigned Level) const { 1423 if (isStackEmpty()) 1424 return false; 1425 auto StartI = Stack.back().first.begin(); 1426 auto EndI = Stack.back().first.end(); 1427 if (std::distance(StartI, EndI) <= (int)Level) 1428 return false; 1429 std::advance(StartI, Level); 1430 return DPred(StartI->Directive); 1431 } 1432 1433 bool DSAStackTy::hasDirective( 1434 const llvm::function_ref<bool(OpenMPDirectiveKind, 1435 const DeclarationNameInfo &, SourceLocation)> 1436 DPred, 1437 bool FromParent) const { 1438 // We look only in the enclosing region. 1439 if (isStackEmpty()) 1440 return false; 1441 auto StartI = std::next(Stack.back().first.rbegin()); 1442 auto EndI = Stack.back().first.rend(); 1443 if (FromParent && StartI != EndI) 1444 StartI = std::next(StartI); 1445 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1446 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1447 return true; 1448 } 1449 return false; 1450 } 1451 1452 void Sema::InitDataSharingAttributesStack() { 1453 VarDataSharingAttributesStack = new DSAStackTy(*this); 1454 } 1455 1456 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1457 1458 void Sema::pushOpenMPFunctionRegion() { 1459 DSAStack->pushFunction(); 1460 } 1461 1462 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1463 DSAStack->popFunction(OldFSI); 1464 } 1465 1466 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1467 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1468 "Expected OpenMP device compilation."); 1469 return !S.isInOpenMPTargetExecutionDirective() && 1470 !S.isInOpenMPDeclareTargetContext(); 1471 } 1472 1473 /// Do we know that we will eventually codegen the given function? 1474 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1475 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1476 "Expected OpenMP device compilation."); 1477 // Templates are emitted when they're instantiated. 1478 if (FD->isDependentContext()) 1479 return false; 1480 1481 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1482 FD->getCanonicalDecl())) 1483 return true; 1484 1485 // Otherwise, the function is known-emitted if it's in our set of 1486 // known-emitted functions. 1487 return S.DeviceKnownEmittedFns.count(FD) > 0; 1488 } 1489 1490 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1491 unsigned DiagID) { 1492 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1493 "Expected OpenMP device compilation."); 1494 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1495 !isKnownEmitted(*this, getCurFunctionDecl())) 1496 ? DeviceDiagBuilder::K_Deferred 1497 : DeviceDiagBuilder::K_Immediate, 1498 Loc, DiagID, getCurFunctionDecl(), *this); 1499 } 1500 1501 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1502 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1503 "Expected OpenMP device compilation."); 1504 assert(Callee && "Callee may not be null."); 1505 FunctionDecl *Caller = getCurFunctionDecl(); 1506 1507 // If the caller is known-emitted, mark the callee as known-emitted. 1508 // Otherwise, mark the call in our call graph so we can traverse it later. 1509 if (!isOpenMPDeviceDelayedContext(*this) || 1510 (Caller && isKnownEmitted(*this, Caller))) 1511 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1512 else if (Caller) 1513 DeviceCallGraph[Caller].insert({Callee, Loc}); 1514 } 1515 1516 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1517 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1518 "OpenMP device compilation mode is expected."); 1519 QualType Ty = E->getType(); 1520 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1521 (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) || 1522 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1523 !Context.getTargetInfo().hasInt128Type())) 1524 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1525 << Ty << E->getSourceRange(); 1526 } 1527 1528 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1529 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1530 1531 ASTContext &Ctx = getASTContext(); 1532 bool IsByRef = true; 1533 1534 // Find the directive that is associated with the provided scope. 1535 D = cast<ValueDecl>(D->getCanonicalDecl()); 1536 QualType Ty = D->getType(); 1537 1538 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1539 // This table summarizes how a given variable should be passed to the device 1540 // given its type and the clauses where it appears. This table is based on 1541 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1542 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1543 // 1544 // ========================================================================= 1545 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1546 // | |(tofrom:scalar)| | pvt | | | | 1547 // ========================================================================= 1548 // | scl | | | | - | | bycopy| 1549 // | scl | | - | x | - | - | bycopy| 1550 // | scl | | x | - | - | - | null | 1551 // | scl | x | | | - | | byref | 1552 // | scl | x | - | x | - | - | bycopy| 1553 // | scl | x | x | - | - | - | null | 1554 // | scl | | - | - | - | x | byref | 1555 // | scl | x | - | - | - | x | byref | 1556 // 1557 // | agg | n.a. | | | - | | byref | 1558 // | agg | n.a. | - | x | - | - | byref | 1559 // | agg | n.a. | x | - | - | - | null | 1560 // | agg | n.a. | - | - | - | x | byref | 1561 // | agg | n.a. | - | - | - | x[] | byref | 1562 // 1563 // | ptr | n.a. | | | - | | bycopy| 1564 // | ptr | n.a. | - | x | - | - | bycopy| 1565 // | ptr | n.a. | x | - | - | - | null | 1566 // | ptr | n.a. | - | - | - | x | byref | 1567 // | ptr | n.a. | - | - | - | x[] | bycopy| 1568 // | ptr | n.a. | - | - | x | | bycopy| 1569 // | ptr | n.a. | - | - | x | x | bycopy| 1570 // | ptr | n.a. | - | - | x | x[] | bycopy| 1571 // ========================================================================= 1572 // Legend: 1573 // scl - scalar 1574 // ptr - pointer 1575 // agg - aggregate 1576 // x - applies 1577 // - - invalid in this combination 1578 // [] - mapped with an array section 1579 // byref - should be mapped by reference 1580 // byval - should be mapped by value 1581 // null - initialize a local variable to null on the device 1582 // 1583 // Observations: 1584 // - All scalar declarations that show up in a map clause have to be passed 1585 // by reference, because they may have been mapped in the enclosing data 1586 // environment. 1587 // - If the scalar value does not fit the size of uintptr, it has to be 1588 // passed by reference, regardless the result in the table above. 1589 // - For pointers mapped by value that have either an implicit map or an 1590 // array section, the runtime library may pass the NULL value to the 1591 // device instead of the value passed to it by the compiler. 1592 1593 if (Ty->isReferenceType()) 1594 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1595 1596 // Locate map clauses and see if the variable being captured is referred to 1597 // in any of those clauses. Here we only care about variables, not fields, 1598 // because fields are part of aggregates. 1599 bool IsVariableUsedInMapClause = false; 1600 bool IsVariableAssociatedWithSection = false; 1601 1602 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1603 D, Level, 1604 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1605 OMPClauseMappableExprCommon::MappableExprComponentListRef 1606 MapExprComponents, 1607 OpenMPClauseKind WhereFoundClauseKind) { 1608 // Only the map clause information influences how a variable is 1609 // captured. E.g. is_device_ptr does not require changing the default 1610 // behavior. 1611 if (WhereFoundClauseKind != OMPC_map) 1612 return false; 1613 1614 auto EI = MapExprComponents.rbegin(); 1615 auto EE = MapExprComponents.rend(); 1616 1617 assert(EI != EE && "Invalid map expression!"); 1618 1619 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1620 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1621 1622 ++EI; 1623 if (EI == EE) 1624 return false; 1625 1626 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1627 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1628 isa<MemberExpr>(EI->getAssociatedExpression())) { 1629 IsVariableAssociatedWithSection = true; 1630 // There is nothing more we need to know about this variable. 1631 return true; 1632 } 1633 1634 // Keep looking for more map info. 1635 return false; 1636 }); 1637 1638 if (IsVariableUsedInMapClause) { 1639 // If variable is identified in a map clause it is always captured by 1640 // reference except if it is a pointer that is dereferenced somehow. 1641 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1642 } else { 1643 // By default, all the data that has a scalar type is mapped by copy 1644 // (except for reduction variables). 1645 IsByRef = 1646 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1647 !Ty->isAnyPointerType()) || 1648 !Ty->isScalarType() || 1649 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1650 DSAStack->hasExplicitDSA( 1651 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1652 } 1653 } 1654 1655 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1656 IsByRef = 1657 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1658 !Ty->isAnyPointerType()) || 1659 !DSAStack->hasExplicitDSA( 1660 D, 1661 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1662 Level, /*NotLastprivate=*/true)) && 1663 // If the variable is artificial and must be captured by value - try to 1664 // capture by value. 1665 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1666 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1667 } 1668 1669 // When passing data by copy, we need to make sure it fits the uintptr size 1670 // and alignment, because the runtime library only deals with uintptr types. 1671 // If it does not fit the uintptr size, we need to pass the data by reference 1672 // instead. 1673 if (!IsByRef && 1674 (Ctx.getTypeSizeInChars(Ty) > 1675 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1676 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1677 IsByRef = true; 1678 } 1679 1680 return IsByRef; 1681 } 1682 1683 unsigned Sema::getOpenMPNestingLevel() const { 1684 assert(getLangOpts().OpenMP); 1685 return DSAStack->getNestingLevel(); 1686 } 1687 1688 bool Sema::isInOpenMPTargetExecutionDirective() const { 1689 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1690 !DSAStack->isClauseParsingMode()) || 1691 DSAStack->hasDirective( 1692 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1693 SourceLocation) -> bool { 1694 return isOpenMPTargetExecutionDirective(K); 1695 }, 1696 false); 1697 } 1698 1699 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1700 unsigned StopAt) { 1701 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1702 D = getCanonicalDecl(D); 1703 1704 // If we are attempting to capture a global variable in a directive with 1705 // 'target' we return true so that this global is also mapped to the device. 1706 // 1707 auto *VD = dyn_cast<VarDecl>(D); 1708 if (VD && !VD->hasLocalStorage()) { 1709 if (isInOpenMPDeclareTargetContext() && 1710 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1711 // Try to mark variable as declare target if it is used in capturing 1712 // regions. 1713 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1714 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1715 return nullptr; 1716 } else if (isInOpenMPTargetExecutionDirective()) { 1717 // If the declaration is enclosed in a 'declare target' directive, 1718 // then it should not be captured. 1719 // 1720 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1721 return nullptr; 1722 return VD; 1723 } 1724 } 1725 // Capture variables captured by reference in lambdas for target-based 1726 // directives. 1727 if (VD && !DSAStack->isClauseParsingMode()) { 1728 if (const auto *RD = VD->getType() 1729 .getCanonicalType() 1730 .getNonReferenceType() 1731 ->getAsCXXRecordDecl()) { 1732 bool SavedForceCaptureByReferenceInTargetExecutable = 1733 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1734 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1735 if (RD->isLambda()) { 1736 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1737 FieldDecl *ThisCapture; 1738 RD->getCaptureFields(Captures, ThisCapture); 1739 for (const LambdaCapture &LC : RD->captures()) { 1740 if (LC.getCaptureKind() == LCK_ByRef) { 1741 VarDecl *VD = LC.getCapturedVar(); 1742 DeclContext *VDC = VD->getDeclContext(); 1743 if (!VDC->Encloses(CurContext)) 1744 continue; 1745 DSAStackTy::DSAVarData DVarPrivate = 1746 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1747 // Do not capture already captured variables. 1748 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1749 DVarPrivate.CKind == OMPC_unknown && 1750 !DSAStack->checkMappableExprComponentListsForDecl( 1751 D, /*CurrentRegionOnly=*/true, 1752 [](OMPClauseMappableExprCommon:: 1753 MappableExprComponentListRef, 1754 OpenMPClauseKind) { return true; })) 1755 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1756 } else if (LC.getCaptureKind() == LCK_This) { 1757 QualType ThisTy = getCurrentThisType(); 1758 if (!ThisTy.isNull() && 1759 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1760 CheckCXXThisCapture(LC.getLocation()); 1761 } 1762 } 1763 } 1764 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1765 SavedForceCaptureByReferenceInTargetExecutable); 1766 } 1767 } 1768 1769 if (CheckScopeInfo) { 1770 bool OpenMPFound = false; 1771 for (unsigned I = StopAt + 1; I > 0; --I) { 1772 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1773 if(!isa<CapturingScopeInfo>(FSI)) 1774 return nullptr; 1775 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1776 if (RSI->CapRegionKind == CR_OpenMP) { 1777 OpenMPFound = true; 1778 break; 1779 } 1780 } 1781 if (!OpenMPFound) 1782 return nullptr; 1783 } 1784 1785 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1786 (!DSAStack->isClauseParsingMode() || 1787 DSAStack->getParentDirective() != OMPD_unknown)) { 1788 auto &&Info = DSAStack->isLoopControlVariable(D); 1789 if (Info.first || 1790 (VD && VD->hasLocalStorage() && 1791 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1792 (VD && DSAStack->isForceVarCapturing())) 1793 return VD ? VD : Info.second; 1794 DSAStackTy::DSAVarData DVarPrivate = 1795 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1796 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1797 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1798 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1799 [](OpenMPDirectiveKind) { return true; }, 1800 DSAStack->isClauseParsingMode()); 1801 // The variable is not private or it is the variable in the directive with 1802 // default(none) clause and not used in any clause. 1803 if (DVarPrivate.CKind != OMPC_unknown || 1804 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1805 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1806 } 1807 return nullptr; 1808 } 1809 1810 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1811 unsigned Level) const { 1812 SmallVector<OpenMPDirectiveKind, 4> Regions; 1813 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1814 FunctionScopesIndex -= Regions.size(); 1815 } 1816 1817 void Sema::startOpenMPLoop() { 1818 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1819 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1820 DSAStack->loopInit(); 1821 } 1822 1823 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1824 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1825 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1826 if (DSAStack->getAssociatedLoops() > 0 && 1827 !DSAStack->isLoopStarted()) { 1828 DSAStack->resetPossibleLoopCounter(D); 1829 DSAStack->loopStart(); 1830 return true; 1831 } 1832 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1833 DSAStack->isLoopControlVariable(D).first) && 1834 !DSAStack->hasExplicitDSA( 1835 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1836 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1837 return true; 1838 } 1839 return DSAStack->hasExplicitDSA( 1840 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1841 (DSAStack->isClauseParsingMode() && 1842 DSAStack->getClauseParsingMode() == OMPC_private) || 1843 // Consider taskgroup reduction descriptor variable a private to avoid 1844 // possible capture in the region. 1845 (DSAStack->hasExplicitDirective( 1846 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1847 Level) && 1848 DSAStack->isTaskgroupReductionRef(D, Level)); 1849 } 1850 1851 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1852 unsigned Level) { 1853 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1854 D = getCanonicalDecl(D); 1855 OpenMPClauseKind OMPC = OMPC_unknown; 1856 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1857 const unsigned NewLevel = I - 1; 1858 if (DSAStack->hasExplicitDSA(D, 1859 [&OMPC](const OpenMPClauseKind K) { 1860 if (isOpenMPPrivate(K)) { 1861 OMPC = K; 1862 return true; 1863 } 1864 return false; 1865 }, 1866 NewLevel)) 1867 break; 1868 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1869 D, NewLevel, 1870 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1871 OpenMPClauseKind) { return true; })) { 1872 OMPC = OMPC_map; 1873 break; 1874 } 1875 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1876 NewLevel)) { 1877 OMPC = OMPC_map; 1878 if (D->getType()->isScalarType() && 1879 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1880 DefaultMapAttributes::DMA_tofrom_scalar) 1881 OMPC = OMPC_firstprivate; 1882 break; 1883 } 1884 } 1885 if (OMPC != OMPC_unknown) 1886 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1887 } 1888 1889 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1890 unsigned Level) const { 1891 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1892 // Return true if the current level is no longer enclosed in a target region. 1893 1894 const auto *VD = dyn_cast<VarDecl>(D); 1895 return VD && !VD->hasLocalStorage() && 1896 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1897 Level); 1898 } 1899 1900 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1901 1902 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1903 const DeclarationNameInfo &DirName, 1904 Scope *CurScope, SourceLocation Loc) { 1905 DSAStack->push(DKind, DirName, CurScope, Loc); 1906 PushExpressionEvaluationContext( 1907 ExpressionEvaluationContext::PotentiallyEvaluated); 1908 } 1909 1910 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1911 DSAStack->setClauseParsingMode(K); 1912 } 1913 1914 void Sema::EndOpenMPClause() { 1915 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1916 } 1917 1918 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1919 ArrayRef<OMPClause *> Clauses); 1920 1921 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1922 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1923 // A variable of class type (or array thereof) that appears in a lastprivate 1924 // clause requires an accessible, unambiguous default constructor for the 1925 // class type, unless the list item is also specified in a firstprivate 1926 // clause. 1927 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1928 for (OMPClause *C : D->clauses()) { 1929 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1930 SmallVector<Expr *, 8> PrivateCopies; 1931 for (Expr *DE : Clause->varlists()) { 1932 if (DE->isValueDependent() || DE->isTypeDependent()) { 1933 PrivateCopies.push_back(nullptr); 1934 continue; 1935 } 1936 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1937 auto *VD = cast<VarDecl>(DRE->getDecl()); 1938 QualType Type = VD->getType().getNonReferenceType(); 1939 const DSAStackTy::DSAVarData DVar = 1940 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1941 if (DVar.CKind == OMPC_lastprivate) { 1942 // Generate helper private variable and initialize it with the 1943 // default value. The address of the original variable is replaced 1944 // by the address of the new private variable in CodeGen. This new 1945 // variable is not added to IdResolver, so the code in the OpenMP 1946 // region uses original variable for proper diagnostics. 1947 VarDecl *VDPrivate = buildVarDecl( 1948 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1949 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1950 ActOnUninitializedDecl(VDPrivate); 1951 if (VDPrivate->isInvalidDecl()) { 1952 PrivateCopies.push_back(nullptr); 1953 continue; 1954 } 1955 PrivateCopies.push_back(buildDeclRefExpr( 1956 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1957 } else { 1958 // The variable is also a firstprivate, so initialization sequence 1959 // for private copy is generated already. 1960 PrivateCopies.push_back(nullptr); 1961 } 1962 } 1963 Clause->setPrivateCopies(PrivateCopies); 1964 } 1965 } 1966 // Check allocate clauses. 1967 if (!CurContext->isDependentContext()) 1968 checkAllocateClauses(*this, DSAStack, D->clauses()); 1969 } 1970 1971 DSAStack->pop(); 1972 DiscardCleanupsInEvaluationContext(); 1973 PopExpressionEvaluationContext(); 1974 } 1975 1976 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1977 Expr *NumIterations, Sema &SemaRef, 1978 Scope *S, DSAStackTy *Stack); 1979 1980 namespace { 1981 1982 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1983 private: 1984 Sema &SemaRef; 1985 1986 public: 1987 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1988 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1989 NamedDecl *ND = Candidate.getCorrectionDecl(); 1990 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1991 return VD->hasGlobalStorage() && 1992 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1993 SemaRef.getCurScope()); 1994 } 1995 return false; 1996 } 1997 1998 std::unique_ptr<CorrectionCandidateCallback> clone() override { 1999 return llvm::make_unique<VarDeclFilterCCC>(*this); 2000 } 2001 2002 }; 2003 2004 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2005 private: 2006 Sema &SemaRef; 2007 2008 public: 2009 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2010 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2011 NamedDecl *ND = Candidate.getCorrectionDecl(); 2012 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2013 isa<FunctionDecl>(ND))) { 2014 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2015 SemaRef.getCurScope()); 2016 } 2017 return false; 2018 } 2019 2020 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2021 return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this); 2022 } 2023 }; 2024 2025 } // namespace 2026 2027 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2028 CXXScopeSpec &ScopeSpec, 2029 const DeclarationNameInfo &Id, 2030 OpenMPDirectiveKind Kind) { 2031 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2032 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2033 2034 if (Lookup.isAmbiguous()) 2035 return ExprError(); 2036 2037 VarDecl *VD; 2038 if (!Lookup.isSingleResult()) { 2039 VarDeclFilterCCC CCC(*this); 2040 if (TypoCorrection Corrected = 2041 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2042 CTK_ErrorRecovery)) { 2043 diagnoseTypo(Corrected, 2044 PDiag(Lookup.empty() 2045 ? diag::err_undeclared_var_use_suggest 2046 : diag::err_omp_expected_var_arg_suggest) 2047 << Id.getName()); 2048 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2049 } else { 2050 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2051 : diag::err_omp_expected_var_arg) 2052 << Id.getName(); 2053 return ExprError(); 2054 } 2055 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2056 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2057 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2058 return ExprError(); 2059 } 2060 Lookup.suppressDiagnostics(); 2061 2062 // OpenMP [2.9.2, Syntax, C/C++] 2063 // Variables must be file-scope, namespace-scope, or static block-scope. 2064 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2065 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2066 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2067 bool IsDecl = 2068 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2069 Diag(VD->getLocation(), 2070 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2071 << VD; 2072 return ExprError(); 2073 } 2074 2075 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2076 NamedDecl *ND = CanonicalVD; 2077 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2078 // A threadprivate directive for file-scope variables must appear outside 2079 // any definition or declaration. 2080 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2081 !getCurLexicalContext()->isTranslationUnit()) { 2082 Diag(Id.getLoc(), diag::err_omp_var_scope) 2083 << getOpenMPDirectiveName(Kind) << VD; 2084 bool IsDecl = 2085 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2086 Diag(VD->getLocation(), 2087 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2088 << VD; 2089 return ExprError(); 2090 } 2091 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2092 // A threadprivate directive for static class member variables must appear 2093 // in the class definition, in the same scope in which the member 2094 // variables are declared. 2095 if (CanonicalVD->isStaticDataMember() && 2096 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2097 Diag(Id.getLoc(), diag::err_omp_var_scope) 2098 << getOpenMPDirectiveName(Kind) << VD; 2099 bool IsDecl = 2100 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2101 Diag(VD->getLocation(), 2102 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2103 << VD; 2104 return ExprError(); 2105 } 2106 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2107 // A threadprivate directive for namespace-scope variables must appear 2108 // outside any definition or declaration other than the namespace 2109 // definition itself. 2110 if (CanonicalVD->getDeclContext()->isNamespace() && 2111 (!getCurLexicalContext()->isFileContext() || 2112 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2113 Diag(Id.getLoc(), diag::err_omp_var_scope) 2114 << getOpenMPDirectiveName(Kind) << VD; 2115 bool IsDecl = 2116 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2117 Diag(VD->getLocation(), 2118 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2119 << VD; 2120 return ExprError(); 2121 } 2122 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2123 // A threadprivate directive for static block-scope variables must appear 2124 // in the scope of the variable and not in a nested scope. 2125 if (CanonicalVD->isLocalVarDecl() && CurScope && 2126 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2127 Diag(Id.getLoc(), diag::err_omp_var_scope) 2128 << getOpenMPDirectiveName(Kind) << VD; 2129 bool IsDecl = 2130 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2131 Diag(VD->getLocation(), 2132 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2133 << VD; 2134 return ExprError(); 2135 } 2136 2137 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2138 // A threadprivate directive must lexically precede all references to any 2139 // of the variables in its list. 2140 if (Kind == OMPD_threadprivate && VD->isUsed() && 2141 !DSAStack->isThreadPrivate(VD)) { 2142 Diag(Id.getLoc(), diag::err_omp_var_used) 2143 << getOpenMPDirectiveName(Kind) << VD; 2144 return ExprError(); 2145 } 2146 2147 QualType ExprType = VD->getType().getNonReferenceType(); 2148 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2149 SourceLocation(), VD, 2150 /*RefersToEnclosingVariableOrCapture=*/false, 2151 Id.getLoc(), ExprType, VK_LValue); 2152 } 2153 2154 Sema::DeclGroupPtrTy 2155 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2156 ArrayRef<Expr *> VarList) { 2157 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2158 CurContext->addDecl(D); 2159 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2160 } 2161 return nullptr; 2162 } 2163 2164 namespace { 2165 class LocalVarRefChecker final 2166 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2167 Sema &SemaRef; 2168 2169 public: 2170 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2171 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2172 if (VD->hasLocalStorage()) { 2173 SemaRef.Diag(E->getBeginLoc(), 2174 diag::err_omp_local_var_in_threadprivate_init) 2175 << E->getSourceRange(); 2176 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2177 << VD << VD->getSourceRange(); 2178 return true; 2179 } 2180 } 2181 return false; 2182 } 2183 bool VisitStmt(const Stmt *S) { 2184 for (const Stmt *Child : S->children()) { 2185 if (Child && Visit(Child)) 2186 return true; 2187 } 2188 return false; 2189 } 2190 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2191 }; 2192 } // namespace 2193 2194 OMPThreadPrivateDecl * 2195 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2196 SmallVector<Expr *, 8> Vars; 2197 for (Expr *RefExpr : VarList) { 2198 auto *DE = cast<DeclRefExpr>(RefExpr); 2199 auto *VD = cast<VarDecl>(DE->getDecl()); 2200 SourceLocation ILoc = DE->getExprLoc(); 2201 2202 // Mark variable as used. 2203 VD->setReferenced(); 2204 VD->markUsed(Context); 2205 2206 QualType QType = VD->getType(); 2207 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2208 // It will be analyzed later. 2209 Vars.push_back(DE); 2210 continue; 2211 } 2212 2213 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2214 // A threadprivate variable must not have an incomplete type. 2215 if (RequireCompleteType(ILoc, VD->getType(), 2216 diag::err_omp_threadprivate_incomplete_type)) { 2217 continue; 2218 } 2219 2220 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2221 // A threadprivate variable must not have a reference type. 2222 if (VD->getType()->isReferenceType()) { 2223 Diag(ILoc, diag::err_omp_ref_type_arg) 2224 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2225 bool IsDecl = 2226 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2227 Diag(VD->getLocation(), 2228 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2229 << VD; 2230 continue; 2231 } 2232 2233 // Check if this is a TLS variable. If TLS is not being supported, produce 2234 // the corresponding diagnostic. 2235 if ((VD->getTLSKind() != VarDecl::TLS_None && 2236 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2237 getLangOpts().OpenMPUseTLS && 2238 getASTContext().getTargetInfo().isTLSSupported())) || 2239 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2240 !VD->isLocalVarDecl())) { 2241 Diag(ILoc, diag::err_omp_var_thread_local) 2242 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2243 bool IsDecl = 2244 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2245 Diag(VD->getLocation(), 2246 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2247 << VD; 2248 continue; 2249 } 2250 2251 // Check if initial value of threadprivate variable reference variable with 2252 // local storage (it is not supported by runtime). 2253 if (const Expr *Init = VD->getAnyInitializer()) { 2254 LocalVarRefChecker Checker(*this); 2255 if (Checker.Visit(Init)) 2256 continue; 2257 } 2258 2259 Vars.push_back(RefExpr); 2260 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2261 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2262 Context, SourceRange(Loc, Loc))); 2263 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2264 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2265 } 2266 OMPThreadPrivateDecl *D = nullptr; 2267 if (!Vars.empty()) { 2268 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2269 Vars); 2270 D->setAccess(AS_public); 2271 } 2272 return D; 2273 } 2274 2275 static OMPAllocateDeclAttr::AllocatorTypeTy 2276 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2277 if (!Allocator) 2278 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2279 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2280 Allocator->isInstantiationDependent() || 2281 Allocator->containsUnexpandedParameterPack()) 2282 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2283 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2284 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2285 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2286 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2287 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2288 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2289 llvm::FoldingSetNodeID AEId, DAEId; 2290 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2291 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2292 if (AEId == DAEId) { 2293 AllocatorKindRes = AllocatorKind; 2294 break; 2295 } 2296 } 2297 return AllocatorKindRes; 2298 } 2299 2300 static bool checkPreviousOMPAllocateAttribute( 2301 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2302 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2303 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2304 return false; 2305 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2306 Expr *PrevAllocator = A->getAllocator(); 2307 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2308 getAllocatorKind(S, Stack, PrevAllocator); 2309 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2310 if (AllocatorsMatch && 2311 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2312 Allocator && PrevAllocator) { 2313 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2314 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2315 llvm::FoldingSetNodeID AEId, PAEId; 2316 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2317 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2318 AllocatorsMatch = AEId == PAEId; 2319 } 2320 if (!AllocatorsMatch) { 2321 SmallString<256> AllocatorBuffer; 2322 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2323 if (Allocator) 2324 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2325 SmallString<256> PrevAllocatorBuffer; 2326 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2327 if (PrevAllocator) 2328 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2329 S.getPrintingPolicy()); 2330 2331 SourceLocation AllocatorLoc = 2332 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2333 SourceRange AllocatorRange = 2334 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2335 SourceLocation PrevAllocatorLoc = 2336 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2337 SourceRange PrevAllocatorRange = 2338 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2339 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2340 << (Allocator ? 1 : 0) << AllocatorStream.str() 2341 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2342 << AllocatorRange; 2343 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2344 << PrevAllocatorRange; 2345 return true; 2346 } 2347 return false; 2348 } 2349 2350 static void 2351 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2352 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2353 Expr *Allocator, SourceRange SR) { 2354 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2355 return; 2356 if (Allocator && 2357 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2358 Allocator->isInstantiationDependent() || 2359 Allocator->containsUnexpandedParameterPack())) 2360 return; 2361 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2362 Allocator, SR); 2363 VD->addAttr(A); 2364 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2365 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2366 } 2367 2368 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2369 SourceLocation Loc, ArrayRef<Expr *> VarList, 2370 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2371 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2372 Expr *Allocator = nullptr; 2373 if (Clauses.empty()) { 2374 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2375 // allocate directives that appear in a target region must specify an 2376 // allocator clause unless a requires directive with the dynamic_allocators 2377 // clause is present in the same compilation unit. 2378 if (LangOpts.OpenMPIsDevice && 2379 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2380 targetDiag(Loc, diag::err_expected_allocator_clause); 2381 } else { 2382 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2383 } 2384 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2385 getAllocatorKind(*this, DSAStack, Allocator); 2386 SmallVector<Expr *, 8> Vars; 2387 for (Expr *RefExpr : VarList) { 2388 auto *DE = cast<DeclRefExpr>(RefExpr); 2389 auto *VD = cast<VarDecl>(DE->getDecl()); 2390 2391 // Check if this is a TLS variable or global register. 2392 if (VD->getTLSKind() != VarDecl::TLS_None || 2393 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2394 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2395 !VD->isLocalVarDecl())) 2396 continue; 2397 2398 // If the used several times in the allocate directive, the same allocator 2399 // must be used. 2400 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2401 AllocatorKind, Allocator)) 2402 continue; 2403 2404 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2405 // If a list item has a static storage type, the allocator expression in the 2406 // allocator clause must be a constant expression that evaluates to one of 2407 // the predefined memory allocator values. 2408 if (Allocator && VD->hasGlobalStorage()) { 2409 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2410 Diag(Allocator->getExprLoc(), 2411 diag::err_omp_expected_predefined_allocator) 2412 << Allocator->getSourceRange(); 2413 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2414 VarDecl::DeclarationOnly; 2415 Diag(VD->getLocation(), 2416 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2417 << VD; 2418 continue; 2419 } 2420 } 2421 2422 Vars.push_back(RefExpr); 2423 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2424 DE->getSourceRange()); 2425 } 2426 if (Vars.empty()) 2427 return nullptr; 2428 if (!Owner) 2429 Owner = getCurLexicalContext(); 2430 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2431 D->setAccess(AS_public); 2432 Owner->addDecl(D); 2433 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2434 } 2435 2436 Sema::DeclGroupPtrTy 2437 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2438 ArrayRef<OMPClause *> ClauseList) { 2439 OMPRequiresDecl *D = nullptr; 2440 if (!CurContext->isFileContext()) { 2441 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2442 } else { 2443 D = CheckOMPRequiresDecl(Loc, ClauseList); 2444 if (D) { 2445 CurContext->addDecl(D); 2446 DSAStack->addRequiresDecl(D); 2447 } 2448 } 2449 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2450 } 2451 2452 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2453 ArrayRef<OMPClause *> ClauseList) { 2454 /// For target specific clauses, the requires directive cannot be 2455 /// specified after the handling of any of the target regions in the 2456 /// current compilation unit. 2457 ArrayRef<SourceLocation> TargetLocations = 2458 DSAStack->getEncounteredTargetLocs(); 2459 if (!TargetLocations.empty()) { 2460 for (const OMPClause *CNew : ClauseList) { 2461 // Check if any of the requires clauses affect target regions. 2462 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2463 isa<OMPUnifiedAddressClause>(CNew) || 2464 isa<OMPReverseOffloadClause>(CNew) || 2465 isa<OMPDynamicAllocatorsClause>(CNew)) { 2466 Diag(Loc, diag::err_omp_target_before_requires) 2467 << getOpenMPClauseName(CNew->getClauseKind()); 2468 for (SourceLocation TargetLoc : TargetLocations) { 2469 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2470 } 2471 } 2472 } 2473 } 2474 2475 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2476 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2477 ClauseList); 2478 return nullptr; 2479 } 2480 2481 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2482 const ValueDecl *D, 2483 const DSAStackTy::DSAVarData &DVar, 2484 bool IsLoopIterVar = false) { 2485 if (DVar.RefExpr) { 2486 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2487 << getOpenMPClauseName(DVar.CKind); 2488 return; 2489 } 2490 enum { 2491 PDSA_StaticMemberShared, 2492 PDSA_StaticLocalVarShared, 2493 PDSA_LoopIterVarPrivate, 2494 PDSA_LoopIterVarLinear, 2495 PDSA_LoopIterVarLastprivate, 2496 PDSA_ConstVarShared, 2497 PDSA_GlobalVarShared, 2498 PDSA_TaskVarFirstprivate, 2499 PDSA_LocalVarPrivate, 2500 PDSA_Implicit 2501 } Reason = PDSA_Implicit; 2502 bool ReportHint = false; 2503 auto ReportLoc = D->getLocation(); 2504 auto *VD = dyn_cast<VarDecl>(D); 2505 if (IsLoopIterVar) { 2506 if (DVar.CKind == OMPC_private) 2507 Reason = PDSA_LoopIterVarPrivate; 2508 else if (DVar.CKind == OMPC_lastprivate) 2509 Reason = PDSA_LoopIterVarLastprivate; 2510 else 2511 Reason = PDSA_LoopIterVarLinear; 2512 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2513 DVar.CKind == OMPC_firstprivate) { 2514 Reason = PDSA_TaskVarFirstprivate; 2515 ReportLoc = DVar.ImplicitDSALoc; 2516 } else if (VD && VD->isStaticLocal()) 2517 Reason = PDSA_StaticLocalVarShared; 2518 else if (VD && VD->isStaticDataMember()) 2519 Reason = PDSA_StaticMemberShared; 2520 else if (VD && VD->isFileVarDecl()) 2521 Reason = PDSA_GlobalVarShared; 2522 else if (D->getType().isConstant(SemaRef.getASTContext())) 2523 Reason = PDSA_ConstVarShared; 2524 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2525 ReportHint = true; 2526 Reason = PDSA_LocalVarPrivate; 2527 } 2528 if (Reason != PDSA_Implicit) { 2529 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2530 << Reason << ReportHint 2531 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2532 } else if (DVar.ImplicitDSALoc.isValid()) { 2533 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2534 << getOpenMPClauseName(DVar.CKind); 2535 } 2536 } 2537 2538 namespace { 2539 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2540 DSAStackTy *Stack; 2541 Sema &SemaRef; 2542 bool ErrorFound = false; 2543 CapturedStmt *CS = nullptr; 2544 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2545 llvm::SmallVector<Expr *, 4> ImplicitMap; 2546 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2547 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2548 2549 void VisitSubCaptures(OMPExecutableDirective *S) { 2550 // Check implicitly captured variables. 2551 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2552 return; 2553 for (const CapturedStmt::Capture &Cap : 2554 S->getInnermostCapturedStmt()->captures()) { 2555 if (!Cap.capturesVariable()) 2556 continue; 2557 VarDecl *VD = Cap.getCapturedVar(); 2558 // Do not try to map the variable if it or its sub-component was mapped 2559 // already. 2560 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2561 Stack->checkMappableExprComponentListsForDecl( 2562 VD, /*CurrentRegionOnly=*/true, 2563 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2564 OpenMPClauseKind) { return true; })) 2565 continue; 2566 DeclRefExpr *DRE = buildDeclRefExpr( 2567 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2568 Cap.getLocation(), /*RefersToCapture=*/true); 2569 Visit(DRE); 2570 } 2571 } 2572 2573 public: 2574 void VisitDeclRefExpr(DeclRefExpr *E) { 2575 if (E->isTypeDependent() || E->isValueDependent() || 2576 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2577 return; 2578 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2579 // Check the datasharing rules for the expressions in the clauses. 2580 if (!CS) { 2581 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2582 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2583 Visit(CED->getInit()); 2584 return; 2585 } 2586 } 2587 VD = VD->getCanonicalDecl(); 2588 // Skip internally declared variables. 2589 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2590 return; 2591 2592 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2593 // Check if the variable has explicit DSA set and stop analysis if it so. 2594 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2595 return; 2596 2597 // Skip internally declared static variables. 2598 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2599 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2600 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2601 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2602 return; 2603 2604 SourceLocation ELoc = E->getExprLoc(); 2605 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2606 // The default(none) clause requires that each variable that is referenced 2607 // in the construct, and does not have a predetermined data-sharing 2608 // attribute, must have its data-sharing attribute explicitly determined 2609 // by being listed in a data-sharing attribute clause. 2610 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2611 isImplicitOrExplicitTaskingRegion(DKind) && 2612 VarsWithInheritedDSA.count(VD) == 0) { 2613 VarsWithInheritedDSA[VD] = E; 2614 return; 2615 } 2616 2617 if (isOpenMPTargetExecutionDirective(DKind) && 2618 !Stack->isLoopControlVariable(VD).first) { 2619 if (!Stack->checkMappableExprComponentListsForDecl( 2620 VD, /*CurrentRegionOnly=*/true, 2621 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2622 StackComponents, 2623 OpenMPClauseKind) { 2624 // Variable is used if it has been marked as an array, array 2625 // section or the variable iself. 2626 return StackComponents.size() == 1 || 2627 std::all_of( 2628 std::next(StackComponents.rbegin()), 2629 StackComponents.rend(), 2630 [](const OMPClauseMappableExprCommon:: 2631 MappableComponent &MC) { 2632 return MC.getAssociatedDeclaration() == 2633 nullptr && 2634 (isa<OMPArraySectionExpr>( 2635 MC.getAssociatedExpression()) || 2636 isa<ArraySubscriptExpr>( 2637 MC.getAssociatedExpression())); 2638 }); 2639 })) { 2640 bool IsFirstprivate = false; 2641 // By default lambdas are captured as firstprivates. 2642 if (const auto *RD = 2643 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2644 IsFirstprivate = RD->isLambda(); 2645 IsFirstprivate = 2646 IsFirstprivate || 2647 (VD->getType().getNonReferenceType()->isScalarType() && 2648 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2649 if (IsFirstprivate) 2650 ImplicitFirstprivate.emplace_back(E); 2651 else 2652 ImplicitMap.emplace_back(E); 2653 return; 2654 } 2655 } 2656 2657 // OpenMP [2.9.3.6, Restrictions, p.2] 2658 // A list item that appears in a reduction clause of the innermost 2659 // enclosing worksharing or parallel construct may not be accessed in an 2660 // explicit task. 2661 DVar = Stack->hasInnermostDSA( 2662 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2663 [](OpenMPDirectiveKind K) { 2664 return isOpenMPParallelDirective(K) || 2665 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2666 }, 2667 /*FromParent=*/true); 2668 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2669 ErrorFound = true; 2670 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2671 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2672 return; 2673 } 2674 2675 // Define implicit data-sharing attributes for task. 2676 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2677 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2678 !Stack->isLoopControlVariable(VD).first) { 2679 ImplicitFirstprivate.push_back(E); 2680 return; 2681 } 2682 2683 // Store implicitly used globals with declare target link for parent 2684 // target. 2685 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2686 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2687 Stack->addToParentTargetRegionLinkGlobals(E); 2688 return; 2689 } 2690 } 2691 } 2692 void VisitMemberExpr(MemberExpr *E) { 2693 if (E->isTypeDependent() || E->isValueDependent() || 2694 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2695 return; 2696 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2697 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2698 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2699 if (!FD) 2700 return; 2701 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2702 // Check if the variable has explicit DSA set and stop analysis if it 2703 // so. 2704 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2705 return; 2706 2707 if (isOpenMPTargetExecutionDirective(DKind) && 2708 !Stack->isLoopControlVariable(FD).first && 2709 !Stack->checkMappableExprComponentListsForDecl( 2710 FD, /*CurrentRegionOnly=*/true, 2711 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2712 StackComponents, 2713 OpenMPClauseKind) { 2714 return isa<CXXThisExpr>( 2715 cast<MemberExpr>( 2716 StackComponents.back().getAssociatedExpression()) 2717 ->getBase() 2718 ->IgnoreParens()); 2719 })) { 2720 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2721 // A bit-field cannot appear in a map clause. 2722 // 2723 if (FD->isBitField()) 2724 return; 2725 2726 // Check to see if the member expression is referencing a class that 2727 // has already been explicitly mapped 2728 if (Stack->isClassPreviouslyMapped(TE->getType())) 2729 return; 2730 2731 ImplicitMap.emplace_back(E); 2732 return; 2733 } 2734 2735 SourceLocation ELoc = E->getExprLoc(); 2736 // OpenMP [2.9.3.6, Restrictions, p.2] 2737 // A list item that appears in a reduction clause of the innermost 2738 // enclosing worksharing or parallel construct may not be accessed in 2739 // an explicit task. 2740 DVar = Stack->hasInnermostDSA( 2741 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2742 [](OpenMPDirectiveKind K) { 2743 return isOpenMPParallelDirective(K) || 2744 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2745 }, 2746 /*FromParent=*/true); 2747 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2748 ErrorFound = true; 2749 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2750 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2751 return; 2752 } 2753 2754 // Define implicit data-sharing attributes for task. 2755 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2756 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2757 !Stack->isLoopControlVariable(FD).first) { 2758 // Check if there is a captured expression for the current field in the 2759 // region. Do not mark it as firstprivate unless there is no captured 2760 // expression. 2761 // TODO: try to make it firstprivate. 2762 if (DVar.CKind != OMPC_unknown) 2763 ImplicitFirstprivate.push_back(E); 2764 } 2765 return; 2766 } 2767 if (isOpenMPTargetExecutionDirective(DKind)) { 2768 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2769 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2770 /*NoDiagnose=*/true)) 2771 return; 2772 const auto *VD = cast<ValueDecl>( 2773 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2774 if (!Stack->checkMappableExprComponentListsForDecl( 2775 VD, /*CurrentRegionOnly=*/true, 2776 [&CurComponents]( 2777 OMPClauseMappableExprCommon::MappableExprComponentListRef 2778 StackComponents, 2779 OpenMPClauseKind) { 2780 auto CCI = CurComponents.rbegin(); 2781 auto CCE = CurComponents.rend(); 2782 for (const auto &SC : llvm::reverse(StackComponents)) { 2783 // Do both expressions have the same kind? 2784 if (CCI->getAssociatedExpression()->getStmtClass() != 2785 SC.getAssociatedExpression()->getStmtClass()) 2786 if (!(isa<OMPArraySectionExpr>( 2787 SC.getAssociatedExpression()) && 2788 isa<ArraySubscriptExpr>( 2789 CCI->getAssociatedExpression()))) 2790 return false; 2791 2792 const Decl *CCD = CCI->getAssociatedDeclaration(); 2793 const Decl *SCD = SC.getAssociatedDeclaration(); 2794 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2795 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2796 if (SCD != CCD) 2797 return false; 2798 std::advance(CCI, 1); 2799 if (CCI == CCE) 2800 break; 2801 } 2802 return true; 2803 })) { 2804 Visit(E->getBase()); 2805 } 2806 } else { 2807 Visit(E->getBase()); 2808 } 2809 } 2810 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2811 for (OMPClause *C : S->clauses()) { 2812 // Skip analysis of arguments of implicitly defined firstprivate clause 2813 // for task|target directives. 2814 // Skip analysis of arguments of implicitly defined map clause for target 2815 // directives. 2816 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2817 C->isImplicit())) { 2818 for (Stmt *CC : C->children()) { 2819 if (CC) 2820 Visit(CC); 2821 } 2822 } 2823 } 2824 // Check implicitly captured variables. 2825 VisitSubCaptures(S); 2826 } 2827 void VisitStmt(Stmt *S) { 2828 for (Stmt *C : S->children()) { 2829 if (C) { 2830 // Check implicitly captured variables in the task-based directives to 2831 // check if they must be firstprivatized. 2832 Visit(C); 2833 } 2834 } 2835 } 2836 2837 bool isErrorFound() const { return ErrorFound; } 2838 ArrayRef<Expr *> getImplicitFirstprivate() const { 2839 return ImplicitFirstprivate; 2840 } 2841 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2842 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2843 return VarsWithInheritedDSA; 2844 } 2845 2846 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2847 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2848 // Process declare target link variables for the target directives. 2849 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2850 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2851 Visit(E); 2852 } 2853 } 2854 }; 2855 } // namespace 2856 2857 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2858 switch (DKind) { 2859 case OMPD_parallel: 2860 case OMPD_parallel_for: 2861 case OMPD_parallel_for_simd: 2862 case OMPD_parallel_sections: 2863 case OMPD_teams: 2864 case OMPD_teams_distribute: 2865 case OMPD_teams_distribute_simd: { 2866 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2867 QualType KmpInt32PtrTy = 2868 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2869 Sema::CapturedParamNameType Params[] = { 2870 std::make_pair(".global_tid.", KmpInt32PtrTy), 2871 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2872 std::make_pair(StringRef(), QualType()) // __context with shared vars 2873 }; 2874 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2875 Params); 2876 break; 2877 } 2878 case OMPD_target_teams: 2879 case OMPD_target_parallel: 2880 case OMPD_target_parallel_for: 2881 case OMPD_target_parallel_for_simd: 2882 case OMPD_target_teams_distribute: 2883 case OMPD_target_teams_distribute_simd: { 2884 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2885 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2886 QualType KmpInt32PtrTy = 2887 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2888 QualType Args[] = {VoidPtrTy}; 2889 FunctionProtoType::ExtProtoInfo EPI; 2890 EPI.Variadic = true; 2891 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2892 Sema::CapturedParamNameType Params[] = { 2893 std::make_pair(".global_tid.", KmpInt32Ty), 2894 std::make_pair(".part_id.", KmpInt32PtrTy), 2895 std::make_pair(".privates.", VoidPtrTy), 2896 std::make_pair( 2897 ".copy_fn.", 2898 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2899 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2900 std::make_pair(StringRef(), QualType()) // __context with shared vars 2901 }; 2902 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2903 Params); 2904 // Mark this captured region as inlined, because we don't use outlined 2905 // function directly. 2906 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2907 AlwaysInlineAttr::CreateImplicit( 2908 Context, AlwaysInlineAttr::Keyword_forceinline)); 2909 Sema::CapturedParamNameType ParamsTarget[] = { 2910 std::make_pair(StringRef(), QualType()) // __context with shared vars 2911 }; 2912 // Start a captured region for 'target' with no implicit parameters. 2913 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2914 ParamsTarget); 2915 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2916 std::make_pair(".global_tid.", KmpInt32PtrTy), 2917 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2918 std::make_pair(StringRef(), QualType()) // __context with shared vars 2919 }; 2920 // Start a captured region for 'teams' or 'parallel'. Both regions have 2921 // the same implicit parameters. 2922 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2923 ParamsTeamsOrParallel); 2924 break; 2925 } 2926 case OMPD_target: 2927 case OMPD_target_simd: { 2928 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2929 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2930 QualType KmpInt32PtrTy = 2931 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2932 QualType Args[] = {VoidPtrTy}; 2933 FunctionProtoType::ExtProtoInfo EPI; 2934 EPI.Variadic = true; 2935 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2936 Sema::CapturedParamNameType Params[] = { 2937 std::make_pair(".global_tid.", KmpInt32Ty), 2938 std::make_pair(".part_id.", KmpInt32PtrTy), 2939 std::make_pair(".privates.", VoidPtrTy), 2940 std::make_pair( 2941 ".copy_fn.", 2942 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2943 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2944 std::make_pair(StringRef(), QualType()) // __context with shared vars 2945 }; 2946 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2947 Params); 2948 // Mark this captured region as inlined, because we don't use outlined 2949 // function directly. 2950 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2951 AlwaysInlineAttr::CreateImplicit( 2952 Context, AlwaysInlineAttr::Keyword_forceinline)); 2953 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2954 std::make_pair(StringRef(), QualType())); 2955 break; 2956 } 2957 case OMPD_simd: 2958 case OMPD_for: 2959 case OMPD_for_simd: 2960 case OMPD_sections: 2961 case OMPD_section: 2962 case OMPD_single: 2963 case OMPD_master: 2964 case OMPD_critical: 2965 case OMPD_taskgroup: 2966 case OMPD_distribute: 2967 case OMPD_distribute_simd: 2968 case OMPD_ordered: 2969 case OMPD_atomic: 2970 case OMPD_target_data: { 2971 Sema::CapturedParamNameType Params[] = { 2972 std::make_pair(StringRef(), QualType()) // __context with shared vars 2973 }; 2974 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2975 Params); 2976 break; 2977 } 2978 case OMPD_task: { 2979 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2980 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2981 QualType KmpInt32PtrTy = 2982 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2983 QualType Args[] = {VoidPtrTy}; 2984 FunctionProtoType::ExtProtoInfo EPI; 2985 EPI.Variadic = true; 2986 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2987 Sema::CapturedParamNameType Params[] = { 2988 std::make_pair(".global_tid.", KmpInt32Ty), 2989 std::make_pair(".part_id.", KmpInt32PtrTy), 2990 std::make_pair(".privates.", VoidPtrTy), 2991 std::make_pair( 2992 ".copy_fn.", 2993 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2994 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2995 std::make_pair(StringRef(), QualType()) // __context with shared vars 2996 }; 2997 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2998 Params); 2999 // Mark this captured region as inlined, because we don't use outlined 3000 // function directly. 3001 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3002 AlwaysInlineAttr::CreateImplicit( 3003 Context, AlwaysInlineAttr::Keyword_forceinline)); 3004 break; 3005 } 3006 case OMPD_taskloop: 3007 case OMPD_taskloop_simd: { 3008 QualType KmpInt32Ty = 3009 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3010 .withConst(); 3011 QualType KmpUInt64Ty = 3012 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3013 .withConst(); 3014 QualType KmpInt64Ty = 3015 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3016 .withConst(); 3017 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3018 QualType KmpInt32PtrTy = 3019 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3020 QualType Args[] = {VoidPtrTy}; 3021 FunctionProtoType::ExtProtoInfo EPI; 3022 EPI.Variadic = true; 3023 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3024 Sema::CapturedParamNameType Params[] = { 3025 std::make_pair(".global_tid.", KmpInt32Ty), 3026 std::make_pair(".part_id.", KmpInt32PtrTy), 3027 std::make_pair(".privates.", VoidPtrTy), 3028 std::make_pair( 3029 ".copy_fn.", 3030 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3031 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3032 std::make_pair(".lb.", KmpUInt64Ty), 3033 std::make_pair(".ub.", KmpUInt64Ty), 3034 std::make_pair(".st.", KmpInt64Ty), 3035 std::make_pair(".liter.", KmpInt32Ty), 3036 std::make_pair(".reductions.", VoidPtrTy), 3037 std::make_pair(StringRef(), QualType()) // __context with shared vars 3038 }; 3039 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3040 Params); 3041 // Mark this captured region as inlined, because we don't use outlined 3042 // function directly. 3043 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3044 AlwaysInlineAttr::CreateImplicit( 3045 Context, AlwaysInlineAttr::Keyword_forceinline)); 3046 break; 3047 } 3048 case OMPD_distribute_parallel_for_simd: 3049 case OMPD_distribute_parallel_for: { 3050 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3051 QualType KmpInt32PtrTy = 3052 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3053 Sema::CapturedParamNameType Params[] = { 3054 std::make_pair(".global_tid.", KmpInt32PtrTy), 3055 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3056 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3057 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3058 std::make_pair(StringRef(), QualType()) // __context with shared vars 3059 }; 3060 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3061 Params); 3062 break; 3063 } 3064 case OMPD_target_teams_distribute_parallel_for: 3065 case OMPD_target_teams_distribute_parallel_for_simd: { 3066 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3067 QualType KmpInt32PtrTy = 3068 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3069 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3070 3071 QualType Args[] = {VoidPtrTy}; 3072 FunctionProtoType::ExtProtoInfo EPI; 3073 EPI.Variadic = true; 3074 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3075 Sema::CapturedParamNameType Params[] = { 3076 std::make_pair(".global_tid.", KmpInt32Ty), 3077 std::make_pair(".part_id.", KmpInt32PtrTy), 3078 std::make_pair(".privates.", VoidPtrTy), 3079 std::make_pair( 3080 ".copy_fn.", 3081 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3082 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3083 std::make_pair(StringRef(), QualType()) // __context with shared vars 3084 }; 3085 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3086 Params); 3087 // Mark this captured region as inlined, because we don't use outlined 3088 // function directly. 3089 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3090 AlwaysInlineAttr::CreateImplicit( 3091 Context, AlwaysInlineAttr::Keyword_forceinline)); 3092 Sema::CapturedParamNameType ParamsTarget[] = { 3093 std::make_pair(StringRef(), QualType()) // __context with shared vars 3094 }; 3095 // Start a captured region for 'target' with no implicit parameters. 3096 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3097 ParamsTarget); 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 3122 case OMPD_teams_distribute_parallel_for: 3123 case OMPD_teams_distribute_parallel_for_simd: { 3124 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3125 QualType KmpInt32PtrTy = 3126 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3127 3128 Sema::CapturedParamNameType ParamsTeams[] = { 3129 std::make_pair(".global_tid.", KmpInt32PtrTy), 3130 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3131 std::make_pair(StringRef(), QualType()) // __context with shared vars 3132 }; 3133 // Start a captured region for 'target' with no implicit parameters. 3134 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3135 ParamsTeams); 3136 3137 Sema::CapturedParamNameType ParamsParallel[] = { 3138 std::make_pair(".global_tid.", KmpInt32PtrTy), 3139 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3140 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3141 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3142 std::make_pair(StringRef(), QualType()) // __context with shared vars 3143 }; 3144 // Start a captured region for 'teams' or 'parallel'. Both regions have 3145 // the same implicit parameters. 3146 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3147 ParamsParallel); 3148 break; 3149 } 3150 case OMPD_target_update: 3151 case OMPD_target_enter_data: 3152 case OMPD_target_exit_data: { 3153 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3154 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3155 QualType KmpInt32PtrTy = 3156 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3157 QualType Args[] = {VoidPtrTy}; 3158 FunctionProtoType::ExtProtoInfo EPI; 3159 EPI.Variadic = true; 3160 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3161 Sema::CapturedParamNameType Params[] = { 3162 std::make_pair(".global_tid.", KmpInt32Ty), 3163 std::make_pair(".part_id.", KmpInt32PtrTy), 3164 std::make_pair(".privates.", VoidPtrTy), 3165 std::make_pair( 3166 ".copy_fn.", 3167 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3168 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3169 std::make_pair(StringRef(), QualType()) // __context with shared vars 3170 }; 3171 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3172 Params); 3173 // Mark this captured region as inlined, because we don't use outlined 3174 // function directly. 3175 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3176 AlwaysInlineAttr::CreateImplicit( 3177 Context, AlwaysInlineAttr::Keyword_forceinline)); 3178 break; 3179 } 3180 case OMPD_threadprivate: 3181 case OMPD_allocate: 3182 case OMPD_taskyield: 3183 case OMPD_barrier: 3184 case OMPD_taskwait: 3185 case OMPD_cancellation_point: 3186 case OMPD_cancel: 3187 case OMPD_flush: 3188 case OMPD_declare_reduction: 3189 case OMPD_declare_mapper: 3190 case OMPD_declare_simd: 3191 case OMPD_declare_target: 3192 case OMPD_end_declare_target: 3193 case OMPD_requires: 3194 llvm_unreachable("OpenMP Directive is not allowed"); 3195 case OMPD_unknown: 3196 llvm_unreachable("Unknown OpenMP directive"); 3197 } 3198 } 3199 3200 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3201 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3202 getOpenMPCaptureRegions(CaptureRegions, DKind); 3203 return CaptureRegions.size(); 3204 } 3205 3206 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3207 Expr *CaptureExpr, bool WithInit, 3208 bool AsExpression) { 3209 assert(CaptureExpr); 3210 ASTContext &C = S.getASTContext(); 3211 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3212 QualType Ty = Init->getType(); 3213 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3214 if (S.getLangOpts().CPlusPlus) { 3215 Ty = C.getLValueReferenceType(Ty); 3216 } else { 3217 Ty = C.getPointerType(Ty); 3218 ExprResult Res = 3219 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3220 if (!Res.isUsable()) 3221 return nullptr; 3222 Init = Res.get(); 3223 } 3224 WithInit = true; 3225 } 3226 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3227 CaptureExpr->getBeginLoc()); 3228 if (!WithInit) 3229 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3230 S.CurContext->addHiddenDecl(CED); 3231 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3232 return CED; 3233 } 3234 3235 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3236 bool WithInit) { 3237 OMPCapturedExprDecl *CD; 3238 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3239 CD = cast<OMPCapturedExprDecl>(VD); 3240 else 3241 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3242 /*AsExpression=*/false); 3243 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3244 CaptureExpr->getExprLoc()); 3245 } 3246 3247 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3248 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3249 if (!Ref) { 3250 OMPCapturedExprDecl *CD = buildCaptureDecl( 3251 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3252 /*WithInit=*/true, /*AsExpression=*/true); 3253 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3254 CaptureExpr->getExprLoc()); 3255 } 3256 ExprResult Res = Ref; 3257 if (!S.getLangOpts().CPlusPlus && 3258 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3259 Ref->getType()->isPointerType()) { 3260 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3261 if (!Res.isUsable()) 3262 return ExprError(); 3263 } 3264 return S.DefaultLvalueConversion(Res.get()); 3265 } 3266 3267 namespace { 3268 // OpenMP directives parsed in this section are represented as a 3269 // CapturedStatement with an associated statement. If a syntax error 3270 // is detected during the parsing of the associated statement, the 3271 // compiler must abort processing and close the CapturedStatement. 3272 // 3273 // Combined directives such as 'target parallel' have more than one 3274 // nested CapturedStatements. This RAII ensures that we unwind out 3275 // of all the nested CapturedStatements when an error is found. 3276 class CaptureRegionUnwinderRAII { 3277 private: 3278 Sema &S; 3279 bool &ErrorFound; 3280 OpenMPDirectiveKind DKind = OMPD_unknown; 3281 3282 public: 3283 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3284 OpenMPDirectiveKind DKind) 3285 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3286 ~CaptureRegionUnwinderRAII() { 3287 if (ErrorFound) { 3288 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3289 while (--ThisCaptureLevel >= 0) 3290 S.ActOnCapturedRegionError(); 3291 } 3292 } 3293 }; 3294 } // namespace 3295 3296 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3297 ArrayRef<OMPClause *> Clauses) { 3298 bool ErrorFound = false; 3299 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3300 *this, ErrorFound, DSAStack->getCurrentDirective()); 3301 if (!S.isUsable()) { 3302 ErrorFound = true; 3303 return StmtError(); 3304 } 3305 3306 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3307 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3308 OMPOrderedClause *OC = nullptr; 3309 OMPScheduleClause *SC = nullptr; 3310 SmallVector<const OMPLinearClause *, 4> LCs; 3311 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3312 // This is required for proper codegen. 3313 for (OMPClause *Clause : Clauses) { 3314 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3315 Clause->getClauseKind() == OMPC_in_reduction) { 3316 // Capture taskgroup task_reduction descriptors inside the tasking regions 3317 // with the corresponding in_reduction items. 3318 auto *IRC = cast<OMPInReductionClause>(Clause); 3319 for (Expr *E : IRC->taskgroup_descriptors()) 3320 if (E) 3321 MarkDeclarationsReferencedInExpr(E); 3322 } 3323 if (isOpenMPPrivate(Clause->getClauseKind()) || 3324 Clause->getClauseKind() == OMPC_copyprivate || 3325 (getLangOpts().OpenMPUseTLS && 3326 getASTContext().getTargetInfo().isTLSSupported() && 3327 Clause->getClauseKind() == OMPC_copyin)) { 3328 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3329 // Mark all variables in private list clauses as used in inner region. 3330 for (Stmt *VarRef : Clause->children()) { 3331 if (auto *E = cast_or_null<Expr>(VarRef)) { 3332 MarkDeclarationsReferencedInExpr(E); 3333 } 3334 } 3335 DSAStack->setForceVarCapturing(/*V=*/false); 3336 } else if (CaptureRegions.size() > 1 || 3337 CaptureRegions.back() != OMPD_unknown) { 3338 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3339 PICs.push_back(C); 3340 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3341 if (Expr *E = C->getPostUpdateExpr()) 3342 MarkDeclarationsReferencedInExpr(E); 3343 } 3344 } 3345 if (Clause->getClauseKind() == OMPC_schedule) 3346 SC = cast<OMPScheduleClause>(Clause); 3347 else if (Clause->getClauseKind() == OMPC_ordered) 3348 OC = cast<OMPOrderedClause>(Clause); 3349 else if (Clause->getClauseKind() == OMPC_linear) 3350 LCs.push_back(cast<OMPLinearClause>(Clause)); 3351 } 3352 // OpenMP, 2.7.1 Loop Construct, Restrictions 3353 // The nonmonotonic modifier cannot be specified if an ordered clause is 3354 // specified. 3355 if (SC && 3356 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3357 SC->getSecondScheduleModifier() == 3358 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3359 OC) { 3360 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3361 ? SC->getFirstScheduleModifierLoc() 3362 : SC->getSecondScheduleModifierLoc(), 3363 diag::err_omp_schedule_nonmonotonic_ordered) 3364 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3365 ErrorFound = true; 3366 } 3367 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3368 for (const OMPLinearClause *C : LCs) { 3369 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3370 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3371 } 3372 ErrorFound = true; 3373 } 3374 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3375 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3376 OC->getNumForLoops()) { 3377 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3378 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3379 ErrorFound = true; 3380 } 3381 if (ErrorFound) { 3382 return StmtError(); 3383 } 3384 StmtResult SR = S; 3385 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3386 // Mark all variables in private list clauses as used in inner region. 3387 // Required for proper codegen of combined directives. 3388 // TODO: add processing for other clauses. 3389 if (ThisCaptureRegion != OMPD_unknown) { 3390 for (const clang::OMPClauseWithPreInit *C : PICs) { 3391 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3392 // Find the particular capture region for the clause if the 3393 // directive is a combined one with multiple capture regions. 3394 // If the directive is not a combined one, the capture region 3395 // associated with the clause is OMPD_unknown and is generated 3396 // only once. 3397 if (CaptureRegion == ThisCaptureRegion || 3398 CaptureRegion == OMPD_unknown) { 3399 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3400 for (Decl *D : DS->decls()) 3401 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3402 } 3403 } 3404 } 3405 } 3406 SR = ActOnCapturedRegionEnd(SR.get()); 3407 } 3408 return SR; 3409 } 3410 3411 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3412 OpenMPDirectiveKind CancelRegion, 3413 SourceLocation StartLoc) { 3414 // CancelRegion is only needed for cancel and cancellation_point. 3415 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3416 return false; 3417 3418 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3419 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3420 return false; 3421 3422 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3423 << getOpenMPDirectiveName(CancelRegion); 3424 return true; 3425 } 3426 3427 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3428 OpenMPDirectiveKind CurrentRegion, 3429 const DeclarationNameInfo &CurrentName, 3430 OpenMPDirectiveKind CancelRegion, 3431 SourceLocation StartLoc) { 3432 if (Stack->getCurScope()) { 3433 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3434 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3435 bool NestingProhibited = false; 3436 bool CloseNesting = true; 3437 bool OrphanSeen = false; 3438 enum { 3439 NoRecommend, 3440 ShouldBeInParallelRegion, 3441 ShouldBeInOrderedRegion, 3442 ShouldBeInTargetRegion, 3443 ShouldBeInTeamsRegion 3444 } Recommend = NoRecommend; 3445 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3446 // OpenMP [2.16, Nesting of Regions] 3447 // OpenMP constructs may not be nested inside a simd region. 3448 // OpenMP [2.8.1,simd Construct, Restrictions] 3449 // An ordered construct with the simd clause is the only OpenMP 3450 // construct that can appear in the simd region. 3451 // Allowing a SIMD construct nested in another SIMD construct is an 3452 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3453 // message. 3454 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3455 ? diag::err_omp_prohibited_region_simd 3456 : diag::warn_omp_nesting_simd); 3457 return CurrentRegion != OMPD_simd; 3458 } 3459 if (ParentRegion == OMPD_atomic) { 3460 // OpenMP [2.16, Nesting of Regions] 3461 // OpenMP constructs may not be nested inside an atomic region. 3462 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3463 return true; 3464 } 3465 if (CurrentRegion == OMPD_section) { 3466 // OpenMP [2.7.2, sections Construct, Restrictions] 3467 // Orphaned section directives are prohibited. That is, the section 3468 // directives must appear within the sections construct and must not be 3469 // encountered elsewhere in the sections region. 3470 if (ParentRegion != OMPD_sections && 3471 ParentRegion != OMPD_parallel_sections) { 3472 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3473 << (ParentRegion != OMPD_unknown) 3474 << getOpenMPDirectiveName(ParentRegion); 3475 return true; 3476 } 3477 return false; 3478 } 3479 // Allow some constructs (except teams and cancellation constructs) to be 3480 // orphaned (they could be used in functions, called from OpenMP regions 3481 // with the required preconditions). 3482 if (ParentRegion == OMPD_unknown && 3483 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3484 CurrentRegion != OMPD_cancellation_point && 3485 CurrentRegion != OMPD_cancel) 3486 return false; 3487 if (CurrentRegion == OMPD_cancellation_point || 3488 CurrentRegion == OMPD_cancel) { 3489 // OpenMP [2.16, Nesting of Regions] 3490 // A cancellation point construct for which construct-type-clause is 3491 // taskgroup must be nested inside a task construct. A cancellation 3492 // point construct for which construct-type-clause is not taskgroup must 3493 // be closely nested inside an OpenMP construct that matches the type 3494 // specified in construct-type-clause. 3495 // A cancel construct for which construct-type-clause is taskgroup must be 3496 // nested inside a task construct. A cancel construct for which 3497 // construct-type-clause is not taskgroup must be closely nested inside an 3498 // OpenMP construct that matches the type specified in 3499 // construct-type-clause. 3500 NestingProhibited = 3501 !((CancelRegion == OMPD_parallel && 3502 (ParentRegion == OMPD_parallel || 3503 ParentRegion == OMPD_target_parallel)) || 3504 (CancelRegion == OMPD_for && 3505 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3506 ParentRegion == OMPD_target_parallel_for || 3507 ParentRegion == OMPD_distribute_parallel_for || 3508 ParentRegion == OMPD_teams_distribute_parallel_for || 3509 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3510 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3511 (CancelRegion == OMPD_sections && 3512 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3513 ParentRegion == OMPD_parallel_sections))); 3514 OrphanSeen = ParentRegion == OMPD_unknown; 3515 } else if (CurrentRegion == OMPD_master) { 3516 // OpenMP [2.16, Nesting of Regions] 3517 // A master region may not be closely nested inside a worksharing, 3518 // atomic, or explicit task region. 3519 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3520 isOpenMPTaskingDirective(ParentRegion); 3521 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3522 // OpenMP [2.16, Nesting of Regions] 3523 // A critical region may not be nested (closely or otherwise) inside a 3524 // critical region with the same name. Note that this restriction is not 3525 // sufficient to prevent deadlock. 3526 SourceLocation PreviousCriticalLoc; 3527 bool DeadLock = Stack->hasDirective( 3528 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3529 const DeclarationNameInfo &DNI, 3530 SourceLocation Loc) { 3531 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3532 PreviousCriticalLoc = Loc; 3533 return true; 3534 } 3535 return false; 3536 }, 3537 false /* skip top directive */); 3538 if (DeadLock) { 3539 SemaRef.Diag(StartLoc, 3540 diag::err_omp_prohibited_region_critical_same_name) 3541 << CurrentName.getName(); 3542 if (PreviousCriticalLoc.isValid()) 3543 SemaRef.Diag(PreviousCriticalLoc, 3544 diag::note_omp_previous_critical_region); 3545 return true; 3546 } 3547 } else if (CurrentRegion == OMPD_barrier) { 3548 // OpenMP [2.16, Nesting of Regions] 3549 // A barrier region may not be closely nested inside a worksharing, 3550 // explicit task, critical, ordered, atomic, or master region. 3551 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3552 isOpenMPTaskingDirective(ParentRegion) || 3553 ParentRegion == OMPD_master || 3554 ParentRegion == OMPD_critical || 3555 ParentRegion == OMPD_ordered; 3556 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3557 !isOpenMPParallelDirective(CurrentRegion) && 3558 !isOpenMPTeamsDirective(CurrentRegion)) { 3559 // OpenMP [2.16, Nesting of Regions] 3560 // A worksharing region may not be closely nested inside a worksharing, 3561 // explicit task, critical, ordered, atomic, or master region. 3562 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3563 isOpenMPTaskingDirective(ParentRegion) || 3564 ParentRegion == OMPD_master || 3565 ParentRegion == OMPD_critical || 3566 ParentRegion == OMPD_ordered; 3567 Recommend = ShouldBeInParallelRegion; 3568 } else if (CurrentRegion == OMPD_ordered) { 3569 // OpenMP [2.16, Nesting of Regions] 3570 // An ordered region may not be closely nested inside a critical, 3571 // atomic, or explicit task region. 3572 // An ordered region must be closely nested inside a loop region (or 3573 // parallel loop region) with an ordered clause. 3574 // OpenMP [2.8.1,simd Construct, Restrictions] 3575 // An ordered construct with the simd clause is the only OpenMP construct 3576 // that can appear in the simd region. 3577 NestingProhibited = ParentRegion == OMPD_critical || 3578 isOpenMPTaskingDirective(ParentRegion) || 3579 !(isOpenMPSimdDirective(ParentRegion) || 3580 Stack->isParentOrderedRegion()); 3581 Recommend = ShouldBeInOrderedRegion; 3582 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3583 // OpenMP [2.16, Nesting of Regions] 3584 // If specified, a teams construct must be contained within a target 3585 // construct. 3586 NestingProhibited = ParentRegion != OMPD_target; 3587 OrphanSeen = ParentRegion == OMPD_unknown; 3588 Recommend = ShouldBeInTargetRegion; 3589 } 3590 if (!NestingProhibited && 3591 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3592 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3593 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3594 // OpenMP [2.16, Nesting of Regions] 3595 // distribute, parallel, parallel sections, parallel workshare, and the 3596 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3597 // constructs that can be closely nested in the teams region. 3598 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3599 !isOpenMPDistributeDirective(CurrentRegion); 3600 Recommend = ShouldBeInParallelRegion; 3601 } 3602 if (!NestingProhibited && 3603 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3604 // OpenMP 4.5 [2.17 Nesting of Regions] 3605 // The region associated with the distribute construct must be strictly 3606 // nested inside a teams region 3607 NestingProhibited = 3608 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3609 Recommend = ShouldBeInTeamsRegion; 3610 } 3611 if (!NestingProhibited && 3612 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3613 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3614 // OpenMP 4.5 [2.17 Nesting of Regions] 3615 // If a target, target update, target data, target enter data, or 3616 // target exit data construct is encountered during execution of a 3617 // target region, the behavior is unspecified. 3618 NestingProhibited = Stack->hasDirective( 3619 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3620 SourceLocation) { 3621 if (isOpenMPTargetExecutionDirective(K)) { 3622 OffendingRegion = K; 3623 return true; 3624 } 3625 return false; 3626 }, 3627 false /* don't skip top directive */); 3628 CloseNesting = false; 3629 } 3630 if (NestingProhibited) { 3631 if (OrphanSeen) { 3632 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3633 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3634 } else { 3635 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3636 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3637 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3638 } 3639 return true; 3640 } 3641 } 3642 return false; 3643 } 3644 3645 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3646 ArrayRef<OMPClause *> Clauses, 3647 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3648 bool ErrorFound = false; 3649 unsigned NamedModifiersNumber = 0; 3650 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3651 OMPD_unknown + 1); 3652 SmallVector<SourceLocation, 4> NameModifierLoc; 3653 for (const OMPClause *C : Clauses) { 3654 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3655 // At most one if clause without a directive-name-modifier can appear on 3656 // the directive. 3657 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3658 if (FoundNameModifiers[CurNM]) { 3659 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3660 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3661 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3662 ErrorFound = true; 3663 } else if (CurNM != OMPD_unknown) { 3664 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3665 ++NamedModifiersNumber; 3666 } 3667 FoundNameModifiers[CurNM] = IC; 3668 if (CurNM == OMPD_unknown) 3669 continue; 3670 // Check if the specified name modifier is allowed for the current 3671 // directive. 3672 // At most one if clause with the particular directive-name-modifier can 3673 // appear on the directive. 3674 bool MatchFound = false; 3675 for (auto NM : AllowedNameModifiers) { 3676 if (CurNM == NM) { 3677 MatchFound = true; 3678 break; 3679 } 3680 } 3681 if (!MatchFound) { 3682 S.Diag(IC->getNameModifierLoc(), 3683 diag::err_omp_wrong_if_directive_name_modifier) 3684 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3685 ErrorFound = true; 3686 } 3687 } 3688 } 3689 // If any if clause on the directive includes a directive-name-modifier then 3690 // all if clauses on the directive must include a directive-name-modifier. 3691 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3692 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3693 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3694 diag::err_omp_no_more_if_clause); 3695 } else { 3696 std::string Values; 3697 std::string Sep(", "); 3698 unsigned AllowedCnt = 0; 3699 unsigned TotalAllowedNum = 3700 AllowedNameModifiers.size() - NamedModifiersNumber; 3701 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3702 ++Cnt) { 3703 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3704 if (!FoundNameModifiers[NM]) { 3705 Values += "'"; 3706 Values += getOpenMPDirectiveName(NM); 3707 Values += "'"; 3708 if (AllowedCnt + 2 == TotalAllowedNum) 3709 Values += " or "; 3710 else if (AllowedCnt + 1 != TotalAllowedNum) 3711 Values += Sep; 3712 ++AllowedCnt; 3713 } 3714 } 3715 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3716 diag::err_omp_unnamed_if_clause) 3717 << (TotalAllowedNum > 1) << Values; 3718 } 3719 for (SourceLocation Loc : NameModifierLoc) { 3720 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3721 } 3722 ErrorFound = true; 3723 } 3724 return ErrorFound; 3725 } 3726 3727 static std::pair<ValueDecl *, bool> 3728 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3729 SourceRange &ERange, bool AllowArraySection = false) { 3730 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3731 RefExpr->containsUnexpandedParameterPack()) 3732 return std::make_pair(nullptr, true); 3733 3734 // OpenMP [3.1, C/C++] 3735 // A list item is a variable name. 3736 // OpenMP [2.9.3.3, Restrictions, p.1] 3737 // A variable that is part of another variable (as an array or 3738 // structure element) cannot appear in a private clause. 3739 RefExpr = RefExpr->IgnoreParens(); 3740 enum { 3741 NoArrayExpr = -1, 3742 ArraySubscript = 0, 3743 OMPArraySection = 1 3744 } IsArrayExpr = NoArrayExpr; 3745 if (AllowArraySection) { 3746 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3747 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3748 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3749 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3750 RefExpr = Base; 3751 IsArrayExpr = ArraySubscript; 3752 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3753 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3754 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3755 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3756 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3757 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3758 RefExpr = Base; 3759 IsArrayExpr = OMPArraySection; 3760 } 3761 } 3762 ELoc = RefExpr->getExprLoc(); 3763 ERange = RefExpr->getSourceRange(); 3764 RefExpr = RefExpr->IgnoreParenImpCasts(); 3765 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3766 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3767 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3768 (S.getCurrentThisType().isNull() || !ME || 3769 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3770 !isa<FieldDecl>(ME->getMemberDecl()))) { 3771 if (IsArrayExpr != NoArrayExpr) { 3772 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3773 << ERange; 3774 } else { 3775 S.Diag(ELoc, 3776 AllowArraySection 3777 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3778 : diag::err_omp_expected_var_name_member_expr) 3779 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3780 } 3781 return std::make_pair(nullptr, false); 3782 } 3783 return std::make_pair( 3784 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3785 } 3786 3787 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3788 ArrayRef<OMPClause *> Clauses) { 3789 assert(!S.CurContext->isDependentContext() && 3790 "Expected non-dependent context."); 3791 auto AllocateRange = 3792 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3793 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3794 DeclToCopy; 3795 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3796 return isOpenMPPrivate(C->getClauseKind()); 3797 }); 3798 for (OMPClause *Cl : PrivateRange) { 3799 MutableArrayRef<Expr *>::iterator I, It, Et; 3800 if (Cl->getClauseKind() == OMPC_private) { 3801 auto *PC = cast<OMPPrivateClause>(Cl); 3802 I = PC->private_copies().begin(); 3803 It = PC->varlist_begin(); 3804 Et = PC->varlist_end(); 3805 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3806 auto *PC = cast<OMPFirstprivateClause>(Cl); 3807 I = PC->private_copies().begin(); 3808 It = PC->varlist_begin(); 3809 Et = PC->varlist_end(); 3810 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3811 auto *PC = cast<OMPLastprivateClause>(Cl); 3812 I = PC->private_copies().begin(); 3813 It = PC->varlist_begin(); 3814 Et = PC->varlist_end(); 3815 } else if (Cl->getClauseKind() == OMPC_linear) { 3816 auto *PC = cast<OMPLinearClause>(Cl); 3817 I = PC->privates().begin(); 3818 It = PC->varlist_begin(); 3819 Et = PC->varlist_end(); 3820 } else if (Cl->getClauseKind() == OMPC_reduction) { 3821 auto *PC = cast<OMPReductionClause>(Cl); 3822 I = PC->privates().begin(); 3823 It = PC->varlist_begin(); 3824 Et = PC->varlist_end(); 3825 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3826 auto *PC = cast<OMPTaskReductionClause>(Cl); 3827 I = PC->privates().begin(); 3828 It = PC->varlist_begin(); 3829 Et = PC->varlist_end(); 3830 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3831 auto *PC = cast<OMPInReductionClause>(Cl); 3832 I = PC->privates().begin(); 3833 It = PC->varlist_begin(); 3834 Et = PC->varlist_end(); 3835 } else { 3836 llvm_unreachable("Expected private clause."); 3837 } 3838 for (Expr *E : llvm::make_range(It, Et)) { 3839 if (!*I) { 3840 ++I; 3841 continue; 3842 } 3843 SourceLocation ELoc; 3844 SourceRange ERange; 3845 Expr *SimpleRefExpr = E; 3846 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3847 /*AllowArraySection=*/true); 3848 DeclToCopy.try_emplace(Res.first, 3849 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3850 ++I; 3851 } 3852 } 3853 for (OMPClause *C : AllocateRange) { 3854 auto *AC = cast<OMPAllocateClause>(C); 3855 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3856 getAllocatorKind(S, Stack, AC->getAllocator()); 3857 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3858 // For task, taskloop or target directives, allocation requests to memory 3859 // allocators with the trait access set to thread result in unspecified 3860 // behavior. 3861 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3862 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3863 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3864 S.Diag(AC->getAllocator()->getExprLoc(), 3865 diag::warn_omp_allocate_thread_on_task_target_directive) 3866 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3867 } 3868 for (Expr *E : AC->varlists()) { 3869 SourceLocation ELoc; 3870 SourceRange ERange; 3871 Expr *SimpleRefExpr = E; 3872 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3873 ValueDecl *VD = Res.first; 3874 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3875 if (!isOpenMPPrivate(Data.CKind)) { 3876 S.Diag(E->getExprLoc(), 3877 diag::err_omp_expected_private_copy_for_allocate); 3878 continue; 3879 } 3880 VarDecl *PrivateVD = DeclToCopy[VD]; 3881 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3882 AllocatorKind, AC->getAllocator())) 3883 continue; 3884 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3885 E->getSourceRange()); 3886 } 3887 } 3888 } 3889 3890 StmtResult Sema::ActOnOpenMPExecutableDirective( 3891 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3892 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3893 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3894 StmtResult Res = StmtError(); 3895 // First check CancelRegion which is then used in checkNestingOfRegions. 3896 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3897 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3898 StartLoc)) 3899 return StmtError(); 3900 3901 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3902 VarsWithInheritedDSAType VarsWithInheritedDSA; 3903 bool ErrorFound = false; 3904 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3905 if (AStmt && !CurContext->isDependentContext()) { 3906 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3907 3908 // Check default data sharing attributes for referenced variables. 3909 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3910 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3911 Stmt *S = AStmt; 3912 while (--ThisCaptureLevel >= 0) 3913 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3914 DSAChecker.Visit(S); 3915 if (DSAChecker.isErrorFound()) 3916 return StmtError(); 3917 // Generate list of implicitly defined firstprivate variables. 3918 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3919 3920 SmallVector<Expr *, 4> ImplicitFirstprivates( 3921 DSAChecker.getImplicitFirstprivate().begin(), 3922 DSAChecker.getImplicitFirstprivate().end()); 3923 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3924 DSAChecker.getImplicitMap().end()); 3925 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3926 for (OMPClause *C : Clauses) { 3927 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3928 for (Expr *E : IRC->taskgroup_descriptors()) 3929 if (E) 3930 ImplicitFirstprivates.emplace_back(E); 3931 } 3932 } 3933 if (!ImplicitFirstprivates.empty()) { 3934 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3935 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3936 SourceLocation())) { 3937 ClausesWithImplicit.push_back(Implicit); 3938 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3939 ImplicitFirstprivates.size(); 3940 } else { 3941 ErrorFound = true; 3942 } 3943 } 3944 if (!ImplicitMaps.empty()) { 3945 CXXScopeSpec MapperIdScopeSpec; 3946 DeclarationNameInfo MapperId; 3947 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3948 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 3949 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 3950 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 3951 ClausesWithImplicit.emplace_back(Implicit); 3952 ErrorFound |= 3953 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3954 } else { 3955 ErrorFound = true; 3956 } 3957 } 3958 } 3959 3960 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3961 switch (Kind) { 3962 case OMPD_parallel: 3963 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3964 EndLoc); 3965 AllowedNameModifiers.push_back(OMPD_parallel); 3966 break; 3967 case OMPD_simd: 3968 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3969 VarsWithInheritedDSA); 3970 break; 3971 case OMPD_for: 3972 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3973 VarsWithInheritedDSA); 3974 break; 3975 case OMPD_for_simd: 3976 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3977 EndLoc, VarsWithInheritedDSA); 3978 break; 3979 case OMPD_sections: 3980 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3981 EndLoc); 3982 break; 3983 case OMPD_section: 3984 assert(ClausesWithImplicit.empty() && 3985 "No clauses are allowed for 'omp section' directive"); 3986 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3987 break; 3988 case OMPD_single: 3989 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3990 EndLoc); 3991 break; 3992 case OMPD_master: 3993 assert(ClausesWithImplicit.empty() && 3994 "No clauses are allowed for 'omp master' directive"); 3995 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3996 break; 3997 case OMPD_critical: 3998 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3999 StartLoc, EndLoc); 4000 break; 4001 case OMPD_parallel_for: 4002 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4003 EndLoc, VarsWithInheritedDSA); 4004 AllowedNameModifiers.push_back(OMPD_parallel); 4005 break; 4006 case OMPD_parallel_for_simd: 4007 Res = ActOnOpenMPParallelForSimdDirective( 4008 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4009 AllowedNameModifiers.push_back(OMPD_parallel); 4010 break; 4011 case OMPD_parallel_sections: 4012 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4013 StartLoc, EndLoc); 4014 AllowedNameModifiers.push_back(OMPD_parallel); 4015 break; 4016 case OMPD_task: 4017 Res = 4018 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4019 AllowedNameModifiers.push_back(OMPD_task); 4020 break; 4021 case OMPD_taskyield: 4022 assert(ClausesWithImplicit.empty() && 4023 "No clauses are allowed for 'omp taskyield' directive"); 4024 assert(AStmt == nullptr && 4025 "No associated statement allowed for 'omp taskyield' directive"); 4026 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4027 break; 4028 case OMPD_barrier: 4029 assert(ClausesWithImplicit.empty() && 4030 "No clauses are allowed for 'omp barrier' directive"); 4031 assert(AStmt == nullptr && 4032 "No associated statement allowed for 'omp barrier' directive"); 4033 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4034 break; 4035 case OMPD_taskwait: 4036 assert(ClausesWithImplicit.empty() && 4037 "No clauses are allowed for 'omp taskwait' directive"); 4038 assert(AStmt == nullptr && 4039 "No associated statement allowed for 'omp taskwait' directive"); 4040 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4041 break; 4042 case OMPD_taskgroup: 4043 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4044 EndLoc); 4045 break; 4046 case OMPD_flush: 4047 assert(AStmt == nullptr && 4048 "No associated statement allowed for 'omp flush' directive"); 4049 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4050 break; 4051 case OMPD_ordered: 4052 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4053 EndLoc); 4054 break; 4055 case OMPD_atomic: 4056 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4057 EndLoc); 4058 break; 4059 case OMPD_teams: 4060 Res = 4061 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4062 break; 4063 case OMPD_target: 4064 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4065 EndLoc); 4066 AllowedNameModifiers.push_back(OMPD_target); 4067 break; 4068 case OMPD_target_parallel: 4069 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4070 StartLoc, EndLoc); 4071 AllowedNameModifiers.push_back(OMPD_target); 4072 AllowedNameModifiers.push_back(OMPD_parallel); 4073 break; 4074 case OMPD_target_parallel_for: 4075 Res = ActOnOpenMPTargetParallelForDirective( 4076 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4077 AllowedNameModifiers.push_back(OMPD_target); 4078 AllowedNameModifiers.push_back(OMPD_parallel); 4079 break; 4080 case OMPD_cancellation_point: 4081 assert(ClausesWithImplicit.empty() && 4082 "No clauses are allowed for 'omp cancellation point' directive"); 4083 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4084 "cancellation point' directive"); 4085 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4086 break; 4087 case OMPD_cancel: 4088 assert(AStmt == nullptr && 4089 "No associated statement allowed for 'omp cancel' directive"); 4090 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4091 CancelRegion); 4092 AllowedNameModifiers.push_back(OMPD_cancel); 4093 break; 4094 case OMPD_target_data: 4095 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4096 EndLoc); 4097 AllowedNameModifiers.push_back(OMPD_target_data); 4098 break; 4099 case OMPD_target_enter_data: 4100 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4101 EndLoc, AStmt); 4102 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4103 break; 4104 case OMPD_target_exit_data: 4105 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4106 EndLoc, AStmt); 4107 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4108 break; 4109 case OMPD_taskloop: 4110 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4111 EndLoc, VarsWithInheritedDSA); 4112 AllowedNameModifiers.push_back(OMPD_taskloop); 4113 break; 4114 case OMPD_taskloop_simd: 4115 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4116 EndLoc, VarsWithInheritedDSA); 4117 AllowedNameModifiers.push_back(OMPD_taskloop); 4118 break; 4119 case OMPD_distribute: 4120 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4121 EndLoc, VarsWithInheritedDSA); 4122 break; 4123 case OMPD_target_update: 4124 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4125 EndLoc, AStmt); 4126 AllowedNameModifiers.push_back(OMPD_target_update); 4127 break; 4128 case OMPD_distribute_parallel_for: 4129 Res = ActOnOpenMPDistributeParallelForDirective( 4130 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4131 AllowedNameModifiers.push_back(OMPD_parallel); 4132 break; 4133 case OMPD_distribute_parallel_for_simd: 4134 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4135 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4136 AllowedNameModifiers.push_back(OMPD_parallel); 4137 break; 4138 case OMPD_distribute_simd: 4139 Res = ActOnOpenMPDistributeSimdDirective( 4140 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4141 break; 4142 case OMPD_target_parallel_for_simd: 4143 Res = ActOnOpenMPTargetParallelForSimdDirective( 4144 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4145 AllowedNameModifiers.push_back(OMPD_target); 4146 AllowedNameModifiers.push_back(OMPD_parallel); 4147 break; 4148 case OMPD_target_simd: 4149 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4150 EndLoc, VarsWithInheritedDSA); 4151 AllowedNameModifiers.push_back(OMPD_target); 4152 break; 4153 case OMPD_teams_distribute: 4154 Res = ActOnOpenMPTeamsDistributeDirective( 4155 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4156 break; 4157 case OMPD_teams_distribute_simd: 4158 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4159 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4160 break; 4161 case OMPD_teams_distribute_parallel_for_simd: 4162 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4163 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4164 AllowedNameModifiers.push_back(OMPD_parallel); 4165 break; 4166 case OMPD_teams_distribute_parallel_for: 4167 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4168 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4169 AllowedNameModifiers.push_back(OMPD_parallel); 4170 break; 4171 case OMPD_target_teams: 4172 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4173 EndLoc); 4174 AllowedNameModifiers.push_back(OMPD_target); 4175 break; 4176 case OMPD_target_teams_distribute: 4177 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4178 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4179 AllowedNameModifiers.push_back(OMPD_target); 4180 break; 4181 case OMPD_target_teams_distribute_parallel_for: 4182 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4183 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4184 AllowedNameModifiers.push_back(OMPD_target); 4185 AllowedNameModifiers.push_back(OMPD_parallel); 4186 break; 4187 case OMPD_target_teams_distribute_parallel_for_simd: 4188 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4189 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4190 AllowedNameModifiers.push_back(OMPD_target); 4191 AllowedNameModifiers.push_back(OMPD_parallel); 4192 break; 4193 case OMPD_target_teams_distribute_simd: 4194 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4195 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4196 AllowedNameModifiers.push_back(OMPD_target); 4197 break; 4198 case OMPD_declare_target: 4199 case OMPD_end_declare_target: 4200 case OMPD_threadprivate: 4201 case OMPD_allocate: 4202 case OMPD_declare_reduction: 4203 case OMPD_declare_mapper: 4204 case OMPD_declare_simd: 4205 case OMPD_requires: 4206 llvm_unreachable("OpenMP Directive is not allowed"); 4207 case OMPD_unknown: 4208 llvm_unreachable("Unknown OpenMP directive"); 4209 } 4210 4211 ErrorFound = Res.isInvalid() || ErrorFound; 4212 4213 // Check variables in the clauses if default(none) was specified. 4214 if (DSAStack->getDefaultDSA() == DSA_none) { 4215 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4216 for (OMPClause *C : Clauses) { 4217 switch (C->getClauseKind()) { 4218 case OMPC_num_threads: 4219 case OMPC_dist_schedule: 4220 // Do not analyse if no parent teams directive. 4221 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4222 break; 4223 continue; 4224 case OMPC_if: 4225 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4226 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4227 break; 4228 continue; 4229 case OMPC_schedule: 4230 break; 4231 case OMPC_ordered: 4232 case OMPC_device: 4233 case OMPC_num_teams: 4234 case OMPC_thread_limit: 4235 case OMPC_priority: 4236 case OMPC_grainsize: 4237 case OMPC_num_tasks: 4238 case OMPC_hint: 4239 case OMPC_collapse: 4240 case OMPC_safelen: 4241 case OMPC_simdlen: 4242 case OMPC_final: 4243 case OMPC_default: 4244 case OMPC_proc_bind: 4245 case OMPC_private: 4246 case OMPC_firstprivate: 4247 case OMPC_lastprivate: 4248 case OMPC_shared: 4249 case OMPC_reduction: 4250 case OMPC_task_reduction: 4251 case OMPC_in_reduction: 4252 case OMPC_linear: 4253 case OMPC_aligned: 4254 case OMPC_copyin: 4255 case OMPC_copyprivate: 4256 case OMPC_nowait: 4257 case OMPC_untied: 4258 case OMPC_mergeable: 4259 case OMPC_allocate: 4260 case OMPC_read: 4261 case OMPC_write: 4262 case OMPC_update: 4263 case OMPC_capture: 4264 case OMPC_seq_cst: 4265 case OMPC_depend: 4266 case OMPC_threads: 4267 case OMPC_simd: 4268 case OMPC_map: 4269 case OMPC_nogroup: 4270 case OMPC_defaultmap: 4271 case OMPC_to: 4272 case OMPC_from: 4273 case OMPC_use_device_ptr: 4274 case OMPC_is_device_ptr: 4275 continue; 4276 case OMPC_allocator: 4277 case OMPC_flush: 4278 case OMPC_threadprivate: 4279 case OMPC_uniform: 4280 case OMPC_unknown: 4281 case OMPC_unified_address: 4282 case OMPC_unified_shared_memory: 4283 case OMPC_reverse_offload: 4284 case OMPC_dynamic_allocators: 4285 case OMPC_atomic_default_mem_order: 4286 llvm_unreachable("Unexpected clause"); 4287 } 4288 for (Stmt *CC : C->children()) { 4289 if (CC) 4290 DSAChecker.Visit(CC); 4291 } 4292 } 4293 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4294 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4295 } 4296 for (const auto &P : VarsWithInheritedDSA) { 4297 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4298 << P.first << P.second->getSourceRange(); 4299 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4300 } 4301 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 4302 4303 if (!AllowedNameModifiers.empty()) 4304 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4305 ErrorFound; 4306 4307 if (ErrorFound) 4308 return StmtError(); 4309 4310 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4311 Res.getAs<OMPExecutableDirective>() 4312 ->getStructuredBlock() 4313 ->setIsOMPStructuredBlock(true); 4314 } 4315 4316 if (!CurContext->isDependentContext() && 4317 isOpenMPTargetExecutionDirective(Kind) && 4318 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4319 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4320 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4321 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4322 // Register target to DSA Stack. 4323 DSAStack->addTargetDirLocation(StartLoc); 4324 } 4325 4326 return Res; 4327 } 4328 4329 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4330 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4331 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4332 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4333 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4334 assert(Aligneds.size() == Alignments.size()); 4335 assert(Linears.size() == LinModifiers.size()); 4336 assert(Linears.size() == Steps.size()); 4337 if (!DG || DG.get().isNull()) 4338 return DeclGroupPtrTy(); 4339 4340 if (!DG.get().isSingleDecl()) { 4341 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4342 return DG; 4343 } 4344 Decl *ADecl = DG.get().getSingleDecl(); 4345 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4346 ADecl = FTD->getTemplatedDecl(); 4347 4348 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4349 if (!FD) { 4350 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4351 return DeclGroupPtrTy(); 4352 } 4353 4354 // OpenMP [2.8.2, declare simd construct, Description] 4355 // The parameter of the simdlen clause must be a constant positive integer 4356 // expression. 4357 ExprResult SL; 4358 if (Simdlen) 4359 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4360 // OpenMP [2.8.2, declare simd construct, Description] 4361 // The special this pointer can be used as if was one of the arguments to the 4362 // function in any of the linear, aligned, or uniform clauses. 4363 // The uniform clause declares one or more arguments to have an invariant 4364 // value for all concurrent invocations of the function in the execution of a 4365 // single SIMD loop. 4366 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4367 const Expr *UniformedLinearThis = nullptr; 4368 for (const Expr *E : Uniforms) { 4369 E = E->IgnoreParenImpCasts(); 4370 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4371 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4372 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4373 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4374 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4375 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4376 continue; 4377 } 4378 if (isa<CXXThisExpr>(E)) { 4379 UniformedLinearThis = E; 4380 continue; 4381 } 4382 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4383 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4384 } 4385 // OpenMP [2.8.2, declare simd construct, Description] 4386 // The aligned clause declares that the object to which each list item points 4387 // is aligned to the number of bytes expressed in the optional parameter of 4388 // the aligned clause. 4389 // The special this pointer can be used as if was one of the arguments to the 4390 // function in any of the linear, aligned, or uniform clauses. 4391 // The type of list items appearing in the aligned clause must be array, 4392 // pointer, reference to array, or reference to pointer. 4393 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4394 const Expr *AlignedThis = nullptr; 4395 for (const Expr *E : Aligneds) { 4396 E = E->IgnoreParenImpCasts(); 4397 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4398 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4399 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4400 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4401 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4402 ->getCanonicalDecl() == CanonPVD) { 4403 // OpenMP [2.8.1, simd construct, Restrictions] 4404 // A list-item cannot appear in more than one aligned clause. 4405 if (AlignedArgs.count(CanonPVD) > 0) { 4406 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4407 << 1 << E->getSourceRange(); 4408 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4409 diag::note_omp_explicit_dsa) 4410 << getOpenMPClauseName(OMPC_aligned); 4411 continue; 4412 } 4413 AlignedArgs[CanonPVD] = E; 4414 QualType QTy = PVD->getType() 4415 .getNonReferenceType() 4416 .getUnqualifiedType() 4417 .getCanonicalType(); 4418 const Type *Ty = QTy.getTypePtrOrNull(); 4419 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4420 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4421 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4422 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4423 } 4424 continue; 4425 } 4426 } 4427 if (isa<CXXThisExpr>(E)) { 4428 if (AlignedThis) { 4429 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4430 << 2 << E->getSourceRange(); 4431 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4432 << getOpenMPClauseName(OMPC_aligned); 4433 } 4434 AlignedThis = E; 4435 continue; 4436 } 4437 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4438 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4439 } 4440 // The optional parameter of the aligned clause, alignment, must be a constant 4441 // positive integer expression. If no optional parameter is specified, 4442 // implementation-defined default alignments for SIMD instructions on the 4443 // target platforms are assumed. 4444 SmallVector<const Expr *, 4> NewAligns; 4445 for (Expr *E : Alignments) { 4446 ExprResult Align; 4447 if (E) 4448 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4449 NewAligns.push_back(Align.get()); 4450 } 4451 // OpenMP [2.8.2, declare simd construct, Description] 4452 // The linear clause declares one or more list items to be private to a SIMD 4453 // lane and to have a linear relationship with respect to the iteration space 4454 // of a loop. 4455 // The special this pointer can be used as if was one of the arguments to the 4456 // function in any of the linear, aligned, or uniform clauses. 4457 // When a linear-step expression is specified in a linear clause it must be 4458 // either a constant integer expression or an integer-typed parameter that is 4459 // specified in a uniform clause on the directive. 4460 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4461 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4462 auto MI = LinModifiers.begin(); 4463 for (const Expr *E : Linears) { 4464 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4465 ++MI; 4466 E = E->IgnoreParenImpCasts(); 4467 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4468 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4469 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4470 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4471 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4472 ->getCanonicalDecl() == CanonPVD) { 4473 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4474 // A list-item cannot appear in more than one linear clause. 4475 if (LinearArgs.count(CanonPVD) > 0) { 4476 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4477 << getOpenMPClauseName(OMPC_linear) 4478 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4479 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4480 diag::note_omp_explicit_dsa) 4481 << getOpenMPClauseName(OMPC_linear); 4482 continue; 4483 } 4484 // Each argument can appear in at most one uniform or linear clause. 4485 if (UniformedArgs.count(CanonPVD) > 0) { 4486 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4487 << getOpenMPClauseName(OMPC_linear) 4488 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4489 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4490 diag::note_omp_explicit_dsa) 4491 << getOpenMPClauseName(OMPC_uniform); 4492 continue; 4493 } 4494 LinearArgs[CanonPVD] = E; 4495 if (E->isValueDependent() || E->isTypeDependent() || 4496 E->isInstantiationDependent() || 4497 E->containsUnexpandedParameterPack()) 4498 continue; 4499 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4500 PVD->getOriginalType()); 4501 continue; 4502 } 4503 } 4504 if (isa<CXXThisExpr>(E)) { 4505 if (UniformedLinearThis) { 4506 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4507 << getOpenMPClauseName(OMPC_linear) 4508 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4509 << E->getSourceRange(); 4510 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4511 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4512 : OMPC_linear); 4513 continue; 4514 } 4515 UniformedLinearThis = E; 4516 if (E->isValueDependent() || E->isTypeDependent() || 4517 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4518 continue; 4519 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4520 E->getType()); 4521 continue; 4522 } 4523 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4524 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4525 } 4526 Expr *Step = nullptr; 4527 Expr *NewStep = nullptr; 4528 SmallVector<Expr *, 4> NewSteps; 4529 for (Expr *E : Steps) { 4530 // Skip the same step expression, it was checked already. 4531 if (Step == E || !E) { 4532 NewSteps.push_back(E ? NewStep : nullptr); 4533 continue; 4534 } 4535 Step = E; 4536 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4537 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4538 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4539 if (UniformedArgs.count(CanonPVD) == 0) { 4540 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4541 << Step->getSourceRange(); 4542 } else if (E->isValueDependent() || E->isTypeDependent() || 4543 E->isInstantiationDependent() || 4544 E->containsUnexpandedParameterPack() || 4545 CanonPVD->getType()->hasIntegerRepresentation()) { 4546 NewSteps.push_back(Step); 4547 } else { 4548 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4549 << Step->getSourceRange(); 4550 } 4551 continue; 4552 } 4553 NewStep = Step; 4554 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4555 !Step->isInstantiationDependent() && 4556 !Step->containsUnexpandedParameterPack()) { 4557 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4558 .get(); 4559 if (NewStep) 4560 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4561 } 4562 NewSteps.push_back(NewStep); 4563 } 4564 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4565 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4566 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4567 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4568 const_cast<Expr **>(Linears.data()), Linears.size(), 4569 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4570 NewSteps.data(), NewSteps.size(), SR); 4571 ADecl->addAttr(NewAttr); 4572 return ConvertDeclToDeclGroup(ADecl); 4573 } 4574 4575 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4576 Stmt *AStmt, 4577 SourceLocation StartLoc, 4578 SourceLocation EndLoc) { 4579 if (!AStmt) 4580 return StmtError(); 4581 4582 auto *CS = cast<CapturedStmt>(AStmt); 4583 // 1.2.2 OpenMP Language Terminology 4584 // Structured block - An executable statement with a single entry at the 4585 // top and a single exit at the bottom. 4586 // The point of exit cannot be a branch out of the structured block. 4587 // longjmp() and throw() must not violate the entry/exit criteria. 4588 CS->getCapturedDecl()->setNothrow(); 4589 4590 setFunctionHasBranchProtectedScope(); 4591 4592 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4593 DSAStack->isCancelRegion()); 4594 } 4595 4596 namespace { 4597 /// Helper class for checking canonical form of the OpenMP loops and 4598 /// extracting iteration space of each loop in the loop nest, that will be used 4599 /// for IR generation. 4600 class OpenMPIterationSpaceChecker { 4601 /// Reference to Sema. 4602 Sema &SemaRef; 4603 /// Data-sharing stack. 4604 DSAStackTy &Stack; 4605 /// A location for diagnostics (when there is no some better location). 4606 SourceLocation DefaultLoc; 4607 /// A location for diagnostics (when increment is not compatible). 4608 SourceLocation ConditionLoc; 4609 /// A source location for referring to loop init later. 4610 SourceRange InitSrcRange; 4611 /// A source location for referring to condition later. 4612 SourceRange ConditionSrcRange; 4613 /// A source location for referring to increment later. 4614 SourceRange IncrementSrcRange; 4615 /// Loop variable. 4616 ValueDecl *LCDecl = nullptr; 4617 /// Reference to loop variable. 4618 Expr *LCRef = nullptr; 4619 /// Lower bound (initializer for the var). 4620 Expr *LB = nullptr; 4621 /// Upper bound. 4622 Expr *UB = nullptr; 4623 /// Loop step (increment). 4624 Expr *Step = nullptr; 4625 /// This flag is true when condition is one of: 4626 /// Var < UB 4627 /// Var <= UB 4628 /// UB > Var 4629 /// UB >= Var 4630 /// This will have no value when the condition is != 4631 llvm::Optional<bool> TestIsLessOp; 4632 /// This flag is true when condition is strict ( < or > ). 4633 bool TestIsStrictOp = false; 4634 /// This flag is true when step is subtracted on each iteration. 4635 bool SubtractStep = false; 4636 /// The outer loop counter this loop depends on (if any). 4637 const ValueDecl *DepDecl = nullptr; 4638 /// Contains number of loop (starts from 1) on which loop counter init 4639 /// expression of this loop depends on. 4640 Optional<unsigned> InitDependOnLC; 4641 /// Contains number of loop (starts from 1) on which loop counter condition 4642 /// expression of this loop depends on. 4643 Optional<unsigned> CondDependOnLC; 4644 /// Checks if the provide statement depends on the loop counter. 4645 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4646 4647 public: 4648 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4649 SourceLocation DefaultLoc) 4650 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4651 ConditionLoc(DefaultLoc) {} 4652 /// Check init-expr for canonical loop form and save loop counter 4653 /// variable - #Var and its initialization value - #LB. 4654 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4655 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4656 /// for less/greater and for strict/non-strict comparison. 4657 bool checkAndSetCond(Expr *S); 4658 /// Check incr-expr for canonical loop form and return true if it 4659 /// does not conform, otherwise save loop step (#Step). 4660 bool checkAndSetInc(Expr *S); 4661 /// Return the loop counter variable. 4662 ValueDecl *getLoopDecl() const { return LCDecl; } 4663 /// Return the reference expression to loop counter variable. 4664 Expr *getLoopDeclRefExpr() const { return LCRef; } 4665 /// Source range of the loop init. 4666 SourceRange getInitSrcRange() const { return InitSrcRange; } 4667 /// Source range of the loop condition. 4668 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4669 /// Source range of the loop increment. 4670 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4671 /// True if the step should be subtracted. 4672 bool shouldSubtractStep() const { return SubtractStep; } 4673 /// True, if the compare operator is strict (<, > or !=). 4674 bool isStrictTestOp() const { return TestIsStrictOp; } 4675 /// Build the expression to calculate the number of iterations. 4676 Expr *buildNumIterations( 4677 Scope *S, const bool LimitedType, 4678 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4679 /// Build the precondition expression for the loops. 4680 Expr * 4681 buildPreCond(Scope *S, Expr *Cond, 4682 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4683 /// Build reference expression to the counter be used for codegen. 4684 DeclRefExpr * 4685 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4686 DSAStackTy &DSA) const; 4687 /// Build reference expression to the private counter be used for 4688 /// codegen. 4689 Expr *buildPrivateCounterVar() const; 4690 /// Build initialization of the counter be used for codegen. 4691 Expr *buildCounterInit() const; 4692 /// Build step of the counter be used for codegen. 4693 Expr *buildCounterStep() const; 4694 /// Build loop data with counter value for depend clauses in ordered 4695 /// directives. 4696 Expr * 4697 buildOrderedLoopData(Scope *S, Expr *Counter, 4698 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4699 SourceLocation Loc, Expr *Inc = nullptr, 4700 OverloadedOperatorKind OOK = OO_Amp); 4701 /// Return true if any expression is dependent. 4702 bool dependent() const; 4703 4704 private: 4705 /// Check the right-hand side of an assignment in the increment 4706 /// expression. 4707 bool checkAndSetIncRHS(Expr *RHS); 4708 /// Helper to set loop counter variable and its initializer. 4709 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4710 bool EmitDiags); 4711 /// Helper to set upper bound. 4712 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4713 SourceRange SR, SourceLocation SL); 4714 /// Helper to set loop increment. 4715 bool setStep(Expr *NewStep, bool Subtract); 4716 }; 4717 4718 bool OpenMPIterationSpaceChecker::dependent() const { 4719 if (!LCDecl) { 4720 assert(!LB && !UB && !Step); 4721 return false; 4722 } 4723 return LCDecl->getType()->isDependentType() || 4724 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4725 (Step && Step->isValueDependent()); 4726 } 4727 4728 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4729 Expr *NewLCRefExpr, 4730 Expr *NewLB, bool EmitDiags) { 4731 // State consistency checking to ensure correct usage. 4732 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4733 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4734 if (!NewLCDecl || !NewLB) 4735 return true; 4736 LCDecl = getCanonicalDecl(NewLCDecl); 4737 LCRef = NewLCRefExpr; 4738 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4739 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4740 if ((Ctor->isCopyOrMoveConstructor() || 4741 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4742 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4743 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4744 LB = NewLB; 4745 if (EmitDiags) 4746 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4747 return false; 4748 } 4749 4750 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4751 llvm::Optional<bool> LessOp, 4752 bool StrictOp, SourceRange SR, 4753 SourceLocation SL) { 4754 // State consistency checking to ensure correct usage. 4755 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4756 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4757 if (!NewUB) 4758 return true; 4759 UB = NewUB; 4760 if (LessOp) 4761 TestIsLessOp = LessOp; 4762 TestIsStrictOp = StrictOp; 4763 ConditionSrcRange = SR; 4764 ConditionLoc = SL; 4765 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4766 return false; 4767 } 4768 4769 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4770 // State consistency checking to ensure correct usage. 4771 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4772 if (!NewStep) 4773 return true; 4774 if (!NewStep->isValueDependent()) { 4775 // Check that the step is integer expression. 4776 SourceLocation StepLoc = NewStep->getBeginLoc(); 4777 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4778 StepLoc, getExprAsWritten(NewStep)); 4779 if (Val.isInvalid()) 4780 return true; 4781 NewStep = Val.get(); 4782 4783 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4784 // If test-expr is of form var relational-op b and relational-op is < or 4785 // <= then incr-expr must cause var to increase on each iteration of the 4786 // loop. If test-expr is of form var relational-op b and relational-op is 4787 // > or >= then incr-expr must cause var to decrease on each iteration of 4788 // the loop. 4789 // If test-expr is of form b relational-op var and relational-op is < or 4790 // <= then incr-expr must cause var to decrease on each iteration of the 4791 // loop. If test-expr is of form b relational-op var and relational-op is 4792 // > or >= then incr-expr must cause var to increase on each iteration of 4793 // the loop. 4794 llvm::APSInt Result; 4795 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4796 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4797 bool IsConstNeg = 4798 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4799 bool IsConstPos = 4800 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4801 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4802 4803 // != with increment is treated as <; != with decrement is treated as > 4804 if (!TestIsLessOp.hasValue()) 4805 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4806 if (UB && (IsConstZero || 4807 (TestIsLessOp.getValue() ? 4808 (IsConstNeg || (IsUnsigned && Subtract)) : 4809 (IsConstPos || (IsUnsigned && !Subtract))))) { 4810 SemaRef.Diag(NewStep->getExprLoc(), 4811 diag::err_omp_loop_incr_not_compatible) 4812 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4813 SemaRef.Diag(ConditionLoc, 4814 diag::note_omp_loop_cond_requres_compatible_incr) 4815 << TestIsLessOp.getValue() << ConditionSrcRange; 4816 return true; 4817 } 4818 if (TestIsLessOp.getValue() == Subtract) { 4819 NewStep = 4820 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4821 .get(); 4822 Subtract = !Subtract; 4823 } 4824 } 4825 4826 Step = NewStep; 4827 SubtractStep = Subtract; 4828 return false; 4829 } 4830 4831 namespace { 4832 /// Checker for the non-rectangular loops. Checks if the initializer or 4833 /// condition expression references loop counter variable. 4834 class LoopCounterRefChecker final 4835 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 4836 Sema &SemaRef; 4837 DSAStackTy &Stack; 4838 const ValueDecl *CurLCDecl = nullptr; 4839 const ValueDecl *DepDecl = nullptr; 4840 const ValueDecl *PrevDepDecl = nullptr; 4841 bool IsInitializer = true; 4842 unsigned BaseLoopId = 0; 4843 bool checkDecl(const Expr *E, const ValueDecl *VD) { 4844 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 4845 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 4846 << (IsInitializer ? 0 : 1); 4847 return false; 4848 } 4849 const auto &&Data = Stack.isLoopControlVariable(VD); 4850 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 4851 // The type of the loop iterator on which we depend may not have a random 4852 // access iterator type. 4853 if (Data.first && VD->getType()->isRecordType()) { 4854 SmallString<128> Name; 4855 llvm::raw_svector_ostream OS(Name); 4856 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4857 /*Qualified=*/true); 4858 SemaRef.Diag(E->getExprLoc(), 4859 diag::err_omp_wrong_dependency_iterator_type) 4860 << OS.str(); 4861 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 4862 return false; 4863 } 4864 if (Data.first && 4865 (DepDecl || (PrevDepDecl && 4866 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 4867 if (!DepDecl && PrevDepDecl) 4868 DepDecl = PrevDepDecl; 4869 SmallString<128> Name; 4870 llvm::raw_svector_ostream OS(Name); 4871 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4872 /*Qualified=*/true); 4873 SemaRef.Diag(E->getExprLoc(), 4874 diag::err_omp_invariant_or_linear_dependency) 4875 << OS.str(); 4876 return false; 4877 } 4878 if (Data.first) { 4879 DepDecl = VD; 4880 BaseLoopId = Data.first; 4881 } 4882 return Data.first; 4883 } 4884 4885 public: 4886 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4887 const ValueDecl *VD = E->getDecl(); 4888 if (isa<VarDecl>(VD)) 4889 return checkDecl(E, VD); 4890 return false; 4891 } 4892 bool VisitMemberExpr(const MemberExpr *E) { 4893 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 4894 const ValueDecl *VD = E->getMemberDecl(); 4895 return checkDecl(E, VD); 4896 } 4897 return false; 4898 } 4899 bool VisitStmt(const Stmt *S) { 4900 bool Res = true; 4901 for (const Stmt *Child : S->children()) 4902 Res = Child && Visit(Child) && Res; 4903 return Res; 4904 } 4905 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 4906 const ValueDecl *CurLCDecl, bool IsInitializer, 4907 const ValueDecl *PrevDepDecl = nullptr) 4908 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 4909 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 4910 unsigned getBaseLoopId() const { 4911 assert(CurLCDecl && "Expected loop dependency."); 4912 return BaseLoopId; 4913 } 4914 const ValueDecl *getDepDecl() const { 4915 assert(CurLCDecl && "Expected loop dependency."); 4916 return DepDecl; 4917 } 4918 }; 4919 } // namespace 4920 4921 Optional<unsigned> 4922 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 4923 bool IsInitializer) { 4924 // Check for the non-rectangular loops. 4925 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 4926 DepDecl); 4927 if (LoopStmtChecker.Visit(S)) { 4928 DepDecl = LoopStmtChecker.getDepDecl(); 4929 return LoopStmtChecker.getBaseLoopId(); 4930 } 4931 return llvm::None; 4932 } 4933 4934 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 4935 // Check init-expr for canonical loop form and save loop counter 4936 // variable - #Var and its initialization value - #LB. 4937 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 4938 // var = lb 4939 // integer-type var = lb 4940 // random-access-iterator-type var = lb 4941 // pointer-type var = lb 4942 // 4943 if (!S) { 4944 if (EmitDiags) { 4945 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 4946 } 4947 return true; 4948 } 4949 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4950 if (!ExprTemp->cleanupsHaveSideEffects()) 4951 S = ExprTemp->getSubExpr(); 4952 4953 InitSrcRange = S->getSourceRange(); 4954 if (Expr *E = dyn_cast<Expr>(S)) 4955 S = E->IgnoreParens(); 4956 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4957 if (BO->getOpcode() == BO_Assign) { 4958 Expr *LHS = BO->getLHS()->IgnoreParens(); 4959 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4960 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4961 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4962 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 4963 EmitDiags); 4964 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 4965 } 4966 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4967 if (ME->isArrow() && 4968 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4969 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 4970 EmitDiags); 4971 } 4972 } 4973 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4974 if (DS->isSingleDecl()) { 4975 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4976 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4977 // Accept non-canonical init form here but emit ext. warning. 4978 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4979 SemaRef.Diag(S->getBeginLoc(), 4980 diag::ext_omp_loop_not_canonical_init) 4981 << S->getSourceRange(); 4982 return setLCDeclAndLB( 4983 Var, 4984 buildDeclRefExpr(SemaRef, Var, 4985 Var->getType().getNonReferenceType(), 4986 DS->getBeginLoc()), 4987 Var->getInit(), EmitDiags); 4988 } 4989 } 4990 } 4991 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4992 if (CE->getOperator() == OO_Equal) { 4993 Expr *LHS = CE->getArg(0); 4994 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4995 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4996 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4997 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 4998 EmitDiags); 4999 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5000 } 5001 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5002 if (ME->isArrow() && 5003 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5004 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5005 EmitDiags); 5006 } 5007 } 5008 } 5009 5010 if (dependent() || SemaRef.CurContext->isDependentContext()) 5011 return false; 5012 if (EmitDiags) { 5013 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5014 << S->getSourceRange(); 5015 } 5016 return true; 5017 } 5018 5019 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5020 /// variable (which may be the loop variable) if possible. 5021 static const ValueDecl *getInitLCDecl(const Expr *E) { 5022 if (!E) 5023 return nullptr; 5024 E = getExprAsWritten(E); 5025 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5026 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5027 if ((Ctor->isCopyOrMoveConstructor() || 5028 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5029 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5030 E = CE->getArg(0)->IgnoreParenImpCasts(); 5031 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5032 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5033 return getCanonicalDecl(VD); 5034 } 5035 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5036 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5037 return getCanonicalDecl(ME->getMemberDecl()); 5038 return nullptr; 5039 } 5040 5041 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5042 // Check test-expr for canonical form, save upper-bound UB, flags for 5043 // less/greater and for strict/non-strict comparison. 5044 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5045 // var relational-op b 5046 // b relational-op var 5047 // 5048 if (!S) { 5049 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5050 return true; 5051 } 5052 S = getExprAsWritten(S); 5053 SourceLocation CondLoc = S->getBeginLoc(); 5054 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5055 if (BO->isRelationalOp()) { 5056 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5057 return setUB(BO->getRHS(), 5058 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5059 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5060 BO->getSourceRange(), BO->getOperatorLoc()); 5061 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5062 return setUB(BO->getLHS(), 5063 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5064 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5065 BO->getSourceRange(), BO->getOperatorLoc()); 5066 } else if (BO->getOpcode() == BO_NE) 5067 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5068 BO->getRHS() : BO->getLHS(), 5069 /*LessOp=*/llvm::None, 5070 /*StrictOp=*/true, 5071 BO->getSourceRange(), BO->getOperatorLoc()); 5072 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5073 if (CE->getNumArgs() == 2) { 5074 auto Op = CE->getOperator(); 5075 switch (Op) { 5076 case OO_Greater: 5077 case OO_GreaterEqual: 5078 case OO_Less: 5079 case OO_LessEqual: 5080 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5081 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5082 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5083 CE->getOperatorLoc()); 5084 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5085 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5086 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5087 CE->getOperatorLoc()); 5088 break; 5089 case OO_ExclaimEqual: 5090 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5091 CE->getArg(1) : CE->getArg(0), 5092 /*LessOp=*/llvm::None, 5093 /*StrictOp=*/true, 5094 CE->getSourceRange(), 5095 CE->getOperatorLoc()); 5096 break; 5097 default: 5098 break; 5099 } 5100 } 5101 } 5102 if (dependent() || SemaRef.CurContext->isDependentContext()) 5103 return false; 5104 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5105 << S->getSourceRange() << LCDecl; 5106 return true; 5107 } 5108 5109 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5110 // RHS of canonical loop form increment can be: 5111 // var + incr 5112 // incr + var 5113 // var - incr 5114 // 5115 RHS = RHS->IgnoreParenImpCasts(); 5116 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5117 if (BO->isAdditiveOp()) { 5118 bool IsAdd = BO->getOpcode() == BO_Add; 5119 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5120 return setStep(BO->getRHS(), !IsAdd); 5121 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5122 return setStep(BO->getLHS(), /*Subtract=*/false); 5123 } 5124 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5125 bool IsAdd = CE->getOperator() == OO_Plus; 5126 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5127 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5128 return setStep(CE->getArg(1), !IsAdd); 5129 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5130 return setStep(CE->getArg(0), /*Subtract=*/false); 5131 } 5132 } 5133 if (dependent() || SemaRef.CurContext->isDependentContext()) 5134 return false; 5135 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5136 << RHS->getSourceRange() << LCDecl; 5137 return true; 5138 } 5139 5140 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5141 // Check incr-expr for canonical loop form and return true if it 5142 // does not conform. 5143 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5144 // ++var 5145 // var++ 5146 // --var 5147 // var-- 5148 // var += incr 5149 // var -= incr 5150 // var = var + incr 5151 // var = incr + var 5152 // var = var - incr 5153 // 5154 if (!S) { 5155 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5156 return true; 5157 } 5158 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5159 if (!ExprTemp->cleanupsHaveSideEffects()) 5160 S = ExprTemp->getSubExpr(); 5161 5162 IncrementSrcRange = S->getSourceRange(); 5163 S = S->IgnoreParens(); 5164 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5165 if (UO->isIncrementDecrementOp() && 5166 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5167 return setStep(SemaRef 5168 .ActOnIntegerConstant(UO->getBeginLoc(), 5169 (UO->isDecrementOp() ? -1 : 1)) 5170 .get(), 5171 /*Subtract=*/false); 5172 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5173 switch (BO->getOpcode()) { 5174 case BO_AddAssign: 5175 case BO_SubAssign: 5176 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5177 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5178 break; 5179 case BO_Assign: 5180 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5181 return checkAndSetIncRHS(BO->getRHS()); 5182 break; 5183 default: 5184 break; 5185 } 5186 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5187 switch (CE->getOperator()) { 5188 case OO_PlusPlus: 5189 case OO_MinusMinus: 5190 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5191 return setStep(SemaRef 5192 .ActOnIntegerConstant( 5193 CE->getBeginLoc(), 5194 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5195 .get(), 5196 /*Subtract=*/false); 5197 break; 5198 case OO_PlusEqual: 5199 case OO_MinusEqual: 5200 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5201 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5202 break; 5203 case OO_Equal: 5204 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5205 return checkAndSetIncRHS(CE->getArg(1)); 5206 break; 5207 default: 5208 break; 5209 } 5210 } 5211 if (dependent() || SemaRef.CurContext->isDependentContext()) 5212 return false; 5213 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5214 << S->getSourceRange() << LCDecl; 5215 return true; 5216 } 5217 5218 static ExprResult 5219 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5220 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5221 if (SemaRef.CurContext->isDependentContext()) 5222 return ExprResult(Capture); 5223 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5224 return SemaRef.PerformImplicitConversion( 5225 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5226 /*AllowExplicit=*/true); 5227 auto I = Captures.find(Capture); 5228 if (I != Captures.end()) 5229 return buildCapture(SemaRef, Capture, I->second); 5230 DeclRefExpr *Ref = nullptr; 5231 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5232 Captures[Capture] = Ref; 5233 return Res; 5234 } 5235 5236 /// Build the expression to calculate the number of iterations. 5237 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5238 Scope *S, const bool LimitedType, 5239 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5240 ExprResult Diff; 5241 QualType VarType = LCDecl->getType().getNonReferenceType(); 5242 if (VarType->isIntegerType() || VarType->isPointerType() || 5243 SemaRef.getLangOpts().CPlusPlus) { 5244 // Upper - Lower 5245 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5246 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5247 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5248 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5249 if (!Upper || !Lower) 5250 return nullptr; 5251 5252 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5253 5254 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5255 // BuildBinOp already emitted error, this one is to point user to upper 5256 // and lower bound, and to tell what is passed to 'operator-'. 5257 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5258 << Upper->getSourceRange() << Lower->getSourceRange(); 5259 return nullptr; 5260 } 5261 } 5262 5263 if (!Diff.isUsable()) 5264 return nullptr; 5265 5266 // Upper - Lower [- 1] 5267 if (TestIsStrictOp) 5268 Diff = SemaRef.BuildBinOp( 5269 S, DefaultLoc, BO_Sub, Diff.get(), 5270 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5271 if (!Diff.isUsable()) 5272 return nullptr; 5273 5274 // Upper - Lower [- 1] + Step 5275 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5276 if (!NewStep.isUsable()) 5277 return nullptr; 5278 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5279 if (!Diff.isUsable()) 5280 return nullptr; 5281 5282 // Parentheses (for dumping/debugging purposes only). 5283 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5284 if (!Diff.isUsable()) 5285 return nullptr; 5286 5287 // (Upper - Lower [- 1] + Step) / Step 5288 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5289 if (!Diff.isUsable()) 5290 return nullptr; 5291 5292 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5293 QualType Type = Diff.get()->getType(); 5294 ASTContext &C = SemaRef.Context; 5295 bool UseVarType = VarType->hasIntegerRepresentation() && 5296 C.getTypeSize(Type) > C.getTypeSize(VarType); 5297 if (!Type->isIntegerType() || UseVarType) { 5298 unsigned NewSize = 5299 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5300 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5301 : Type->hasSignedIntegerRepresentation(); 5302 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5303 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5304 Diff = SemaRef.PerformImplicitConversion( 5305 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5306 if (!Diff.isUsable()) 5307 return nullptr; 5308 } 5309 } 5310 if (LimitedType) { 5311 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5312 if (NewSize != C.getTypeSize(Type)) { 5313 if (NewSize < C.getTypeSize(Type)) { 5314 assert(NewSize == 64 && "incorrect loop var size"); 5315 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5316 << InitSrcRange << ConditionSrcRange; 5317 } 5318 QualType NewType = C.getIntTypeForBitwidth( 5319 NewSize, Type->hasSignedIntegerRepresentation() || 5320 C.getTypeSize(Type) < NewSize); 5321 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5322 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5323 Sema::AA_Converting, true); 5324 if (!Diff.isUsable()) 5325 return nullptr; 5326 } 5327 } 5328 } 5329 5330 return Diff.get(); 5331 } 5332 5333 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5334 Scope *S, Expr *Cond, 5335 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5336 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5337 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5338 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5339 5340 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 5341 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 5342 if (!NewLB.isUsable() || !NewUB.isUsable()) 5343 return nullptr; 5344 5345 ExprResult CondExpr = 5346 SemaRef.BuildBinOp(S, DefaultLoc, 5347 TestIsLessOp.getValue() ? 5348 (TestIsStrictOp ? BO_LT : BO_LE) : 5349 (TestIsStrictOp ? BO_GT : BO_GE), 5350 NewLB.get(), NewUB.get()); 5351 if (CondExpr.isUsable()) { 5352 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5353 SemaRef.Context.BoolTy)) 5354 CondExpr = SemaRef.PerformImplicitConversion( 5355 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5356 /*AllowExplicit=*/true); 5357 } 5358 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5359 // Otherwise use original loop condition and evaluate it in runtime. 5360 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5361 } 5362 5363 /// Build reference expression to the counter be used for codegen. 5364 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5365 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5366 DSAStackTy &DSA) const { 5367 auto *VD = dyn_cast<VarDecl>(LCDecl); 5368 if (!VD) { 5369 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5370 DeclRefExpr *Ref = buildDeclRefExpr( 5371 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5372 const DSAStackTy::DSAVarData Data = 5373 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5374 // If the loop control decl is explicitly marked as private, do not mark it 5375 // as captured again. 5376 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5377 Captures.insert(std::make_pair(LCRef, Ref)); 5378 return Ref; 5379 } 5380 return cast<DeclRefExpr>(LCRef); 5381 } 5382 5383 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5384 if (LCDecl && !LCDecl->isInvalidDecl()) { 5385 QualType Type = LCDecl->getType().getNonReferenceType(); 5386 VarDecl *PrivateVar = buildVarDecl( 5387 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5388 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5389 isa<VarDecl>(LCDecl) 5390 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5391 : nullptr); 5392 if (PrivateVar->isInvalidDecl()) 5393 return nullptr; 5394 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5395 } 5396 return nullptr; 5397 } 5398 5399 /// Build initialization of the counter to be used for codegen. 5400 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5401 5402 /// Build step of the counter be used for codegen. 5403 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5404 5405 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5406 Scope *S, Expr *Counter, 5407 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5408 Expr *Inc, OverloadedOperatorKind OOK) { 5409 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5410 if (!Cnt) 5411 return nullptr; 5412 if (Inc) { 5413 assert((OOK == OO_Plus || OOK == OO_Minus) && 5414 "Expected only + or - operations for depend clauses."); 5415 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5416 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5417 if (!Cnt) 5418 return nullptr; 5419 } 5420 ExprResult Diff; 5421 QualType VarType = LCDecl->getType().getNonReferenceType(); 5422 if (VarType->isIntegerType() || VarType->isPointerType() || 5423 SemaRef.getLangOpts().CPlusPlus) { 5424 // Upper - Lower 5425 Expr *Upper = TestIsLessOp.getValue() 5426 ? Cnt 5427 : tryBuildCapture(SemaRef, UB, Captures).get(); 5428 Expr *Lower = TestIsLessOp.getValue() 5429 ? tryBuildCapture(SemaRef, LB, Captures).get() 5430 : Cnt; 5431 if (!Upper || !Lower) 5432 return nullptr; 5433 5434 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5435 5436 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5437 // BuildBinOp already emitted error, this one is to point user to upper 5438 // and lower bound, and to tell what is passed to 'operator-'. 5439 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5440 << Upper->getSourceRange() << Lower->getSourceRange(); 5441 return nullptr; 5442 } 5443 } 5444 5445 if (!Diff.isUsable()) 5446 return nullptr; 5447 5448 // Parentheses (for dumping/debugging purposes only). 5449 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5450 if (!Diff.isUsable()) 5451 return nullptr; 5452 5453 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5454 if (!NewStep.isUsable()) 5455 return nullptr; 5456 // (Upper - Lower) / Step 5457 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5458 if (!Diff.isUsable()) 5459 return nullptr; 5460 5461 return Diff.get(); 5462 } 5463 5464 /// Iteration space of a single for loop. 5465 struct LoopIterationSpace final { 5466 /// True if the condition operator is the strict compare operator (<, > or 5467 /// !=). 5468 bool IsStrictCompare = false; 5469 /// Condition of the loop. 5470 Expr *PreCond = nullptr; 5471 /// This expression calculates the number of iterations in the loop. 5472 /// It is always possible to calculate it before starting the loop. 5473 Expr *NumIterations = nullptr; 5474 /// The loop counter variable. 5475 Expr *CounterVar = nullptr; 5476 /// Private loop counter variable. 5477 Expr *PrivateCounterVar = nullptr; 5478 /// This is initializer for the initial value of #CounterVar. 5479 Expr *CounterInit = nullptr; 5480 /// This is step for the #CounterVar used to generate its update: 5481 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5482 Expr *CounterStep = nullptr; 5483 /// Should step be subtracted? 5484 bool Subtract = false; 5485 /// Source range of the loop init. 5486 SourceRange InitSrcRange; 5487 /// Source range of the loop condition. 5488 SourceRange CondSrcRange; 5489 /// Source range of the loop increment. 5490 SourceRange IncSrcRange; 5491 }; 5492 5493 } // namespace 5494 5495 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5496 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5497 assert(Init && "Expected loop in canonical form."); 5498 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5499 if (AssociatedLoops > 0 && 5500 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5501 DSAStack->loopStart(); 5502 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5503 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5504 if (ValueDecl *D = ISC.getLoopDecl()) { 5505 auto *VD = dyn_cast<VarDecl>(D); 5506 if (!VD) { 5507 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5508 VD = Private; 5509 } else { 5510 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5511 /*WithInit=*/false); 5512 VD = cast<VarDecl>(Ref->getDecl()); 5513 } 5514 } 5515 DSAStack->addLoopControlVariable(D, VD); 5516 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5517 if (LD != D->getCanonicalDecl()) { 5518 DSAStack->resetPossibleLoopCounter(); 5519 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5520 MarkDeclarationsReferencedInExpr( 5521 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5522 Var->getType().getNonLValueExprType(Context), 5523 ForLoc, /*RefersToCapture=*/true)); 5524 } 5525 } 5526 } 5527 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5528 } 5529 } 5530 5531 /// Called on a for stmt to check and extract its iteration space 5532 /// for further processing (such as collapsing). 5533 static bool checkOpenMPIterationSpace( 5534 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5535 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5536 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5537 Expr *OrderedLoopCountExpr, 5538 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5539 LoopIterationSpace &ResultIterSpace, 5540 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5541 // OpenMP [2.6, Canonical Loop Form] 5542 // for (init-expr; test-expr; incr-expr) structured-block 5543 auto *For = dyn_cast_or_null<ForStmt>(S); 5544 if (!For) { 5545 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5546 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5547 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5548 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5549 if (TotalNestedLoopCount > 1) { 5550 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5551 SemaRef.Diag(DSA.getConstructLoc(), 5552 diag::note_omp_collapse_ordered_expr) 5553 << 2 << CollapseLoopCountExpr->getSourceRange() 5554 << OrderedLoopCountExpr->getSourceRange(); 5555 else if (CollapseLoopCountExpr) 5556 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5557 diag::note_omp_collapse_ordered_expr) 5558 << 0 << CollapseLoopCountExpr->getSourceRange(); 5559 else 5560 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5561 diag::note_omp_collapse_ordered_expr) 5562 << 1 << OrderedLoopCountExpr->getSourceRange(); 5563 } 5564 return true; 5565 } 5566 assert(For->getBody()); 5567 5568 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 5569 5570 // Check init. 5571 Stmt *Init = For->getInit(); 5572 if (ISC.checkAndSetInit(Init)) 5573 return true; 5574 5575 bool HasErrors = false; 5576 5577 // Check loop variable's type. 5578 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5579 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5580 5581 // OpenMP [2.6, Canonical Loop Form] 5582 // Var is one of the following: 5583 // A variable of signed or unsigned integer type. 5584 // For C++, a variable of a random access iterator type. 5585 // For C, a variable of a pointer type. 5586 QualType VarType = LCDecl->getType().getNonReferenceType(); 5587 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5588 !VarType->isPointerType() && 5589 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5590 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5591 << SemaRef.getLangOpts().CPlusPlus; 5592 HasErrors = true; 5593 } 5594 5595 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5596 // a Construct 5597 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5598 // parallel for construct is (are) private. 5599 // The loop iteration variable in the associated for-loop of a simd 5600 // construct with just one associated for-loop is linear with a 5601 // constant-linear-step that is the increment of the associated for-loop. 5602 // Exclude loop var from the list of variables with implicitly defined data 5603 // sharing attributes. 5604 VarsWithImplicitDSA.erase(LCDecl); 5605 5606 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5607 // in a Construct, C/C++]. 5608 // The loop iteration variable in the associated for-loop of a simd 5609 // construct with just one associated for-loop may be listed in a linear 5610 // clause with a constant-linear-step that is the increment of the 5611 // associated for-loop. 5612 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5613 // parallel for construct may be listed in a private or lastprivate clause. 5614 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5615 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5616 // declared in the loop and it is predetermined as a private. 5617 OpenMPClauseKind PredeterminedCKind = 5618 isOpenMPSimdDirective(DKind) 5619 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5620 : OMPC_private; 5621 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5622 DVar.CKind != PredeterminedCKind) || 5623 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5624 isOpenMPDistributeDirective(DKind)) && 5625 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5626 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5627 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5628 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5629 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5630 << getOpenMPClauseName(PredeterminedCKind); 5631 if (DVar.RefExpr == nullptr) 5632 DVar.CKind = PredeterminedCKind; 5633 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5634 HasErrors = true; 5635 } else if (LoopDeclRefExpr != nullptr) { 5636 // Make the loop iteration variable private (for worksharing constructs), 5637 // linear (for simd directives with the only one associated loop) or 5638 // lastprivate (for simd directives with several collapsed or ordered 5639 // loops). 5640 if (DVar.CKind == OMPC_unknown) 5641 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5642 } 5643 5644 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5645 5646 // Check test-expr. 5647 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5648 5649 // Check incr-expr. 5650 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5651 } 5652 5653 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5654 return HasErrors; 5655 5656 // Build the loop's iteration space representation. 5657 ResultIterSpace.PreCond = 5658 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5659 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5660 DSA.getCurScope(), 5661 (isOpenMPWorksharingDirective(DKind) || 5662 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5663 Captures); 5664 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5665 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5666 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5667 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5668 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5669 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5670 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5671 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5672 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5673 5674 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5675 ResultIterSpace.NumIterations == nullptr || 5676 ResultIterSpace.CounterVar == nullptr || 5677 ResultIterSpace.PrivateCounterVar == nullptr || 5678 ResultIterSpace.CounterInit == nullptr || 5679 ResultIterSpace.CounterStep == nullptr); 5680 if (!HasErrors && DSA.isOrderedRegion()) { 5681 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5682 if (CurrentNestedLoopCount < 5683 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5684 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5685 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5686 DSA.getOrderedRegionParam().second->setLoopCounter( 5687 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5688 } 5689 } 5690 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5691 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5692 // Erroneous case - clause has some problems. 5693 continue; 5694 } 5695 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5696 Pair.second.size() <= CurrentNestedLoopCount) { 5697 // Erroneous case - clause has some problems. 5698 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5699 continue; 5700 } 5701 Expr *CntValue; 5702 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5703 CntValue = ISC.buildOrderedLoopData( 5704 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5705 Pair.first->getDependencyLoc()); 5706 else 5707 CntValue = ISC.buildOrderedLoopData( 5708 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5709 Pair.first->getDependencyLoc(), 5710 Pair.second[CurrentNestedLoopCount].first, 5711 Pair.second[CurrentNestedLoopCount].second); 5712 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5713 } 5714 } 5715 5716 return HasErrors; 5717 } 5718 5719 /// Build 'VarRef = Start. 5720 static ExprResult 5721 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5722 ExprResult Start, 5723 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5724 // Build 'VarRef = Start. 5725 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5726 if (!NewStart.isUsable()) 5727 return ExprError(); 5728 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5729 VarRef.get()->getType())) { 5730 NewStart = SemaRef.PerformImplicitConversion( 5731 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5732 /*AllowExplicit=*/true); 5733 if (!NewStart.isUsable()) 5734 return ExprError(); 5735 } 5736 5737 ExprResult Init = 5738 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5739 return Init; 5740 } 5741 5742 /// Build 'VarRef = Start + Iter * Step'. 5743 static ExprResult buildCounterUpdate( 5744 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5745 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5746 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5747 // Add parentheses (for debugging purposes only). 5748 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5749 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5750 !Step.isUsable()) 5751 return ExprError(); 5752 5753 ExprResult NewStep = Step; 5754 if (Captures) 5755 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5756 if (NewStep.isInvalid()) 5757 return ExprError(); 5758 ExprResult Update = 5759 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5760 if (!Update.isUsable()) 5761 return ExprError(); 5762 5763 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5764 // 'VarRef = Start (+|-) Iter * Step'. 5765 ExprResult NewStart = Start; 5766 if (Captures) 5767 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5768 if (NewStart.isInvalid()) 5769 return ExprError(); 5770 5771 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5772 ExprResult SavedUpdate = Update; 5773 ExprResult UpdateVal; 5774 if (VarRef.get()->getType()->isOverloadableType() || 5775 NewStart.get()->getType()->isOverloadableType() || 5776 Update.get()->getType()->isOverloadableType()) { 5777 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5778 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5779 Update = 5780 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5781 if (Update.isUsable()) { 5782 UpdateVal = 5783 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5784 VarRef.get(), SavedUpdate.get()); 5785 if (UpdateVal.isUsable()) { 5786 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5787 UpdateVal.get()); 5788 } 5789 } 5790 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5791 } 5792 5793 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5794 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5795 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5796 NewStart.get(), SavedUpdate.get()); 5797 if (!Update.isUsable()) 5798 return ExprError(); 5799 5800 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5801 VarRef.get()->getType())) { 5802 Update = SemaRef.PerformImplicitConversion( 5803 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5804 if (!Update.isUsable()) 5805 return ExprError(); 5806 } 5807 5808 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5809 } 5810 return Update; 5811 } 5812 5813 /// Convert integer expression \a E to make it have at least \a Bits 5814 /// bits. 5815 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5816 if (E == nullptr) 5817 return ExprError(); 5818 ASTContext &C = SemaRef.Context; 5819 QualType OldType = E->getType(); 5820 unsigned HasBits = C.getTypeSize(OldType); 5821 if (HasBits >= Bits) 5822 return ExprResult(E); 5823 // OK to convert to signed, because new type has more bits than old. 5824 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5825 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5826 true); 5827 } 5828 5829 /// Check if the given expression \a E is a constant integer that fits 5830 /// into \a Bits bits. 5831 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5832 if (E == nullptr) 5833 return false; 5834 llvm::APSInt Result; 5835 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5836 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5837 return false; 5838 } 5839 5840 /// Build preinits statement for the given declarations. 5841 static Stmt *buildPreInits(ASTContext &Context, 5842 MutableArrayRef<Decl *> PreInits) { 5843 if (!PreInits.empty()) { 5844 return new (Context) DeclStmt( 5845 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5846 SourceLocation(), SourceLocation()); 5847 } 5848 return nullptr; 5849 } 5850 5851 /// Build preinits statement for the given declarations. 5852 static Stmt * 5853 buildPreInits(ASTContext &Context, 5854 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5855 if (!Captures.empty()) { 5856 SmallVector<Decl *, 16> PreInits; 5857 for (const auto &Pair : Captures) 5858 PreInits.push_back(Pair.second->getDecl()); 5859 return buildPreInits(Context, PreInits); 5860 } 5861 return nullptr; 5862 } 5863 5864 /// Build postupdate expression for the given list of postupdates expressions. 5865 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5866 Expr *PostUpdate = nullptr; 5867 if (!PostUpdates.empty()) { 5868 for (Expr *E : PostUpdates) { 5869 Expr *ConvE = S.BuildCStyleCastExpr( 5870 E->getExprLoc(), 5871 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5872 E->getExprLoc(), E) 5873 .get(); 5874 PostUpdate = PostUpdate 5875 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5876 PostUpdate, ConvE) 5877 .get() 5878 : ConvE; 5879 } 5880 } 5881 return PostUpdate; 5882 } 5883 5884 /// Called on a for stmt to check itself and nested loops (if any). 5885 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5886 /// number of collapsed loops otherwise. 5887 static unsigned 5888 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5889 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5890 DSAStackTy &DSA, 5891 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5892 OMPLoopDirective::HelperExprs &Built) { 5893 unsigned NestedLoopCount = 1; 5894 if (CollapseLoopCountExpr) { 5895 // Found 'collapse' clause - calculate collapse number. 5896 Expr::EvalResult Result; 5897 if (!CollapseLoopCountExpr->isValueDependent() && 5898 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 5899 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5900 } else { 5901 Built.clear(/*size=*/1); 5902 return 1; 5903 } 5904 } 5905 unsigned OrderedLoopCount = 1; 5906 if (OrderedLoopCountExpr) { 5907 // Found 'ordered' clause - calculate collapse number. 5908 Expr::EvalResult EVResult; 5909 if (!OrderedLoopCountExpr->isValueDependent() && 5910 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 5911 SemaRef.getASTContext())) { 5912 llvm::APSInt Result = EVResult.Val.getInt(); 5913 if (Result.getLimitedValue() < NestedLoopCount) { 5914 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5915 diag::err_omp_wrong_ordered_loop_count) 5916 << OrderedLoopCountExpr->getSourceRange(); 5917 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5918 diag::note_collapse_loop_count) 5919 << CollapseLoopCountExpr->getSourceRange(); 5920 } 5921 OrderedLoopCount = Result.getLimitedValue(); 5922 } else { 5923 Built.clear(/*size=*/1); 5924 return 1; 5925 } 5926 } 5927 // This is helper routine for loop directives (e.g., 'for', 'simd', 5928 // 'for simd', etc.). 5929 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 5930 SmallVector<LoopIterationSpace, 4> IterSpaces( 5931 std::max(OrderedLoopCount, NestedLoopCount)); 5932 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 5933 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5934 if (checkOpenMPIterationSpace( 5935 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5936 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5937 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5938 Captures)) 5939 return 0; 5940 // Move on to the next nested for loop, or to the loop body. 5941 // OpenMP [2.8.1, simd construct, Restrictions] 5942 // All loops associated with the construct must be perfectly nested; that 5943 // is, there must be no intervening code nor any OpenMP directive between 5944 // any two loops. 5945 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5946 } 5947 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 5948 if (checkOpenMPIterationSpace( 5949 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5950 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5951 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5952 Captures)) 5953 return 0; 5954 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 5955 // Handle initialization of captured loop iterator variables. 5956 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 5957 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 5958 Captures[DRE] = DRE; 5959 } 5960 } 5961 // Move on to the next nested for loop, or to the loop body. 5962 // OpenMP [2.8.1, simd construct, Restrictions] 5963 // All loops associated with the construct must be perfectly nested; that 5964 // is, there must be no intervening code nor any OpenMP directive between 5965 // any two loops. 5966 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5967 } 5968 5969 Built.clear(/* size */ NestedLoopCount); 5970 5971 if (SemaRef.CurContext->isDependentContext()) 5972 return NestedLoopCount; 5973 5974 // An example of what is generated for the following code: 5975 // 5976 // #pragma omp simd collapse(2) ordered(2) 5977 // for (i = 0; i < NI; ++i) 5978 // for (k = 0; k < NK; ++k) 5979 // for (j = J0; j < NJ; j+=2) { 5980 // <loop body> 5981 // } 5982 // 5983 // We generate the code below. 5984 // Note: the loop body may be outlined in CodeGen. 5985 // Note: some counters may be C++ classes, operator- is used to find number of 5986 // iterations and operator+= to calculate counter value. 5987 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 5988 // or i64 is currently supported). 5989 // 5990 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 5991 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 5992 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 5993 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 5994 // // similar updates for vars in clauses (e.g. 'linear') 5995 // <loop body (using local i and j)> 5996 // } 5997 // i = NI; // assign final values of counters 5998 // j = NJ; 5999 // 6000 6001 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6002 // the iteration counts of the collapsed for loops. 6003 // Precondition tests if there is at least one iteration (all conditions are 6004 // true). 6005 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6006 Expr *N0 = IterSpaces[0].NumIterations; 6007 ExprResult LastIteration32 = 6008 widenIterationCount(/*Bits=*/32, 6009 SemaRef 6010 .PerformImplicitConversion( 6011 N0->IgnoreImpCasts(), N0->getType(), 6012 Sema::AA_Converting, /*AllowExplicit=*/true) 6013 .get(), 6014 SemaRef); 6015 ExprResult LastIteration64 = widenIterationCount( 6016 /*Bits=*/64, 6017 SemaRef 6018 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6019 Sema::AA_Converting, 6020 /*AllowExplicit=*/true) 6021 .get(), 6022 SemaRef); 6023 6024 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6025 return NestedLoopCount; 6026 6027 ASTContext &C = SemaRef.Context; 6028 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6029 6030 Scope *CurScope = DSA.getCurScope(); 6031 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6032 if (PreCond.isUsable()) { 6033 PreCond = 6034 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6035 PreCond.get(), IterSpaces[Cnt].PreCond); 6036 } 6037 Expr *N = IterSpaces[Cnt].NumIterations; 6038 SourceLocation Loc = N->getExprLoc(); 6039 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6040 if (LastIteration32.isUsable()) 6041 LastIteration32 = SemaRef.BuildBinOp( 6042 CurScope, Loc, BO_Mul, LastIteration32.get(), 6043 SemaRef 6044 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6045 Sema::AA_Converting, 6046 /*AllowExplicit=*/true) 6047 .get()); 6048 if (LastIteration64.isUsable()) 6049 LastIteration64 = SemaRef.BuildBinOp( 6050 CurScope, Loc, BO_Mul, LastIteration64.get(), 6051 SemaRef 6052 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6053 Sema::AA_Converting, 6054 /*AllowExplicit=*/true) 6055 .get()); 6056 } 6057 6058 // Choose either the 32-bit or 64-bit version. 6059 ExprResult LastIteration = LastIteration64; 6060 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6061 (LastIteration32.isUsable() && 6062 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6063 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6064 fitsInto( 6065 /*Bits=*/32, 6066 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6067 LastIteration64.get(), SemaRef)))) 6068 LastIteration = LastIteration32; 6069 QualType VType = LastIteration.get()->getType(); 6070 QualType RealVType = VType; 6071 QualType StrideVType = VType; 6072 if (isOpenMPTaskLoopDirective(DKind)) { 6073 VType = 6074 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6075 StrideVType = 6076 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6077 } 6078 6079 if (!LastIteration.isUsable()) 6080 return 0; 6081 6082 // Save the number of iterations. 6083 ExprResult NumIterations = LastIteration; 6084 { 6085 LastIteration = SemaRef.BuildBinOp( 6086 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6087 LastIteration.get(), 6088 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6089 if (!LastIteration.isUsable()) 6090 return 0; 6091 } 6092 6093 // Calculate the last iteration number beforehand instead of doing this on 6094 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6095 llvm::APSInt Result; 6096 bool IsConstant = 6097 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6098 ExprResult CalcLastIteration; 6099 if (!IsConstant) { 6100 ExprResult SaveRef = 6101 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6102 LastIteration = SaveRef; 6103 6104 // Prepare SaveRef + 1. 6105 NumIterations = SemaRef.BuildBinOp( 6106 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6107 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6108 if (!NumIterations.isUsable()) 6109 return 0; 6110 } 6111 6112 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6113 6114 // Build variables passed into runtime, necessary for worksharing directives. 6115 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6116 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6117 isOpenMPDistributeDirective(DKind)) { 6118 // Lower bound variable, initialized with zero. 6119 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6120 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6121 SemaRef.AddInitializerToDecl(LBDecl, 6122 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6123 /*DirectInit*/ false); 6124 6125 // Upper bound variable, initialized with last iteration number. 6126 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6127 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6128 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6129 /*DirectInit*/ false); 6130 6131 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6132 // This will be used to implement clause 'lastprivate'. 6133 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6134 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6135 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6136 SemaRef.AddInitializerToDecl(ILDecl, 6137 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6138 /*DirectInit*/ false); 6139 6140 // Stride variable returned by runtime (we initialize it to 1 by default). 6141 VarDecl *STDecl = 6142 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6143 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6144 SemaRef.AddInitializerToDecl(STDecl, 6145 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6146 /*DirectInit*/ false); 6147 6148 // Build expression: UB = min(UB, LastIteration) 6149 // It is necessary for CodeGen of directives with static scheduling. 6150 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6151 UB.get(), LastIteration.get()); 6152 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6153 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6154 LastIteration.get(), UB.get()); 6155 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6156 CondOp.get()); 6157 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6158 6159 // If we have a combined directive that combines 'distribute', 'for' or 6160 // 'simd' we need to be able to access the bounds of the schedule of the 6161 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6162 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6163 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6164 // Lower bound variable, initialized with zero. 6165 VarDecl *CombLBDecl = 6166 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6167 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6168 SemaRef.AddInitializerToDecl( 6169 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6170 /*DirectInit*/ false); 6171 6172 // Upper bound variable, initialized with last iteration number. 6173 VarDecl *CombUBDecl = 6174 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6175 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6176 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6177 /*DirectInit*/ false); 6178 6179 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6180 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6181 ExprResult CombCondOp = 6182 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6183 LastIteration.get(), CombUB.get()); 6184 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6185 CombCondOp.get()); 6186 CombEUB = 6187 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6188 6189 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6190 // We expect to have at least 2 more parameters than the 'parallel' 6191 // directive does - the lower and upper bounds of the previous schedule. 6192 assert(CD->getNumParams() >= 4 && 6193 "Unexpected number of parameters in loop combined directive"); 6194 6195 // Set the proper type for the bounds given what we learned from the 6196 // enclosed loops. 6197 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6198 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6199 6200 // Previous lower and upper bounds are obtained from the region 6201 // parameters. 6202 PrevLB = 6203 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6204 PrevUB = 6205 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6206 } 6207 } 6208 6209 // Build the iteration variable and its initialization before loop. 6210 ExprResult IV; 6211 ExprResult Init, CombInit; 6212 { 6213 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6214 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6215 Expr *RHS = 6216 (isOpenMPWorksharingDirective(DKind) || 6217 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6218 ? LB.get() 6219 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6220 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6221 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6222 6223 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6224 Expr *CombRHS = 6225 (isOpenMPWorksharingDirective(DKind) || 6226 isOpenMPTaskLoopDirective(DKind) || 6227 isOpenMPDistributeDirective(DKind)) 6228 ? CombLB.get() 6229 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6230 CombInit = 6231 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6232 CombInit = 6233 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6234 } 6235 } 6236 6237 bool UseStrictCompare = 6238 RealVType->hasUnsignedIntegerRepresentation() && 6239 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6240 return LIS.IsStrictCompare; 6241 }); 6242 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6243 // unsigned IV)) for worksharing loops. 6244 SourceLocation CondLoc = AStmt->getBeginLoc(); 6245 Expr *BoundUB = UB.get(); 6246 if (UseStrictCompare) { 6247 BoundUB = 6248 SemaRef 6249 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6250 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6251 .get(); 6252 BoundUB = 6253 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6254 } 6255 ExprResult Cond = 6256 (isOpenMPWorksharingDirective(DKind) || 6257 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6258 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6259 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6260 BoundUB) 6261 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6262 NumIterations.get()); 6263 ExprResult CombDistCond; 6264 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6265 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6266 NumIterations.get()); 6267 } 6268 6269 ExprResult CombCond; 6270 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6271 Expr *BoundCombUB = CombUB.get(); 6272 if (UseStrictCompare) { 6273 BoundCombUB = 6274 SemaRef 6275 .BuildBinOp( 6276 CurScope, CondLoc, BO_Add, BoundCombUB, 6277 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6278 .get(); 6279 BoundCombUB = 6280 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6281 .get(); 6282 } 6283 CombCond = 6284 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6285 IV.get(), BoundCombUB); 6286 } 6287 // Loop increment (IV = IV + 1) 6288 SourceLocation IncLoc = AStmt->getBeginLoc(); 6289 ExprResult Inc = 6290 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6291 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6292 if (!Inc.isUsable()) 6293 return 0; 6294 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6295 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6296 if (!Inc.isUsable()) 6297 return 0; 6298 6299 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6300 // Used for directives with static scheduling. 6301 // In combined construct, add combined version that use CombLB and CombUB 6302 // base variables for the update 6303 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6304 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6305 isOpenMPDistributeDirective(DKind)) { 6306 // LB + ST 6307 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6308 if (!NextLB.isUsable()) 6309 return 0; 6310 // LB = LB + ST 6311 NextLB = 6312 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6313 NextLB = 6314 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6315 if (!NextLB.isUsable()) 6316 return 0; 6317 // UB + ST 6318 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6319 if (!NextUB.isUsable()) 6320 return 0; 6321 // UB = UB + ST 6322 NextUB = 6323 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6324 NextUB = 6325 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6326 if (!NextUB.isUsable()) 6327 return 0; 6328 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6329 CombNextLB = 6330 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6331 if (!NextLB.isUsable()) 6332 return 0; 6333 // LB = LB + ST 6334 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6335 CombNextLB.get()); 6336 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6337 /*DiscardedValue*/ false); 6338 if (!CombNextLB.isUsable()) 6339 return 0; 6340 // UB + ST 6341 CombNextUB = 6342 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6343 if (!CombNextUB.isUsable()) 6344 return 0; 6345 // UB = UB + ST 6346 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6347 CombNextUB.get()); 6348 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6349 /*DiscardedValue*/ false); 6350 if (!CombNextUB.isUsable()) 6351 return 0; 6352 } 6353 } 6354 6355 // Create increment expression for distribute loop when combined in a same 6356 // directive with for as IV = IV + ST; ensure upper bound expression based 6357 // on PrevUB instead of NumIterations - used to implement 'for' when found 6358 // in combination with 'distribute', like in 'distribute parallel for' 6359 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6360 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6361 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6362 DistCond = SemaRef.BuildBinOp( 6363 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6364 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6365 6366 DistInc = 6367 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6368 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6369 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6370 DistInc.get()); 6371 DistInc = 6372 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6373 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6374 6375 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6376 // construct 6377 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6378 ExprResult IsUBGreater = 6379 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6380 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6381 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6382 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6383 CondOp.get()); 6384 PrevEUB = 6385 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6386 6387 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6388 // parallel for is in combination with a distribute directive with 6389 // schedule(static, 1) 6390 Expr *BoundPrevUB = PrevUB.get(); 6391 if (UseStrictCompare) { 6392 BoundPrevUB = 6393 SemaRef 6394 .BuildBinOp( 6395 CurScope, CondLoc, BO_Add, BoundPrevUB, 6396 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6397 .get(); 6398 BoundPrevUB = 6399 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6400 .get(); 6401 } 6402 ParForInDistCond = 6403 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6404 IV.get(), BoundPrevUB); 6405 } 6406 6407 // Build updates and final values of the loop counters. 6408 bool HasErrors = false; 6409 Built.Counters.resize(NestedLoopCount); 6410 Built.Inits.resize(NestedLoopCount); 6411 Built.Updates.resize(NestedLoopCount); 6412 Built.Finals.resize(NestedLoopCount); 6413 { 6414 // We implement the following algorithm for obtaining the 6415 // original loop iteration variable values based on the 6416 // value of the collapsed loop iteration variable IV. 6417 // 6418 // Let n+1 be the number of collapsed loops in the nest. 6419 // Iteration variables (I0, I1, .... In) 6420 // Iteration counts (N0, N1, ... Nn) 6421 // 6422 // Acc = IV; 6423 // 6424 // To compute Ik for loop k, 0 <= k <= n, generate: 6425 // Prod = N(k+1) * N(k+2) * ... * Nn; 6426 // Ik = Acc / Prod; 6427 // Acc -= Ik * Prod; 6428 // 6429 ExprResult Acc = IV; 6430 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6431 LoopIterationSpace &IS = IterSpaces[Cnt]; 6432 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6433 ExprResult Iter; 6434 6435 // Compute prod 6436 ExprResult Prod = 6437 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6438 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6439 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6440 IterSpaces[K].NumIterations); 6441 6442 // Iter = Acc / Prod 6443 // If there is at least one more inner loop to avoid 6444 // multiplication by 1. 6445 if (Cnt + 1 < NestedLoopCount) 6446 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6447 Acc.get(), Prod.get()); 6448 else 6449 Iter = Acc; 6450 if (!Iter.isUsable()) { 6451 HasErrors = true; 6452 break; 6453 } 6454 6455 // Update Acc: 6456 // Acc -= Iter * Prod 6457 // Check if there is at least one more inner loop to avoid 6458 // multiplication by 1. 6459 if (Cnt + 1 < NestedLoopCount) 6460 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6461 Iter.get(), Prod.get()); 6462 else 6463 Prod = Iter; 6464 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6465 Acc.get(), Prod.get()); 6466 6467 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6468 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6469 DeclRefExpr *CounterVar = buildDeclRefExpr( 6470 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6471 /*RefersToCapture=*/true); 6472 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6473 IS.CounterInit, Captures); 6474 if (!Init.isUsable()) { 6475 HasErrors = true; 6476 break; 6477 } 6478 ExprResult Update = buildCounterUpdate( 6479 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6480 IS.CounterStep, IS.Subtract, &Captures); 6481 if (!Update.isUsable()) { 6482 HasErrors = true; 6483 break; 6484 } 6485 6486 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6487 ExprResult Final = buildCounterUpdate( 6488 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 6489 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 6490 if (!Final.isUsable()) { 6491 HasErrors = true; 6492 break; 6493 } 6494 6495 if (!Update.isUsable() || !Final.isUsable()) { 6496 HasErrors = true; 6497 break; 6498 } 6499 // Save results 6500 Built.Counters[Cnt] = IS.CounterVar; 6501 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6502 Built.Inits[Cnt] = Init.get(); 6503 Built.Updates[Cnt] = Update.get(); 6504 Built.Finals[Cnt] = Final.get(); 6505 } 6506 } 6507 6508 if (HasErrors) 6509 return 0; 6510 6511 // Save results 6512 Built.IterationVarRef = IV.get(); 6513 Built.LastIteration = LastIteration.get(); 6514 Built.NumIterations = NumIterations.get(); 6515 Built.CalcLastIteration = SemaRef 6516 .ActOnFinishFullExpr(CalcLastIteration.get(), 6517 /*DiscardedValue*/ false) 6518 .get(); 6519 Built.PreCond = PreCond.get(); 6520 Built.PreInits = buildPreInits(C, Captures); 6521 Built.Cond = Cond.get(); 6522 Built.Init = Init.get(); 6523 Built.Inc = Inc.get(); 6524 Built.LB = LB.get(); 6525 Built.UB = UB.get(); 6526 Built.IL = IL.get(); 6527 Built.ST = ST.get(); 6528 Built.EUB = EUB.get(); 6529 Built.NLB = NextLB.get(); 6530 Built.NUB = NextUB.get(); 6531 Built.PrevLB = PrevLB.get(); 6532 Built.PrevUB = PrevUB.get(); 6533 Built.DistInc = DistInc.get(); 6534 Built.PrevEUB = PrevEUB.get(); 6535 Built.DistCombinedFields.LB = CombLB.get(); 6536 Built.DistCombinedFields.UB = CombUB.get(); 6537 Built.DistCombinedFields.EUB = CombEUB.get(); 6538 Built.DistCombinedFields.Init = CombInit.get(); 6539 Built.DistCombinedFields.Cond = CombCond.get(); 6540 Built.DistCombinedFields.NLB = CombNextLB.get(); 6541 Built.DistCombinedFields.NUB = CombNextUB.get(); 6542 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6543 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6544 6545 return NestedLoopCount; 6546 } 6547 6548 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6549 auto CollapseClauses = 6550 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6551 if (CollapseClauses.begin() != CollapseClauses.end()) 6552 return (*CollapseClauses.begin())->getNumForLoops(); 6553 return nullptr; 6554 } 6555 6556 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6557 auto OrderedClauses = 6558 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6559 if (OrderedClauses.begin() != OrderedClauses.end()) 6560 return (*OrderedClauses.begin())->getNumForLoops(); 6561 return nullptr; 6562 } 6563 6564 static bool checkSimdlenSafelenSpecified(Sema &S, 6565 const ArrayRef<OMPClause *> Clauses) { 6566 const OMPSafelenClause *Safelen = nullptr; 6567 const OMPSimdlenClause *Simdlen = nullptr; 6568 6569 for (const OMPClause *Clause : Clauses) { 6570 if (Clause->getClauseKind() == OMPC_safelen) 6571 Safelen = cast<OMPSafelenClause>(Clause); 6572 else if (Clause->getClauseKind() == OMPC_simdlen) 6573 Simdlen = cast<OMPSimdlenClause>(Clause); 6574 if (Safelen && Simdlen) 6575 break; 6576 } 6577 6578 if (Simdlen && Safelen) { 6579 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6580 const Expr *SafelenLength = Safelen->getSafelen(); 6581 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6582 SimdlenLength->isInstantiationDependent() || 6583 SimdlenLength->containsUnexpandedParameterPack()) 6584 return false; 6585 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6586 SafelenLength->isInstantiationDependent() || 6587 SafelenLength->containsUnexpandedParameterPack()) 6588 return false; 6589 Expr::EvalResult SimdlenResult, SafelenResult; 6590 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6591 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6592 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6593 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6594 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6595 // If both simdlen and safelen clauses are specified, the value of the 6596 // simdlen parameter must be less than or equal to the value of the safelen 6597 // parameter. 6598 if (SimdlenRes > SafelenRes) { 6599 S.Diag(SimdlenLength->getExprLoc(), 6600 diag::err_omp_wrong_simdlen_safelen_values) 6601 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6602 return true; 6603 } 6604 } 6605 return false; 6606 } 6607 6608 StmtResult 6609 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6610 SourceLocation StartLoc, SourceLocation EndLoc, 6611 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6612 if (!AStmt) 6613 return StmtError(); 6614 6615 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6616 OMPLoopDirective::HelperExprs B; 6617 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6618 // define the nested loops number. 6619 unsigned NestedLoopCount = checkOpenMPLoop( 6620 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6621 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6622 if (NestedLoopCount == 0) 6623 return StmtError(); 6624 6625 assert((CurContext->isDependentContext() || B.builtAll()) && 6626 "omp simd loop exprs were not built"); 6627 6628 if (!CurContext->isDependentContext()) { 6629 // Finalize the clauses that need pre-built expressions for CodeGen. 6630 for (OMPClause *C : Clauses) { 6631 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6632 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6633 B.NumIterations, *this, CurScope, 6634 DSAStack)) 6635 return StmtError(); 6636 } 6637 } 6638 6639 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6640 return StmtError(); 6641 6642 setFunctionHasBranchProtectedScope(); 6643 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6644 Clauses, AStmt, B); 6645 } 6646 6647 StmtResult 6648 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6649 SourceLocation StartLoc, SourceLocation EndLoc, 6650 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6651 if (!AStmt) 6652 return StmtError(); 6653 6654 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6655 OMPLoopDirective::HelperExprs B; 6656 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6657 // define the nested loops number. 6658 unsigned NestedLoopCount = checkOpenMPLoop( 6659 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6660 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6661 if (NestedLoopCount == 0) 6662 return StmtError(); 6663 6664 assert((CurContext->isDependentContext() || B.builtAll()) && 6665 "omp for loop exprs were not built"); 6666 6667 if (!CurContext->isDependentContext()) { 6668 // Finalize the clauses that need pre-built expressions for CodeGen. 6669 for (OMPClause *C : Clauses) { 6670 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6671 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6672 B.NumIterations, *this, CurScope, 6673 DSAStack)) 6674 return StmtError(); 6675 } 6676 } 6677 6678 setFunctionHasBranchProtectedScope(); 6679 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6680 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6681 } 6682 6683 StmtResult Sema::ActOnOpenMPForSimdDirective( 6684 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6685 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6686 if (!AStmt) 6687 return StmtError(); 6688 6689 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6690 OMPLoopDirective::HelperExprs B; 6691 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6692 // define the nested loops number. 6693 unsigned NestedLoopCount = 6694 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6695 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6696 VarsWithImplicitDSA, B); 6697 if (NestedLoopCount == 0) 6698 return StmtError(); 6699 6700 assert((CurContext->isDependentContext() || B.builtAll()) && 6701 "omp for simd loop exprs were not built"); 6702 6703 if (!CurContext->isDependentContext()) { 6704 // Finalize the clauses that need pre-built expressions for CodeGen. 6705 for (OMPClause *C : Clauses) { 6706 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6707 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6708 B.NumIterations, *this, CurScope, 6709 DSAStack)) 6710 return StmtError(); 6711 } 6712 } 6713 6714 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6715 return StmtError(); 6716 6717 setFunctionHasBranchProtectedScope(); 6718 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6719 Clauses, AStmt, B); 6720 } 6721 6722 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6723 Stmt *AStmt, 6724 SourceLocation StartLoc, 6725 SourceLocation EndLoc) { 6726 if (!AStmt) 6727 return StmtError(); 6728 6729 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6730 auto BaseStmt = AStmt; 6731 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6732 BaseStmt = CS->getCapturedStmt(); 6733 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6734 auto S = C->children(); 6735 if (S.begin() == S.end()) 6736 return StmtError(); 6737 // All associated statements must be '#pragma omp section' except for 6738 // the first one. 6739 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6740 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6741 if (SectionStmt) 6742 Diag(SectionStmt->getBeginLoc(), 6743 diag::err_omp_sections_substmt_not_section); 6744 return StmtError(); 6745 } 6746 cast<OMPSectionDirective>(SectionStmt) 6747 ->setHasCancel(DSAStack->isCancelRegion()); 6748 } 6749 } else { 6750 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6751 return StmtError(); 6752 } 6753 6754 setFunctionHasBranchProtectedScope(); 6755 6756 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6757 DSAStack->isCancelRegion()); 6758 } 6759 6760 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6761 SourceLocation StartLoc, 6762 SourceLocation EndLoc) { 6763 if (!AStmt) 6764 return StmtError(); 6765 6766 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6767 6768 setFunctionHasBranchProtectedScope(); 6769 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6770 6771 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6772 DSAStack->isCancelRegion()); 6773 } 6774 6775 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6776 Stmt *AStmt, 6777 SourceLocation StartLoc, 6778 SourceLocation EndLoc) { 6779 if (!AStmt) 6780 return StmtError(); 6781 6782 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6783 6784 setFunctionHasBranchProtectedScope(); 6785 6786 // OpenMP [2.7.3, single Construct, Restrictions] 6787 // The copyprivate clause must not be used with the nowait clause. 6788 const OMPClause *Nowait = nullptr; 6789 const OMPClause *Copyprivate = nullptr; 6790 for (const OMPClause *Clause : Clauses) { 6791 if (Clause->getClauseKind() == OMPC_nowait) 6792 Nowait = Clause; 6793 else if (Clause->getClauseKind() == OMPC_copyprivate) 6794 Copyprivate = Clause; 6795 if (Copyprivate && Nowait) { 6796 Diag(Copyprivate->getBeginLoc(), 6797 diag::err_omp_single_copyprivate_with_nowait); 6798 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6799 return StmtError(); 6800 } 6801 } 6802 6803 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6804 } 6805 6806 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6807 SourceLocation StartLoc, 6808 SourceLocation EndLoc) { 6809 if (!AStmt) 6810 return StmtError(); 6811 6812 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6813 6814 setFunctionHasBranchProtectedScope(); 6815 6816 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6817 } 6818 6819 StmtResult Sema::ActOnOpenMPCriticalDirective( 6820 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6821 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6822 if (!AStmt) 6823 return StmtError(); 6824 6825 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6826 6827 bool ErrorFound = false; 6828 llvm::APSInt Hint; 6829 SourceLocation HintLoc; 6830 bool DependentHint = false; 6831 for (const OMPClause *C : Clauses) { 6832 if (C->getClauseKind() == OMPC_hint) { 6833 if (!DirName.getName()) { 6834 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6835 ErrorFound = true; 6836 } 6837 Expr *E = cast<OMPHintClause>(C)->getHint(); 6838 if (E->isTypeDependent() || E->isValueDependent() || 6839 E->isInstantiationDependent()) { 6840 DependentHint = true; 6841 } else { 6842 Hint = E->EvaluateKnownConstInt(Context); 6843 HintLoc = C->getBeginLoc(); 6844 } 6845 } 6846 } 6847 if (ErrorFound) 6848 return StmtError(); 6849 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6850 if (Pair.first && DirName.getName() && !DependentHint) { 6851 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6852 Diag(StartLoc, diag::err_omp_critical_with_hint); 6853 if (HintLoc.isValid()) 6854 Diag(HintLoc, diag::note_omp_critical_hint_here) 6855 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6856 else 6857 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6858 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6859 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6860 << 1 6861 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6862 /*Radix=*/10, /*Signed=*/false); 6863 } else { 6864 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6865 } 6866 } 6867 } 6868 6869 setFunctionHasBranchProtectedScope(); 6870 6871 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6872 Clauses, AStmt); 6873 if (!Pair.first && DirName.getName() && !DependentHint) 6874 DSAStack->addCriticalWithHint(Dir, Hint); 6875 return Dir; 6876 } 6877 6878 StmtResult Sema::ActOnOpenMPParallelForDirective( 6879 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6880 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6881 if (!AStmt) 6882 return StmtError(); 6883 6884 auto *CS = cast<CapturedStmt>(AStmt); 6885 // 1.2.2 OpenMP Language Terminology 6886 // Structured block - An executable statement with a single entry at the 6887 // top and a single exit at the bottom. 6888 // The point of exit cannot be a branch out of the structured block. 6889 // longjmp() and throw() must not violate the entry/exit criteria. 6890 CS->getCapturedDecl()->setNothrow(); 6891 6892 OMPLoopDirective::HelperExprs B; 6893 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6894 // define the nested loops number. 6895 unsigned NestedLoopCount = 6896 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6897 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6898 VarsWithImplicitDSA, B); 6899 if (NestedLoopCount == 0) 6900 return StmtError(); 6901 6902 assert((CurContext->isDependentContext() || B.builtAll()) && 6903 "omp parallel for loop exprs were not built"); 6904 6905 if (!CurContext->isDependentContext()) { 6906 // Finalize the clauses that need pre-built expressions for CodeGen. 6907 for (OMPClause *C : Clauses) { 6908 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6909 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6910 B.NumIterations, *this, CurScope, 6911 DSAStack)) 6912 return StmtError(); 6913 } 6914 } 6915 6916 setFunctionHasBranchProtectedScope(); 6917 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6918 NestedLoopCount, Clauses, AStmt, B, 6919 DSAStack->isCancelRegion()); 6920 } 6921 6922 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6923 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6924 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6925 if (!AStmt) 6926 return StmtError(); 6927 6928 auto *CS = cast<CapturedStmt>(AStmt); 6929 // 1.2.2 OpenMP Language Terminology 6930 // Structured block - An executable statement with a single entry at the 6931 // top and a single exit at the bottom. 6932 // The point of exit cannot be a branch out of the structured block. 6933 // longjmp() and throw() must not violate the entry/exit criteria. 6934 CS->getCapturedDecl()->setNothrow(); 6935 6936 OMPLoopDirective::HelperExprs B; 6937 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6938 // define the nested loops number. 6939 unsigned NestedLoopCount = 6940 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 6941 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6942 VarsWithImplicitDSA, B); 6943 if (NestedLoopCount == 0) 6944 return StmtError(); 6945 6946 if (!CurContext->isDependentContext()) { 6947 // Finalize the clauses that need pre-built expressions for CodeGen. 6948 for (OMPClause *C : Clauses) { 6949 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6950 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6951 B.NumIterations, *this, CurScope, 6952 DSAStack)) 6953 return StmtError(); 6954 } 6955 } 6956 6957 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6958 return StmtError(); 6959 6960 setFunctionHasBranchProtectedScope(); 6961 return OMPParallelForSimdDirective::Create( 6962 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6963 } 6964 6965 StmtResult 6966 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 6967 Stmt *AStmt, SourceLocation StartLoc, 6968 SourceLocation EndLoc) { 6969 if (!AStmt) 6970 return StmtError(); 6971 6972 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6973 auto BaseStmt = AStmt; 6974 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6975 BaseStmt = CS->getCapturedStmt(); 6976 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6977 auto S = C->children(); 6978 if (S.begin() == S.end()) 6979 return StmtError(); 6980 // All associated statements must be '#pragma omp section' except for 6981 // the first one. 6982 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6983 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6984 if (SectionStmt) 6985 Diag(SectionStmt->getBeginLoc(), 6986 diag::err_omp_parallel_sections_substmt_not_section); 6987 return StmtError(); 6988 } 6989 cast<OMPSectionDirective>(SectionStmt) 6990 ->setHasCancel(DSAStack->isCancelRegion()); 6991 } 6992 } else { 6993 Diag(AStmt->getBeginLoc(), 6994 diag::err_omp_parallel_sections_not_compound_stmt); 6995 return StmtError(); 6996 } 6997 6998 setFunctionHasBranchProtectedScope(); 6999 7000 return OMPParallelSectionsDirective::Create( 7001 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7002 } 7003 7004 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7005 Stmt *AStmt, SourceLocation StartLoc, 7006 SourceLocation EndLoc) { 7007 if (!AStmt) 7008 return StmtError(); 7009 7010 auto *CS = cast<CapturedStmt>(AStmt); 7011 // 1.2.2 OpenMP Language Terminology 7012 // Structured block - An executable statement with a single entry at the 7013 // top and a single exit at the bottom. 7014 // The point of exit cannot be a branch out of the structured block. 7015 // longjmp() and throw() must not violate the entry/exit criteria. 7016 CS->getCapturedDecl()->setNothrow(); 7017 7018 setFunctionHasBranchProtectedScope(); 7019 7020 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7021 DSAStack->isCancelRegion()); 7022 } 7023 7024 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7025 SourceLocation EndLoc) { 7026 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7027 } 7028 7029 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7030 SourceLocation EndLoc) { 7031 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7032 } 7033 7034 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7035 SourceLocation EndLoc) { 7036 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7037 } 7038 7039 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7040 Stmt *AStmt, 7041 SourceLocation StartLoc, 7042 SourceLocation EndLoc) { 7043 if (!AStmt) 7044 return StmtError(); 7045 7046 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7047 7048 setFunctionHasBranchProtectedScope(); 7049 7050 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7051 AStmt, 7052 DSAStack->getTaskgroupReductionRef()); 7053 } 7054 7055 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7056 SourceLocation StartLoc, 7057 SourceLocation EndLoc) { 7058 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7059 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7060 } 7061 7062 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7063 Stmt *AStmt, 7064 SourceLocation StartLoc, 7065 SourceLocation EndLoc) { 7066 const OMPClause *DependFound = nullptr; 7067 const OMPClause *DependSourceClause = nullptr; 7068 const OMPClause *DependSinkClause = nullptr; 7069 bool ErrorFound = false; 7070 const OMPThreadsClause *TC = nullptr; 7071 const OMPSIMDClause *SC = nullptr; 7072 for (const OMPClause *C : Clauses) { 7073 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7074 DependFound = C; 7075 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7076 if (DependSourceClause) { 7077 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7078 << getOpenMPDirectiveName(OMPD_ordered) 7079 << getOpenMPClauseName(OMPC_depend) << 2; 7080 ErrorFound = true; 7081 } else { 7082 DependSourceClause = C; 7083 } 7084 if (DependSinkClause) { 7085 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7086 << 0; 7087 ErrorFound = true; 7088 } 7089 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7090 if (DependSourceClause) { 7091 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7092 << 1; 7093 ErrorFound = true; 7094 } 7095 DependSinkClause = C; 7096 } 7097 } else if (C->getClauseKind() == OMPC_threads) { 7098 TC = cast<OMPThreadsClause>(C); 7099 } else if (C->getClauseKind() == OMPC_simd) { 7100 SC = cast<OMPSIMDClause>(C); 7101 } 7102 } 7103 if (!ErrorFound && !SC && 7104 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7105 // OpenMP [2.8.1,simd Construct, Restrictions] 7106 // An ordered construct with the simd clause is the only OpenMP construct 7107 // that can appear in the simd region. 7108 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7109 ErrorFound = true; 7110 } else if (DependFound && (TC || SC)) { 7111 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7112 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7113 ErrorFound = true; 7114 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7115 Diag(DependFound->getBeginLoc(), 7116 diag::err_omp_ordered_directive_without_param); 7117 ErrorFound = true; 7118 } else if (TC || Clauses.empty()) { 7119 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7120 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7121 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7122 << (TC != nullptr); 7123 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7124 ErrorFound = true; 7125 } 7126 } 7127 if ((!AStmt && !DependFound) || ErrorFound) 7128 return StmtError(); 7129 7130 if (AStmt) { 7131 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7132 7133 setFunctionHasBranchProtectedScope(); 7134 } 7135 7136 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7137 } 7138 7139 namespace { 7140 /// Helper class for checking expression in 'omp atomic [update]' 7141 /// construct. 7142 class OpenMPAtomicUpdateChecker { 7143 /// Error results for atomic update expressions. 7144 enum ExprAnalysisErrorCode { 7145 /// A statement is not an expression statement. 7146 NotAnExpression, 7147 /// Expression is not builtin binary or unary operation. 7148 NotABinaryOrUnaryExpression, 7149 /// Unary operation is not post-/pre- increment/decrement operation. 7150 NotAnUnaryIncDecExpression, 7151 /// An expression is not of scalar type. 7152 NotAScalarType, 7153 /// A binary operation is not an assignment operation. 7154 NotAnAssignmentOp, 7155 /// RHS part of the binary operation is not a binary expression. 7156 NotABinaryExpression, 7157 /// RHS part is not additive/multiplicative/shift/biwise binary 7158 /// expression. 7159 NotABinaryOperator, 7160 /// RHS binary operation does not have reference to the updated LHS 7161 /// part. 7162 NotAnUpdateExpression, 7163 /// No errors is found. 7164 NoError 7165 }; 7166 /// Reference to Sema. 7167 Sema &SemaRef; 7168 /// A location for note diagnostics (when error is found). 7169 SourceLocation NoteLoc; 7170 /// 'x' lvalue part of the source atomic expression. 7171 Expr *X; 7172 /// 'expr' rvalue part of the source atomic expression. 7173 Expr *E; 7174 /// Helper expression of the form 7175 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7176 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7177 Expr *UpdateExpr; 7178 /// Is 'x' a LHS in a RHS part of full update expression. It is 7179 /// important for non-associative operations. 7180 bool IsXLHSInRHSPart; 7181 BinaryOperatorKind Op; 7182 SourceLocation OpLoc; 7183 /// true if the source expression is a postfix unary operation, false 7184 /// if it is a prefix unary operation. 7185 bool IsPostfixUpdate; 7186 7187 public: 7188 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7189 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7190 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7191 /// Check specified statement that it is suitable for 'atomic update' 7192 /// constructs and extract 'x', 'expr' and Operation from the original 7193 /// expression. If DiagId and NoteId == 0, then only check is performed 7194 /// without error notification. 7195 /// \param DiagId Diagnostic which should be emitted if error is found. 7196 /// \param NoteId Diagnostic note for the main error message. 7197 /// \return true if statement is not an update expression, false otherwise. 7198 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7199 /// Return the 'x' lvalue part of the source atomic expression. 7200 Expr *getX() const { return X; } 7201 /// Return the 'expr' rvalue part of the source atomic expression. 7202 Expr *getExpr() const { return E; } 7203 /// Return the update expression used in calculation of the updated 7204 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7205 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7206 Expr *getUpdateExpr() const { return UpdateExpr; } 7207 /// Return true if 'x' is LHS in RHS part of full update expression, 7208 /// false otherwise. 7209 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7210 7211 /// true if the source expression is a postfix unary operation, false 7212 /// if it is a prefix unary operation. 7213 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7214 7215 private: 7216 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7217 unsigned NoteId = 0); 7218 }; 7219 } // namespace 7220 7221 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7222 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7223 ExprAnalysisErrorCode ErrorFound = NoError; 7224 SourceLocation ErrorLoc, NoteLoc; 7225 SourceRange ErrorRange, NoteRange; 7226 // Allowed constructs are: 7227 // x = x binop expr; 7228 // x = expr binop x; 7229 if (AtomicBinOp->getOpcode() == BO_Assign) { 7230 X = AtomicBinOp->getLHS(); 7231 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7232 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7233 if (AtomicInnerBinOp->isMultiplicativeOp() || 7234 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7235 AtomicInnerBinOp->isBitwiseOp()) { 7236 Op = AtomicInnerBinOp->getOpcode(); 7237 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7238 Expr *LHS = AtomicInnerBinOp->getLHS(); 7239 Expr *RHS = AtomicInnerBinOp->getRHS(); 7240 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7241 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7242 /*Canonical=*/true); 7243 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7244 /*Canonical=*/true); 7245 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7246 /*Canonical=*/true); 7247 if (XId == LHSId) { 7248 E = RHS; 7249 IsXLHSInRHSPart = true; 7250 } else if (XId == RHSId) { 7251 E = LHS; 7252 IsXLHSInRHSPart = false; 7253 } else { 7254 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7255 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7256 NoteLoc = X->getExprLoc(); 7257 NoteRange = X->getSourceRange(); 7258 ErrorFound = NotAnUpdateExpression; 7259 } 7260 } else { 7261 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7262 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7263 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7264 NoteRange = SourceRange(NoteLoc, NoteLoc); 7265 ErrorFound = NotABinaryOperator; 7266 } 7267 } else { 7268 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7269 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7270 ErrorFound = NotABinaryExpression; 7271 } 7272 } else { 7273 ErrorLoc = AtomicBinOp->getExprLoc(); 7274 ErrorRange = AtomicBinOp->getSourceRange(); 7275 NoteLoc = AtomicBinOp->getOperatorLoc(); 7276 NoteRange = SourceRange(NoteLoc, NoteLoc); 7277 ErrorFound = NotAnAssignmentOp; 7278 } 7279 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7280 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7281 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7282 return true; 7283 } 7284 if (SemaRef.CurContext->isDependentContext()) 7285 E = X = UpdateExpr = nullptr; 7286 return ErrorFound != NoError; 7287 } 7288 7289 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7290 unsigned NoteId) { 7291 ExprAnalysisErrorCode ErrorFound = NoError; 7292 SourceLocation ErrorLoc, NoteLoc; 7293 SourceRange ErrorRange, NoteRange; 7294 // Allowed constructs are: 7295 // x++; 7296 // x--; 7297 // ++x; 7298 // --x; 7299 // x binop= expr; 7300 // x = x binop expr; 7301 // x = expr binop x; 7302 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7303 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7304 if (AtomicBody->getType()->isScalarType() || 7305 AtomicBody->isInstantiationDependent()) { 7306 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7307 AtomicBody->IgnoreParenImpCasts())) { 7308 // Check for Compound Assignment Operation 7309 Op = BinaryOperator::getOpForCompoundAssignment( 7310 AtomicCompAssignOp->getOpcode()); 7311 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7312 E = AtomicCompAssignOp->getRHS(); 7313 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7314 IsXLHSInRHSPart = true; 7315 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7316 AtomicBody->IgnoreParenImpCasts())) { 7317 // Check for Binary Operation 7318 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7319 return true; 7320 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7321 AtomicBody->IgnoreParenImpCasts())) { 7322 // Check for Unary Operation 7323 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7324 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7325 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7326 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7327 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7328 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7329 IsXLHSInRHSPart = true; 7330 } else { 7331 ErrorFound = NotAnUnaryIncDecExpression; 7332 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7333 ErrorRange = AtomicUnaryOp->getSourceRange(); 7334 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7335 NoteRange = SourceRange(NoteLoc, NoteLoc); 7336 } 7337 } else if (!AtomicBody->isInstantiationDependent()) { 7338 ErrorFound = NotABinaryOrUnaryExpression; 7339 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7340 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7341 } 7342 } else { 7343 ErrorFound = NotAScalarType; 7344 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7345 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7346 } 7347 } else { 7348 ErrorFound = NotAnExpression; 7349 NoteLoc = ErrorLoc = S->getBeginLoc(); 7350 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7351 } 7352 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7353 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7354 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7355 return true; 7356 } 7357 if (SemaRef.CurContext->isDependentContext()) 7358 E = X = UpdateExpr = nullptr; 7359 if (ErrorFound == NoError && E && X) { 7360 // Build an update expression of form 'OpaqueValueExpr(x) binop 7361 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7362 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7363 auto *OVEX = new (SemaRef.getASTContext()) 7364 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7365 auto *OVEExpr = new (SemaRef.getASTContext()) 7366 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7367 ExprResult Update = 7368 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7369 IsXLHSInRHSPart ? OVEExpr : OVEX); 7370 if (Update.isInvalid()) 7371 return true; 7372 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7373 Sema::AA_Casting); 7374 if (Update.isInvalid()) 7375 return true; 7376 UpdateExpr = Update.get(); 7377 } 7378 return ErrorFound != NoError; 7379 } 7380 7381 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7382 Stmt *AStmt, 7383 SourceLocation StartLoc, 7384 SourceLocation EndLoc) { 7385 if (!AStmt) 7386 return StmtError(); 7387 7388 auto *CS = cast<CapturedStmt>(AStmt); 7389 // 1.2.2 OpenMP Language Terminology 7390 // Structured block - An executable statement with a single entry at the 7391 // top and a single exit at the bottom. 7392 // The point of exit cannot be a branch out of the structured block. 7393 // longjmp() and throw() must not violate the entry/exit criteria. 7394 OpenMPClauseKind AtomicKind = OMPC_unknown; 7395 SourceLocation AtomicKindLoc; 7396 for (const OMPClause *C : Clauses) { 7397 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7398 C->getClauseKind() == OMPC_update || 7399 C->getClauseKind() == OMPC_capture) { 7400 if (AtomicKind != OMPC_unknown) { 7401 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7402 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7403 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7404 << getOpenMPClauseName(AtomicKind); 7405 } else { 7406 AtomicKind = C->getClauseKind(); 7407 AtomicKindLoc = C->getBeginLoc(); 7408 } 7409 } 7410 } 7411 7412 Stmt *Body = CS->getCapturedStmt(); 7413 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7414 Body = EWC->getSubExpr(); 7415 7416 Expr *X = nullptr; 7417 Expr *V = nullptr; 7418 Expr *E = nullptr; 7419 Expr *UE = nullptr; 7420 bool IsXLHSInRHSPart = false; 7421 bool IsPostfixUpdate = false; 7422 // OpenMP [2.12.6, atomic Construct] 7423 // In the next expressions: 7424 // * x and v (as applicable) are both l-value expressions with scalar type. 7425 // * During the execution of an atomic region, multiple syntactic 7426 // occurrences of x must designate the same storage location. 7427 // * Neither of v and expr (as applicable) may access the storage location 7428 // designated by x. 7429 // * Neither of x and expr (as applicable) may access the storage location 7430 // designated by v. 7431 // * expr is an expression with scalar type. 7432 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7433 // * binop, binop=, ++, and -- are not overloaded operators. 7434 // * The expression x binop expr must be numerically equivalent to x binop 7435 // (expr). This requirement is satisfied if the operators in expr have 7436 // precedence greater than binop, or by using parentheses around expr or 7437 // subexpressions of expr. 7438 // * The expression expr binop x must be numerically equivalent to (expr) 7439 // binop x. This requirement is satisfied if the operators in expr have 7440 // precedence equal to or greater than binop, or by using parentheses around 7441 // expr or subexpressions of expr. 7442 // * For forms that allow multiple occurrences of x, the number of times 7443 // that x is evaluated is unspecified. 7444 if (AtomicKind == OMPC_read) { 7445 enum { 7446 NotAnExpression, 7447 NotAnAssignmentOp, 7448 NotAScalarType, 7449 NotAnLValue, 7450 NoError 7451 } ErrorFound = NoError; 7452 SourceLocation ErrorLoc, NoteLoc; 7453 SourceRange ErrorRange, NoteRange; 7454 // If clause is read: 7455 // v = x; 7456 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7457 const auto *AtomicBinOp = 7458 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7459 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7460 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7461 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7462 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7463 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7464 if (!X->isLValue() || !V->isLValue()) { 7465 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7466 ErrorFound = NotAnLValue; 7467 ErrorLoc = AtomicBinOp->getExprLoc(); 7468 ErrorRange = AtomicBinOp->getSourceRange(); 7469 NoteLoc = NotLValueExpr->getExprLoc(); 7470 NoteRange = NotLValueExpr->getSourceRange(); 7471 } 7472 } else if (!X->isInstantiationDependent() || 7473 !V->isInstantiationDependent()) { 7474 const Expr *NotScalarExpr = 7475 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7476 ? V 7477 : X; 7478 ErrorFound = NotAScalarType; 7479 ErrorLoc = AtomicBinOp->getExprLoc(); 7480 ErrorRange = AtomicBinOp->getSourceRange(); 7481 NoteLoc = NotScalarExpr->getExprLoc(); 7482 NoteRange = NotScalarExpr->getSourceRange(); 7483 } 7484 } else if (!AtomicBody->isInstantiationDependent()) { 7485 ErrorFound = NotAnAssignmentOp; 7486 ErrorLoc = AtomicBody->getExprLoc(); 7487 ErrorRange = AtomicBody->getSourceRange(); 7488 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7489 : AtomicBody->getExprLoc(); 7490 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7491 : AtomicBody->getSourceRange(); 7492 } 7493 } else { 7494 ErrorFound = NotAnExpression; 7495 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7496 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7497 } 7498 if (ErrorFound != NoError) { 7499 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7500 << ErrorRange; 7501 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7502 << NoteRange; 7503 return StmtError(); 7504 } 7505 if (CurContext->isDependentContext()) 7506 V = X = nullptr; 7507 } else if (AtomicKind == OMPC_write) { 7508 enum { 7509 NotAnExpression, 7510 NotAnAssignmentOp, 7511 NotAScalarType, 7512 NotAnLValue, 7513 NoError 7514 } ErrorFound = NoError; 7515 SourceLocation ErrorLoc, NoteLoc; 7516 SourceRange ErrorRange, NoteRange; 7517 // If clause is write: 7518 // x = expr; 7519 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7520 const auto *AtomicBinOp = 7521 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7522 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7523 X = AtomicBinOp->getLHS(); 7524 E = AtomicBinOp->getRHS(); 7525 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7526 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 7527 if (!X->isLValue()) { 7528 ErrorFound = NotAnLValue; 7529 ErrorLoc = AtomicBinOp->getExprLoc(); 7530 ErrorRange = AtomicBinOp->getSourceRange(); 7531 NoteLoc = X->getExprLoc(); 7532 NoteRange = X->getSourceRange(); 7533 } 7534 } else if (!X->isInstantiationDependent() || 7535 !E->isInstantiationDependent()) { 7536 const Expr *NotScalarExpr = 7537 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7538 ? E 7539 : X; 7540 ErrorFound = NotAScalarType; 7541 ErrorLoc = AtomicBinOp->getExprLoc(); 7542 ErrorRange = AtomicBinOp->getSourceRange(); 7543 NoteLoc = NotScalarExpr->getExprLoc(); 7544 NoteRange = NotScalarExpr->getSourceRange(); 7545 } 7546 } else if (!AtomicBody->isInstantiationDependent()) { 7547 ErrorFound = NotAnAssignmentOp; 7548 ErrorLoc = AtomicBody->getExprLoc(); 7549 ErrorRange = AtomicBody->getSourceRange(); 7550 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7551 : AtomicBody->getExprLoc(); 7552 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7553 : AtomicBody->getSourceRange(); 7554 } 7555 } else { 7556 ErrorFound = NotAnExpression; 7557 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7558 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7559 } 7560 if (ErrorFound != NoError) { 7561 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7562 << ErrorRange; 7563 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7564 << NoteRange; 7565 return StmtError(); 7566 } 7567 if (CurContext->isDependentContext()) 7568 E = X = nullptr; 7569 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7570 // If clause is update: 7571 // x++; 7572 // x--; 7573 // ++x; 7574 // --x; 7575 // x binop= expr; 7576 // x = x binop expr; 7577 // x = expr binop x; 7578 OpenMPAtomicUpdateChecker Checker(*this); 7579 if (Checker.checkStatement( 7580 Body, (AtomicKind == OMPC_update) 7581 ? diag::err_omp_atomic_update_not_expression_statement 7582 : diag::err_omp_atomic_not_expression_statement, 7583 diag::note_omp_atomic_update)) 7584 return StmtError(); 7585 if (!CurContext->isDependentContext()) { 7586 E = Checker.getExpr(); 7587 X = Checker.getX(); 7588 UE = Checker.getUpdateExpr(); 7589 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7590 } 7591 } else if (AtomicKind == OMPC_capture) { 7592 enum { 7593 NotAnAssignmentOp, 7594 NotACompoundStatement, 7595 NotTwoSubstatements, 7596 NotASpecificExpression, 7597 NoError 7598 } ErrorFound = NoError; 7599 SourceLocation ErrorLoc, NoteLoc; 7600 SourceRange ErrorRange, NoteRange; 7601 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7602 // If clause is a capture: 7603 // v = x++; 7604 // v = x--; 7605 // v = ++x; 7606 // v = --x; 7607 // v = x binop= expr; 7608 // v = x = x binop expr; 7609 // v = x = expr binop x; 7610 const auto *AtomicBinOp = 7611 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7612 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7613 V = AtomicBinOp->getLHS(); 7614 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7615 OpenMPAtomicUpdateChecker Checker(*this); 7616 if (Checker.checkStatement( 7617 Body, diag::err_omp_atomic_capture_not_expression_statement, 7618 diag::note_omp_atomic_update)) 7619 return StmtError(); 7620 E = Checker.getExpr(); 7621 X = Checker.getX(); 7622 UE = Checker.getUpdateExpr(); 7623 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7624 IsPostfixUpdate = Checker.isPostfixUpdate(); 7625 } else if (!AtomicBody->isInstantiationDependent()) { 7626 ErrorLoc = AtomicBody->getExprLoc(); 7627 ErrorRange = AtomicBody->getSourceRange(); 7628 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7629 : AtomicBody->getExprLoc(); 7630 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7631 : AtomicBody->getSourceRange(); 7632 ErrorFound = NotAnAssignmentOp; 7633 } 7634 if (ErrorFound != NoError) { 7635 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7636 << ErrorRange; 7637 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7638 return StmtError(); 7639 } 7640 if (CurContext->isDependentContext()) 7641 UE = V = E = X = nullptr; 7642 } else { 7643 // If clause is a capture: 7644 // { v = x; x = expr; } 7645 // { v = x; x++; } 7646 // { v = x; x--; } 7647 // { v = x; ++x; } 7648 // { v = x; --x; } 7649 // { v = x; x binop= expr; } 7650 // { v = x; x = x binop expr; } 7651 // { v = x; x = expr binop x; } 7652 // { x++; v = x; } 7653 // { x--; v = x; } 7654 // { ++x; v = x; } 7655 // { --x; v = x; } 7656 // { x binop= expr; v = x; } 7657 // { x = x binop expr; v = x; } 7658 // { x = expr binop x; v = x; } 7659 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7660 // Check that this is { expr1; expr2; } 7661 if (CS->size() == 2) { 7662 Stmt *First = CS->body_front(); 7663 Stmt *Second = CS->body_back(); 7664 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7665 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7666 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7667 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7668 // Need to find what subexpression is 'v' and what is 'x'. 7669 OpenMPAtomicUpdateChecker Checker(*this); 7670 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7671 BinaryOperator *BinOp = nullptr; 7672 if (IsUpdateExprFound) { 7673 BinOp = dyn_cast<BinaryOperator>(First); 7674 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7675 } 7676 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7677 // { v = x; x++; } 7678 // { v = x; x--; } 7679 // { v = x; ++x; } 7680 // { v = x; --x; } 7681 // { v = x; x binop= expr; } 7682 // { v = x; x = x binop expr; } 7683 // { v = x; x = expr binop x; } 7684 // Check that the first expression has form v = x. 7685 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7686 llvm::FoldingSetNodeID XId, PossibleXId; 7687 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7688 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7689 IsUpdateExprFound = XId == PossibleXId; 7690 if (IsUpdateExprFound) { 7691 V = BinOp->getLHS(); 7692 X = Checker.getX(); 7693 E = Checker.getExpr(); 7694 UE = Checker.getUpdateExpr(); 7695 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7696 IsPostfixUpdate = true; 7697 } 7698 } 7699 if (!IsUpdateExprFound) { 7700 IsUpdateExprFound = !Checker.checkStatement(First); 7701 BinOp = nullptr; 7702 if (IsUpdateExprFound) { 7703 BinOp = dyn_cast<BinaryOperator>(Second); 7704 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7705 } 7706 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7707 // { x++; v = x; } 7708 // { x--; v = x; } 7709 // { ++x; v = x; } 7710 // { --x; v = x; } 7711 // { x binop= expr; v = x; } 7712 // { x = x binop expr; v = x; } 7713 // { x = expr binop x; v = x; } 7714 // Check that the second expression has form v = x. 7715 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7716 llvm::FoldingSetNodeID XId, PossibleXId; 7717 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7718 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7719 IsUpdateExprFound = XId == PossibleXId; 7720 if (IsUpdateExprFound) { 7721 V = BinOp->getLHS(); 7722 X = Checker.getX(); 7723 E = Checker.getExpr(); 7724 UE = Checker.getUpdateExpr(); 7725 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7726 IsPostfixUpdate = false; 7727 } 7728 } 7729 } 7730 if (!IsUpdateExprFound) { 7731 // { v = x; x = expr; } 7732 auto *FirstExpr = dyn_cast<Expr>(First); 7733 auto *SecondExpr = dyn_cast<Expr>(Second); 7734 if (!FirstExpr || !SecondExpr || 7735 !(FirstExpr->isInstantiationDependent() || 7736 SecondExpr->isInstantiationDependent())) { 7737 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7738 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7739 ErrorFound = NotAnAssignmentOp; 7740 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7741 : First->getBeginLoc(); 7742 NoteRange = ErrorRange = FirstBinOp 7743 ? FirstBinOp->getSourceRange() 7744 : SourceRange(ErrorLoc, ErrorLoc); 7745 } else { 7746 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7747 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7748 ErrorFound = NotAnAssignmentOp; 7749 NoteLoc = ErrorLoc = SecondBinOp 7750 ? SecondBinOp->getOperatorLoc() 7751 : Second->getBeginLoc(); 7752 NoteRange = ErrorRange = 7753 SecondBinOp ? SecondBinOp->getSourceRange() 7754 : SourceRange(ErrorLoc, ErrorLoc); 7755 } else { 7756 Expr *PossibleXRHSInFirst = 7757 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7758 Expr *PossibleXLHSInSecond = 7759 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7760 llvm::FoldingSetNodeID X1Id, X2Id; 7761 PossibleXRHSInFirst->Profile(X1Id, Context, 7762 /*Canonical=*/true); 7763 PossibleXLHSInSecond->Profile(X2Id, Context, 7764 /*Canonical=*/true); 7765 IsUpdateExprFound = X1Id == X2Id; 7766 if (IsUpdateExprFound) { 7767 V = FirstBinOp->getLHS(); 7768 X = SecondBinOp->getLHS(); 7769 E = SecondBinOp->getRHS(); 7770 UE = nullptr; 7771 IsXLHSInRHSPart = false; 7772 IsPostfixUpdate = true; 7773 } else { 7774 ErrorFound = NotASpecificExpression; 7775 ErrorLoc = FirstBinOp->getExprLoc(); 7776 ErrorRange = FirstBinOp->getSourceRange(); 7777 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7778 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7779 } 7780 } 7781 } 7782 } 7783 } 7784 } else { 7785 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7786 NoteRange = ErrorRange = 7787 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7788 ErrorFound = NotTwoSubstatements; 7789 } 7790 } else { 7791 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7792 NoteRange = ErrorRange = 7793 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7794 ErrorFound = NotACompoundStatement; 7795 } 7796 if (ErrorFound != NoError) { 7797 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7798 << ErrorRange; 7799 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7800 return StmtError(); 7801 } 7802 if (CurContext->isDependentContext()) 7803 UE = V = E = X = nullptr; 7804 } 7805 } 7806 7807 setFunctionHasBranchProtectedScope(); 7808 7809 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7810 X, V, E, UE, IsXLHSInRHSPart, 7811 IsPostfixUpdate); 7812 } 7813 7814 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7815 Stmt *AStmt, 7816 SourceLocation StartLoc, 7817 SourceLocation EndLoc) { 7818 if (!AStmt) 7819 return StmtError(); 7820 7821 auto *CS = cast<CapturedStmt>(AStmt); 7822 // 1.2.2 OpenMP Language Terminology 7823 // Structured block - An executable statement with a single entry at the 7824 // top and a single exit at the bottom. 7825 // The point of exit cannot be a branch out of the structured block. 7826 // longjmp() and throw() must not violate the entry/exit criteria. 7827 CS->getCapturedDecl()->setNothrow(); 7828 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7829 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7830 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7831 // 1.2.2 OpenMP Language Terminology 7832 // Structured block - An executable statement with a single entry at the 7833 // top and a single exit at the bottom. 7834 // The point of exit cannot be a branch out of the structured block. 7835 // longjmp() and throw() must not violate the entry/exit criteria. 7836 CS->getCapturedDecl()->setNothrow(); 7837 } 7838 7839 // OpenMP [2.16, Nesting of Regions] 7840 // If specified, a teams construct must be contained within a target 7841 // construct. That target construct must contain no statements or directives 7842 // outside of the teams construct. 7843 if (DSAStack->hasInnerTeamsRegion()) { 7844 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7845 bool OMPTeamsFound = true; 7846 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7847 auto I = CS->body_begin(); 7848 while (I != CS->body_end()) { 7849 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7850 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7851 OMPTeamsFound) { 7852 7853 OMPTeamsFound = false; 7854 break; 7855 } 7856 ++I; 7857 } 7858 assert(I != CS->body_end() && "Not found statement"); 7859 S = *I; 7860 } else { 7861 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7862 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7863 } 7864 if (!OMPTeamsFound) { 7865 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7866 Diag(DSAStack->getInnerTeamsRegionLoc(), 7867 diag::note_omp_nested_teams_construct_here); 7868 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7869 << isa<OMPExecutableDirective>(S); 7870 return StmtError(); 7871 } 7872 } 7873 7874 setFunctionHasBranchProtectedScope(); 7875 7876 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7877 } 7878 7879 StmtResult 7880 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7881 Stmt *AStmt, SourceLocation StartLoc, 7882 SourceLocation EndLoc) { 7883 if (!AStmt) 7884 return StmtError(); 7885 7886 auto *CS = cast<CapturedStmt>(AStmt); 7887 // 1.2.2 OpenMP Language Terminology 7888 // Structured block - An executable statement with a single entry at the 7889 // top and a single exit at the bottom. 7890 // The point of exit cannot be a branch out of the structured block. 7891 // longjmp() and throw() must not violate the entry/exit criteria. 7892 CS->getCapturedDecl()->setNothrow(); 7893 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7894 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7895 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7896 // 1.2.2 OpenMP Language Terminology 7897 // Structured block - An executable statement with a single entry at the 7898 // top and a single exit at the bottom. 7899 // The point of exit cannot be a branch out of the structured block. 7900 // longjmp() and throw() must not violate the entry/exit criteria. 7901 CS->getCapturedDecl()->setNothrow(); 7902 } 7903 7904 setFunctionHasBranchProtectedScope(); 7905 7906 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7907 AStmt); 7908 } 7909 7910 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7911 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7912 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7913 if (!AStmt) 7914 return StmtError(); 7915 7916 auto *CS = cast<CapturedStmt>(AStmt); 7917 // 1.2.2 OpenMP Language Terminology 7918 // Structured block - An executable statement with a single entry at the 7919 // top and a single exit at the bottom. 7920 // The point of exit cannot be a branch out of the structured block. 7921 // longjmp() and throw() must not violate the entry/exit criteria. 7922 CS->getCapturedDecl()->setNothrow(); 7923 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7924 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7925 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7926 // 1.2.2 OpenMP Language Terminology 7927 // Structured block - An executable statement with a single entry at the 7928 // top and a single exit at the bottom. 7929 // The point of exit cannot be a branch out of the structured block. 7930 // longjmp() and throw() must not violate the entry/exit criteria. 7931 CS->getCapturedDecl()->setNothrow(); 7932 } 7933 7934 OMPLoopDirective::HelperExprs B; 7935 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7936 // define the nested loops number. 7937 unsigned NestedLoopCount = 7938 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 7939 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7940 VarsWithImplicitDSA, B); 7941 if (NestedLoopCount == 0) 7942 return StmtError(); 7943 7944 assert((CurContext->isDependentContext() || B.builtAll()) && 7945 "omp target parallel for loop exprs were not built"); 7946 7947 if (!CurContext->isDependentContext()) { 7948 // Finalize the clauses that need pre-built expressions for CodeGen. 7949 for (OMPClause *C : Clauses) { 7950 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7951 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7952 B.NumIterations, *this, CurScope, 7953 DSAStack)) 7954 return StmtError(); 7955 } 7956 } 7957 7958 setFunctionHasBranchProtectedScope(); 7959 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 7960 NestedLoopCount, Clauses, AStmt, 7961 B, DSAStack->isCancelRegion()); 7962 } 7963 7964 /// Check for existence of a map clause in the list of clauses. 7965 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 7966 const OpenMPClauseKind K) { 7967 return llvm::any_of( 7968 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 7969 } 7970 7971 template <typename... Params> 7972 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 7973 const Params... ClauseTypes) { 7974 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 7975 } 7976 7977 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 7978 Stmt *AStmt, 7979 SourceLocation StartLoc, 7980 SourceLocation EndLoc) { 7981 if (!AStmt) 7982 return StmtError(); 7983 7984 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7985 7986 // OpenMP [2.10.1, Restrictions, p. 97] 7987 // At least one map clause must appear on the directive. 7988 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 7989 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7990 << "'map' or 'use_device_ptr'" 7991 << getOpenMPDirectiveName(OMPD_target_data); 7992 return StmtError(); 7993 } 7994 7995 setFunctionHasBranchProtectedScope(); 7996 7997 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7998 AStmt); 7999 } 8000 8001 StmtResult 8002 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8003 SourceLocation StartLoc, 8004 SourceLocation EndLoc, Stmt *AStmt) { 8005 if (!AStmt) 8006 return StmtError(); 8007 8008 auto *CS = cast<CapturedStmt>(AStmt); 8009 // 1.2.2 OpenMP Language Terminology 8010 // Structured block - An executable statement with a single entry at the 8011 // top and a single exit at the bottom. 8012 // The point of exit cannot be a branch out of the structured block. 8013 // longjmp() and throw() must not violate the entry/exit criteria. 8014 CS->getCapturedDecl()->setNothrow(); 8015 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8016 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8017 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8018 // 1.2.2 OpenMP Language Terminology 8019 // Structured block - An executable statement with a single entry at the 8020 // top and a single exit at the bottom. 8021 // The point of exit cannot be a branch out of the structured block. 8022 // longjmp() and throw() must not violate the entry/exit criteria. 8023 CS->getCapturedDecl()->setNothrow(); 8024 } 8025 8026 // OpenMP [2.10.2, Restrictions, p. 99] 8027 // At least one map clause must appear on the directive. 8028 if (!hasClauses(Clauses, OMPC_map)) { 8029 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8030 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8031 return StmtError(); 8032 } 8033 8034 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8035 AStmt); 8036 } 8037 8038 StmtResult 8039 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8040 SourceLocation StartLoc, 8041 SourceLocation EndLoc, Stmt *AStmt) { 8042 if (!AStmt) 8043 return StmtError(); 8044 8045 auto *CS = cast<CapturedStmt>(AStmt); 8046 // 1.2.2 OpenMP Language Terminology 8047 // Structured block - An executable statement with a single entry at the 8048 // top and a single exit at the bottom. 8049 // The point of exit cannot be a branch out of the structured block. 8050 // longjmp() and throw() must not violate the entry/exit criteria. 8051 CS->getCapturedDecl()->setNothrow(); 8052 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8053 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8054 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8055 // 1.2.2 OpenMP Language Terminology 8056 // Structured block - An executable statement with a single entry at the 8057 // top and a single exit at the bottom. 8058 // The point of exit cannot be a branch out of the structured block. 8059 // longjmp() and throw() must not violate the entry/exit criteria. 8060 CS->getCapturedDecl()->setNothrow(); 8061 } 8062 8063 // OpenMP [2.10.3, Restrictions, p. 102] 8064 // At least one map clause must appear on the directive. 8065 if (!hasClauses(Clauses, OMPC_map)) { 8066 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8067 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8068 return StmtError(); 8069 } 8070 8071 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8072 AStmt); 8073 } 8074 8075 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8076 SourceLocation StartLoc, 8077 SourceLocation EndLoc, 8078 Stmt *AStmt) { 8079 if (!AStmt) 8080 return StmtError(); 8081 8082 auto *CS = cast<CapturedStmt>(AStmt); 8083 // 1.2.2 OpenMP Language Terminology 8084 // Structured block - An executable statement with a single entry at the 8085 // top and a single exit at the bottom. 8086 // The point of exit cannot be a branch out of the structured block. 8087 // longjmp() and throw() must not violate the entry/exit criteria. 8088 CS->getCapturedDecl()->setNothrow(); 8089 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8090 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8091 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8092 // 1.2.2 OpenMP Language Terminology 8093 // Structured block - An executable statement with a single entry at the 8094 // top and a single exit at the bottom. 8095 // The point of exit cannot be a branch out of the structured block. 8096 // longjmp() and throw() must not violate the entry/exit criteria. 8097 CS->getCapturedDecl()->setNothrow(); 8098 } 8099 8100 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8101 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8102 return StmtError(); 8103 } 8104 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8105 AStmt); 8106 } 8107 8108 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8109 Stmt *AStmt, SourceLocation StartLoc, 8110 SourceLocation EndLoc) { 8111 if (!AStmt) 8112 return StmtError(); 8113 8114 auto *CS = cast<CapturedStmt>(AStmt); 8115 // 1.2.2 OpenMP Language Terminology 8116 // Structured block - An executable statement with a single entry at the 8117 // top and a single exit at the bottom. 8118 // The point of exit cannot be a branch out of the structured block. 8119 // longjmp() and throw() must not violate the entry/exit criteria. 8120 CS->getCapturedDecl()->setNothrow(); 8121 8122 setFunctionHasBranchProtectedScope(); 8123 8124 DSAStack->setParentTeamsRegionLoc(StartLoc); 8125 8126 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8127 } 8128 8129 StmtResult 8130 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8131 SourceLocation EndLoc, 8132 OpenMPDirectiveKind CancelRegion) { 8133 if (DSAStack->isParentNowaitRegion()) { 8134 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8135 return StmtError(); 8136 } 8137 if (DSAStack->isParentOrderedRegion()) { 8138 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8139 return StmtError(); 8140 } 8141 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8142 CancelRegion); 8143 } 8144 8145 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8146 SourceLocation StartLoc, 8147 SourceLocation EndLoc, 8148 OpenMPDirectiveKind CancelRegion) { 8149 if (DSAStack->isParentNowaitRegion()) { 8150 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8151 return StmtError(); 8152 } 8153 if (DSAStack->isParentOrderedRegion()) { 8154 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8155 return StmtError(); 8156 } 8157 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8158 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8159 CancelRegion); 8160 } 8161 8162 static bool checkGrainsizeNumTasksClauses(Sema &S, 8163 ArrayRef<OMPClause *> Clauses) { 8164 const OMPClause *PrevClause = nullptr; 8165 bool ErrorFound = false; 8166 for (const OMPClause *C : Clauses) { 8167 if (C->getClauseKind() == OMPC_grainsize || 8168 C->getClauseKind() == OMPC_num_tasks) { 8169 if (!PrevClause) 8170 PrevClause = C; 8171 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8172 S.Diag(C->getBeginLoc(), 8173 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8174 << getOpenMPClauseName(C->getClauseKind()) 8175 << getOpenMPClauseName(PrevClause->getClauseKind()); 8176 S.Diag(PrevClause->getBeginLoc(), 8177 diag::note_omp_previous_grainsize_num_tasks) 8178 << getOpenMPClauseName(PrevClause->getClauseKind()); 8179 ErrorFound = true; 8180 } 8181 } 8182 } 8183 return ErrorFound; 8184 } 8185 8186 static bool checkReductionClauseWithNogroup(Sema &S, 8187 ArrayRef<OMPClause *> Clauses) { 8188 const OMPClause *ReductionClause = nullptr; 8189 const OMPClause *NogroupClause = nullptr; 8190 for (const OMPClause *C : Clauses) { 8191 if (C->getClauseKind() == OMPC_reduction) { 8192 ReductionClause = C; 8193 if (NogroupClause) 8194 break; 8195 continue; 8196 } 8197 if (C->getClauseKind() == OMPC_nogroup) { 8198 NogroupClause = C; 8199 if (ReductionClause) 8200 break; 8201 continue; 8202 } 8203 } 8204 if (ReductionClause && NogroupClause) { 8205 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8206 << SourceRange(NogroupClause->getBeginLoc(), 8207 NogroupClause->getEndLoc()); 8208 return true; 8209 } 8210 return false; 8211 } 8212 8213 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8214 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8215 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8216 if (!AStmt) 8217 return StmtError(); 8218 8219 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8220 OMPLoopDirective::HelperExprs B; 8221 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8222 // define the nested loops number. 8223 unsigned NestedLoopCount = 8224 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8225 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8226 VarsWithImplicitDSA, B); 8227 if (NestedLoopCount == 0) 8228 return StmtError(); 8229 8230 assert((CurContext->isDependentContext() || B.builtAll()) && 8231 "omp for loop exprs were not built"); 8232 8233 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8234 // The grainsize clause and num_tasks clause are mutually exclusive and may 8235 // not appear on the same taskloop directive. 8236 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8237 return StmtError(); 8238 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8239 // If a reduction clause is present on the taskloop directive, the nogroup 8240 // clause must not be specified. 8241 if (checkReductionClauseWithNogroup(*this, Clauses)) 8242 return StmtError(); 8243 8244 setFunctionHasBranchProtectedScope(); 8245 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8246 NestedLoopCount, Clauses, AStmt, B); 8247 } 8248 8249 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8250 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8251 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8252 if (!AStmt) 8253 return StmtError(); 8254 8255 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8256 OMPLoopDirective::HelperExprs B; 8257 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8258 // define the nested loops number. 8259 unsigned NestedLoopCount = 8260 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8261 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8262 VarsWithImplicitDSA, B); 8263 if (NestedLoopCount == 0) 8264 return StmtError(); 8265 8266 assert((CurContext->isDependentContext() || B.builtAll()) && 8267 "omp for loop exprs were not built"); 8268 8269 if (!CurContext->isDependentContext()) { 8270 // Finalize the clauses that need pre-built expressions for CodeGen. 8271 for (OMPClause *C : Clauses) { 8272 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8273 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8274 B.NumIterations, *this, CurScope, 8275 DSAStack)) 8276 return StmtError(); 8277 } 8278 } 8279 8280 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8281 // The grainsize clause and num_tasks clause are mutually exclusive and may 8282 // not appear on the same taskloop directive. 8283 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8284 return StmtError(); 8285 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8286 // If a reduction clause is present on the taskloop directive, the nogroup 8287 // clause must not be specified. 8288 if (checkReductionClauseWithNogroup(*this, Clauses)) 8289 return StmtError(); 8290 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8291 return StmtError(); 8292 8293 setFunctionHasBranchProtectedScope(); 8294 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8295 NestedLoopCount, Clauses, AStmt, B); 8296 } 8297 8298 StmtResult Sema::ActOnOpenMPDistributeDirective( 8299 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8300 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8301 if (!AStmt) 8302 return StmtError(); 8303 8304 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8305 OMPLoopDirective::HelperExprs B; 8306 // In presence of clause 'collapse' with number of loops, it will 8307 // define the nested loops number. 8308 unsigned NestedLoopCount = 8309 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8310 nullptr /*ordered not a clause on distribute*/, AStmt, 8311 *this, *DSAStack, VarsWithImplicitDSA, B); 8312 if (NestedLoopCount == 0) 8313 return StmtError(); 8314 8315 assert((CurContext->isDependentContext() || B.builtAll()) && 8316 "omp for loop exprs were not built"); 8317 8318 setFunctionHasBranchProtectedScope(); 8319 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8320 NestedLoopCount, Clauses, AStmt, B); 8321 } 8322 8323 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8324 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8325 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8326 if (!AStmt) 8327 return StmtError(); 8328 8329 auto *CS = cast<CapturedStmt>(AStmt); 8330 // 1.2.2 OpenMP Language Terminology 8331 // Structured block - An executable statement with a single entry at the 8332 // top and a single exit at the bottom. 8333 // The point of exit cannot be a branch out of the structured block. 8334 // longjmp() and throw() must not violate the entry/exit criteria. 8335 CS->getCapturedDecl()->setNothrow(); 8336 for (int ThisCaptureLevel = 8337 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8338 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8339 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8340 // 1.2.2 OpenMP Language Terminology 8341 // Structured block - An executable statement with a single entry at the 8342 // top and a single exit at the bottom. 8343 // The point of exit cannot be a branch out of the structured block. 8344 // longjmp() and throw() must not violate the entry/exit criteria. 8345 CS->getCapturedDecl()->setNothrow(); 8346 } 8347 8348 OMPLoopDirective::HelperExprs B; 8349 // In presence of clause 'collapse' with number of loops, it will 8350 // define the nested loops number. 8351 unsigned NestedLoopCount = checkOpenMPLoop( 8352 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8353 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8354 VarsWithImplicitDSA, B); 8355 if (NestedLoopCount == 0) 8356 return StmtError(); 8357 8358 assert((CurContext->isDependentContext() || B.builtAll()) && 8359 "omp for loop exprs were not built"); 8360 8361 setFunctionHasBranchProtectedScope(); 8362 return OMPDistributeParallelForDirective::Create( 8363 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8364 DSAStack->isCancelRegion()); 8365 } 8366 8367 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8368 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8369 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8370 if (!AStmt) 8371 return StmtError(); 8372 8373 auto *CS = cast<CapturedStmt>(AStmt); 8374 // 1.2.2 OpenMP Language Terminology 8375 // Structured block - An executable statement with a single entry at the 8376 // top and a single exit at the bottom. 8377 // The point of exit cannot be a branch out of the structured block. 8378 // longjmp() and throw() must not violate the entry/exit criteria. 8379 CS->getCapturedDecl()->setNothrow(); 8380 for (int ThisCaptureLevel = 8381 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8382 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8383 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8384 // 1.2.2 OpenMP Language Terminology 8385 // Structured block - An executable statement with a single entry at the 8386 // top and a single exit at the bottom. 8387 // The point of exit cannot be a branch out of the structured block. 8388 // longjmp() and throw() must not violate the entry/exit criteria. 8389 CS->getCapturedDecl()->setNothrow(); 8390 } 8391 8392 OMPLoopDirective::HelperExprs B; 8393 // In presence of clause 'collapse' with number of loops, it will 8394 // define the nested loops number. 8395 unsigned NestedLoopCount = checkOpenMPLoop( 8396 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8397 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8398 VarsWithImplicitDSA, B); 8399 if (NestedLoopCount == 0) 8400 return StmtError(); 8401 8402 assert((CurContext->isDependentContext() || B.builtAll()) && 8403 "omp for loop exprs were not built"); 8404 8405 if (!CurContext->isDependentContext()) { 8406 // Finalize the clauses that need pre-built expressions for CodeGen. 8407 for (OMPClause *C : Clauses) { 8408 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8409 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8410 B.NumIterations, *this, CurScope, 8411 DSAStack)) 8412 return StmtError(); 8413 } 8414 } 8415 8416 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8417 return StmtError(); 8418 8419 setFunctionHasBranchProtectedScope(); 8420 return OMPDistributeParallelForSimdDirective::Create( 8421 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8422 } 8423 8424 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8425 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8426 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8427 if (!AStmt) 8428 return StmtError(); 8429 8430 auto *CS = cast<CapturedStmt>(AStmt); 8431 // 1.2.2 OpenMP Language Terminology 8432 // Structured block - An executable statement with a single entry at the 8433 // top and a single exit at the bottom. 8434 // The point of exit cannot be a branch out of the structured block. 8435 // longjmp() and throw() must not violate the entry/exit criteria. 8436 CS->getCapturedDecl()->setNothrow(); 8437 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8438 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8439 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8440 // 1.2.2 OpenMP Language Terminology 8441 // Structured block - An executable statement with a single entry at the 8442 // top and a single exit at the bottom. 8443 // The point of exit cannot be a branch out of the structured block. 8444 // longjmp() and throw() must not violate the entry/exit criteria. 8445 CS->getCapturedDecl()->setNothrow(); 8446 } 8447 8448 OMPLoopDirective::HelperExprs B; 8449 // In presence of clause 'collapse' with number of loops, it will 8450 // define the nested loops number. 8451 unsigned NestedLoopCount = 8452 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8453 nullptr /*ordered not a clause on distribute*/, CS, *this, 8454 *DSAStack, VarsWithImplicitDSA, B); 8455 if (NestedLoopCount == 0) 8456 return StmtError(); 8457 8458 assert((CurContext->isDependentContext() || B.builtAll()) && 8459 "omp for loop exprs were not built"); 8460 8461 if (!CurContext->isDependentContext()) { 8462 // Finalize the clauses that need pre-built expressions for CodeGen. 8463 for (OMPClause *C : Clauses) { 8464 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8465 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8466 B.NumIterations, *this, CurScope, 8467 DSAStack)) 8468 return StmtError(); 8469 } 8470 } 8471 8472 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8473 return StmtError(); 8474 8475 setFunctionHasBranchProtectedScope(); 8476 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8477 NestedLoopCount, Clauses, AStmt, B); 8478 } 8479 8480 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 8481 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8482 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8483 if (!AStmt) 8484 return StmtError(); 8485 8486 auto *CS = cast<CapturedStmt>(AStmt); 8487 // 1.2.2 OpenMP Language Terminology 8488 // Structured block - An executable statement with a single entry at the 8489 // top and a single exit at the bottom. 8490 // The point of exit cannot be a branch out of the structured block. 8491 // longjmp() and throw() must not violate the entry/exit criteria. 8492 CS->getCapturedDecl()->setNothrow(); 8493 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8494 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8495 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8496 // 1.2.2 OpenMP Language Terminology 8497 // Structured block - An executable statement with a single entry at the 8498 // top and a single exit at the bottom. 8499 // The point of exit cannot be a branch out of the structured block. 8500 // longjmp() and throw() must not violate the entry/exit criteria. 8501 CS->getCapturedDecl()->setNothrow(); 8502 } 8503 8504 OMPLoopDirective::HelperExprs B; 8505 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8506 // define the nested loops number. 8507 unsigned NestedLoopCount = checkOpenMPLoop( 8508 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8509 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8510 VarsWithImplicitDSA, B); 8511 if (NestedLoopCount == 0) 8512 return StmtError(); 8513 8514 assert((CurContext->isDependentContext() || B.builtAll()) && 8515 "omp target parallel for simd loop exprs were not built"); 8516 8517 if (!CurContext->isDependentContext()) { 8518 // Finalize the clauses that need pre-built expressions for CodeGen. 8519 for (OMPClause *C : Clauses) { 8520 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8521 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8522 B.NumIterations, *this, CurScope, 8523 DSAStack)) 8524 return StmtError(); 8525 } 8526 } 8527 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8528 return StmtError(); 8529 8530 setFunctionHasBranchProtectedScope(); 8531 return OMPTargetParallelForSimdDirective::Create( 8532 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8533 } 8534 8535 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8536 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8537 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8538 if (!AStmt) 8539 return StmtError(); 8540 8541 auto *CS = cast<CapturedStmt>(AStmt); 8542 // 1.2.2 OpenMP Language Terminology 8543 // Structured block - An executable statement with a single entry at the 8544 // top and a single exit at the bottom. 8545 // The point of exit cannot be a branch out of the structured block. 8546 // longjmp() and throw() must not violate the entry/exit criteria. 8547 CS->getCapturedDecl()->setNothrow(); 8548 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8549 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8550 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8551 // 1.2.2 OpenMP Language Terminology 8552 // Structured block - An executable statement with a single entry at the 8553 // top and a single exit at the bottom. 8554 // The point of exit cannot be a branch out of the structured block. 8555 // longjmp() and throw() must not violate the entry/exit criteria. 8556 CS->getCapturedDecl()->setNothrow(); 8557 } 8558 8559 OMPLoopDirective::HelperExprs B; 8560 // In presence of clause 'collapse' with number of loops, it will define the 8561 // nested loops number. 8562 unsigned NestedLoopCount = 8563 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8564 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8565 VarsWithImplicitDSA, B); 8566 if (NestedLoopCount == 0) 8567 return StmtError(); 8568 8569 assert((CurContext->isDependentContext() || B.builtAll()) && 8570 "omp target simd loop exprs were not built"); 8571 8572 if (!CurContext->isDependentContext()) { 8573 // Finalize the clauses that need pre-built expressions for CodeGen. 8574 for (OMPClause *C : Clauses) { 8575 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8576 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8577 B.NumIterations, *this, CurScope, 8578 DSAStack)) 8579 return StmtError(); 8580 } 8581 } 8582 8583 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8584 return StmtError(); 8585 8586 setFunctionHasBranchProtectedScope(); 8587 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8588 NestedLoopCount, Clauses, AStmt, B); 8589 } 8590 8591 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8592 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8593 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8594 if (!AStmt) 8595 return StmtError(); 8596 8597 auto *CS = cast<CapturedStmt>(AStmt); 8598 // 1.2.2 OpenMP Language Terminology 8599 // Structured block - An executable statement with a single entry at the 8600 // top and a single exit at the bottom. 8601 // The point of exit cannot be a branch out of the structured block. 8602 // longjmp() and throw() must not violate the entry/exit criteria. 8603 CS->getCapturedDecl()->setNothrow(); 8604 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8605 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8606 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8607 // 1.2.2 OpenMP Language Terminology 8608 // Structured block - An executable statement with a single entry at the 8609 // top and a single exit at the bottom. 8610 // The point of exit cannot be a branch out of the structured block. 8611 // longjmp() and throw() must not violate the entry/exit criteria. 8612 CS->getCapturedDecl()->setNothrow(); 8613 } 8614 8615 OMPLoopDirective::HelperExprs B; 8616 // In presence of clause 'collapse' with number of loops, it will 8617 // define the nested loops number. 8618 unsigned NestedLoopCount = 8619 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8620 nullptr /*ordered not a clause on distribute*/, CS, *this, 8621 *DSAStack, VarsWithImplicitDSA, B); 8622 if (NestedLoopCount == 0) 8623 return StmtError(); 8624 8625 assert((CurContext->isDependentContext() || B.builtAll()) && 8626 "omp teams distribute loop exprs were not built"); 8627 8628 setFunctionHasBranchProtectedScope(); 8629 8630 DSAStack->setParentTeamsRegionLoc(StartLoc); 8631 8632 return OMPTeamsDistributeDirective::Create( 8633 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8634 } 8635 8636 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8637 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8638 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8639 if (!AStmt) 8640 return StmtError(); 8641 8642 auto *CS = cast<CapturedStmt>(AStmt); 8643 // 1.2.2 OpenMP Language Terminology 8644 // Structured block - An executable statement with a single entry at the 8645 // top and a single exit at the bottom. 8646 // The point of exit cannot be a branch out of the structured block. 8647 // longjmp() and throw() must not violate the entry/exit criteria. 8648 CS->getCapturedDecl()->setNothrow(); 8649 for (int ThisCaptureLevel = 8650 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8651 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8652 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8653 // 1.2.2 OpenMP Language Terminology 8654 // Structured block - An executable statement with a single entry at the 8655 // top and a single exit at the bottom. 8656 // The point of exit cannot be a branch out of the structured block. 8657 // longjmp() and throw() must not violate the entry/exit criteria. 8658 CS->getCapturedDecl()->setNothrow(); 8659 } 8660 8661 8662 OMPLoopDirective::HelperExprs B; 8663 // In presence of clause 'collapse' with number of loops, it will 8664 // define the nested loops number. 8665 unsigned NestedLoopCount = checkOpenMPLoop( 8666 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8667 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8668 VarsWithImplicitDSA, B); 8669 8670 if (NestedLoopCount == 0) 8671 return StmtError(); 8672 8673 assert((CurContext->isDependentContext() || B.builtAll()) && 8674 "omp teams distribute simd loop exprs were not built"); 8675 8676 if (!CurContext->isDependentContext()) { 8677 // Finalize the clauses that need pre-built expressions for CodeGen. 8678 for (OMPClause *C : Clauses) { 8679 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8680 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8681 B.NumIterations, *this, CurScope, 8682 DSAStack)) 8683 return StmtError(); 8684 } 8685 } 8686 8687 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8688 return StmtError(); 8689 8690 setFunctionHasBranchProtectedScope(); 8691 8692 DSAStack->setParentTeamsRegionLoc(StartLoc); 8693 8694 return OMPTeamsDistributeSimdDirective::Create( 8695 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8696 } 8697 8698 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8699 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8700 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8701 if (!AStmt) 8702 return StmtError(); 8703 8704 auto *CS = cast<CapturedStmt>(AStmt); 8705 // 1.2.2 OpenMP Language Terminology 8706 // Structured block - An executable statement with a single entry at the 8707 // top and a single exit at the bottom. 8708 // The point of exit cannot be a branch out of the structured block. 8709 // longjmp() and throw() must not violate the entry/exit criteria. 8710 CS->getCapturedDecl()->setNothrow(); 8711 8712 for (int ThisCaptureLevel = 8713 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8714 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8715 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8716 // 1.2.2 OpenMP Language Terminology 8717 // Structured block - An executable statement with a single entry at the 8718 // top and a single exit at the bottom. 8719 // The point of exit cannot be a branch out of the structured block. 8720 // longjmp() and throw() must not violate the entry/exit criteria. 8721 CS->getCapturedDecl()->setNothrow(); 8722 } 8723 8724 OMPLoopDirective::HelperExprs B; 8725 // In presence of clause 'collapse' with number of loops, it will 8726 // define the nested loops number. 8727 unsigned NestedLoopCount = checkOpenMPLoop( 8728 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8729 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8730 VarsWithImplicitDSA, B); 8731 8732 if (NestedLoopCount == 0) 8733 return StmtError(); 8734 8735 assert((CurContext->isDependentContext() || B.builtAll()) && 8736 "omp for loop exprs were not built"); 8737 8738 if (!CurContext->isDependentContext()) { 8739 // Finalize the clauses that need pre-built expressions for CodeGen. 8740 for (OMPClause *C : Clauses) { 8741 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8742 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8743 B.NumIterations, *this, CurScope, 8744 DSAStack)) 8745 return StmtError(); 8746 } 8747 } 8748 8749 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8750 return StmtError(); 8751 8752 setFunctionHasBranchProtectedScope(); 8753 8754 DSAStack->setParentTeamsRegionLoc(StartLoc); 8755 8756 return OMPTeamsDistributeParallelForSimdDirective::Create( 8757 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8758 } 8759 8760 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 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 8774 for (int ThisCaptureLevel = 8775 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8776 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8777 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8778 // 1.2.2 OpenMP Language Terminology 8779 // Structured block - An executable statement with a single entry at the 8780 // top and a single exit at the bottom. 8781 // The point of exit cannot be a branch out of the structured block. 8782 // longjmp() and throw() must not violate the entry/exit criteria. 8783 CS->getCapturedDecl()->setNothrow(); 8784 } 8785 8786 OMPLoopDirective::HelperExprs B; 8787 // In presence of clause 'collapse' with number of loops, it will 8788 // define the nested loops number. 8789 unsigned NestedLoopCount = checkOpenMPLoop( 8790 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8791 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8792 VarsWithImplicitDSA, B); 8793 8794 if (NestedLoopCount == 0) 8795 return StmtError(); 8796 8797 assert((CurContext->isDependentContext() || B.builtAll()) && 8798 "omp for loop exprs were not built"); 8799 8800 setFunctionHasBranchProtectedScope(); 8801 8802 DSAStack->setParentTeamsRegionLoc(StartLoc); 8803 8804 return OMPTeamsDistributeParallelForDirective::Create( 8805 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8806 DSAStack->isCancelRegion()); 8807 } 8808 8809 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8810 Stmt *AStmt, 8811 SourceLocation StartLoc, 8812 SourceLocation EndLoc) { 8813 if (!AStmt) 8814 return StmtError(); 8815 8816 auto *CS = cast<CapturedStmt>(AStmt); 8817 // 1.2.2 OpenMP Language Terminology 8818 // Structured block - An executable statement with a single entry at the 8819 // top and a single exit at the bottom. 8820 // The point of exit cannot be a branch out of the structured block. 8821 // longjmp() and throw() must not violate the entry/exit criteria. 8822 CS->getCapturedDecl()->setNothrow(); 8823 8824 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8825 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8826 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8827 // 1.2.2 OpenMP Language Terminology 8828 // Structured block - An executable statement with a single entry at the 8829 // top and a single exit at the bottom. 8830 // The point of exit cannot be a branch out of the structured block. 8831 // longjmp() and throw() must not violate the entry/exit criteria. 8832 CS->getCapturedDecl()->setNothrow(); 8833 } 8834 setFunctionHasBranchProtectedScope(); 8835 8836 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8837 AStmt); 8838 } 8839 8840 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8841 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8842 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8843 if (!AStmt) 8844 return StmtError(); 8845 8846 auto *CS = cast<CapturedStmt>(AStmt); 8847 // 1.2.2 OpenMP Language Terminology 8848 // Structured block - An executable statement with a single entry at the 8849 // top and a single exit at the bottom. 8850 // The point of exit cannot be a branch out of the structured block. 8851 // longjmp() and throw() must not violate the entry/exit criteria. 8852 CS->getCapturedDecl()->setNothrow(); 8853 for (int ThisCaptureLevel = 8854 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8855 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8856 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8857 // 1.2.2 OpenMP Language Terminology 8858 // Structured block - An executable statement with a single entry at the 8859 // top and a single exit at the bottom. 8860 // The point of exit cannot be a branch out of the structured block. 8861 // longjmp() and throw() must not violate the entry/exit criteria. 8862 CS->getCapturedDecl()->setNothrow(); 8863 } 8864 8865 OMPLoopDirective::HelperExprs B; 8866 // In presence of clause 'collapse' with number of loops, it will 8867 // define the nested loops number. 8868 unsigned NestedLoopCount = checkOpenMPLoop( 8869 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8870 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8871 VarsWithImplicitDSA, B); 8872 if (NestedLoopCount == 0) 8873 return StmtError(); 8874 8875 assert((CurContext->isDependentContext() || B.builtAll()) && 8876 "omp target teams distribute loop exprs were not built"); 8877 8878 setFunctionHasBranchProtectedScope(); 8879 return OMPTargetTeamsDistributeDirective::Create( 8880 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8881 } 8882 8883 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8884 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8885 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8886 if (!AStmt) 8887 return StmtError(); 8888 8889 auto *CS = cast<CapturedStmt>(AStmt); 8890 // 1.2.2 OpenMP Language Terminology 8891 // Structured block - An executable statement with a single entry at the 8892 // top and a single exit at the bottom. 8893 // The point of exit cannot be a branch out of the structured block. 8894 // longjmp() and throw() must not violate the entry/exit criteria. 8895 CS->getCapturedDecl()->setNothrow(); 8896 for (int ThisCaptureLevel = 8897 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8898 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8899 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8900 // 1.2.2 OpenMP Language Terminology 8901 // Structured block - An executable statement with a single entry at the 8902 // top and a single exit at the bottom. 8903 // The point of exit cannot be a branch out of the structured block. 8904 // longjmp() and throw() must not violate the entry/exit criteria. 8905 CS->getCapturedDecl()->setNothrow(); 8906 } 8907 8908 OMPLoopDirective::HelperExprs B; 8909 // In presence of clause 'collapse' with number of loops, it will 8910 // define the nested loops number. 8911 unsigned NestedLoopCount = checkOpenMPLoop( 8912 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8913 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8914 VarsWithImplicitDSA, B); 8915 if (NestedLoopCount == 0) 8916 return StmtError(); 8917 8918 assert((CurContext->isDependentContext() || B.builtAll()) && 8919 "omp target teams distribute parallel for loop exprs were not built"); 8920 8921 if (!CurContext->isDependentContext()) { 8922 // Finalize the clauses that need pre-built expressions for CodeGen. 8923 for (OMPClause *C : Clauses) { 8924 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8925 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8926 B.NumIterations, *this, CurScope, 8927 DSAStack)) 8928 return StmtError(); 8929 } 8930 } 8931 8932 setFunctionHasBranchProtectedScope(); 8933 return OMPTargetTeamsDistributeParallelForDirective::Create( 8934 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8935 DSAStack->isCancelRegion()); 8936 } 8937 8938 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 8939 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8940 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8941 if (!AStmt) 8942 return StmtError(); 8943 8944 auto *CS = cast<CapturedStmt>(AStmt); 8945 // 1.2.2 OpenMP Language Terminology 8946 // Structured block - An executable statement with a single entry at the 8947 // top and a single exit at the bottom. 8948 // The point of exit cannot be a branch out of the structured block. 8949 // longjmp() and throw() must not violate the entry/exit criteria. 8950 CS->getCapturedDecl()->setNothrow(); 8951 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 8952 OMPD_target_teams_distribute_parallel_for_simd); 8953 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8954 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8955 // 1.2.2 OpenMP Language Terminology 8956 // Structured block - An executable statement with a single entry at the 8957 // top and a single exit at the bottom. 8958 // The point of exit cannot be a branch out of the structured block. 8959 // longjmp() and throw() must not violate the entry/exit criteria. 8960 CS->getCapturedDecl()->setNothrow(); 8961 } 8962 8963 OMPLoopDirective::HelperExprs B; 8964 // In presence of clause 'collapse' with number of loops, it will 8965 // define the nested loops number. 8966 unsigned NestedLoopCount = 8967 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 8968 getCollapseNumberExpr(Clauses), 8969 nullptr /*ordered not a clause on distribute*/, CS, *this, 8970 *DSAStack, VarsWithImplicitDSA, B); 8971 if (NestedLoopCount == 0) 8972 return StmtError(); 8973 8974 assert((CurContext->isDependentContext() || B.builtAll()) && 8975 "omp target teams distribute parallel for simd loop exprs were not " 8976 "built"); 8977 8978 if (!CurContext->isDependentContext()) { 8979 // Finalize the clauses that need pre-built expressions for CodeGen. 8980 for (OMPClause *C : Clauses) { 8981 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8982 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8983 B.NumIterations, *this, CurScope, 8984 DSAStack)) 8985 return StmtError(); 8986 } 8987 } 8988 8989 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8990 return StmtError(); 8991 8992 setFunctionHasBranchProtectedScope(); 8993 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 8994 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8995 } 8996 8997 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 8998 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8999 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9000 if (!AStmt) 9001 return StmtError(); 9002 9003 auto *CS = cast<CapturedStmt>(AStmt); 9004 // 1.2.2 OpenMP Language Terminology 9005 // Structured block - An executable statement with a single entry at the 9006 // top and a single exit at the bottom. 9007 // The point of exit cannot be a branch out of the structured block. 9008 // longjmp() and throw() must not violate the entry/exit criteria. 9009 CS->getCapturedDecl()->setNothrow(); 9010 for (int ThisCaptureLevel = 9011 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9012 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9013 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9014 // 1.2.2 OpenMP Language Terminology 9015 // Structured block - An executable statement with a single entry at the 9016 // top and a single exit at the bottom. 9017 // The point of exit cannot be a branch out of the structured block. 9018 // longjmp() and throw() must not violate the entry/exit criteria. 9019 CS->getCapturedDecl()->setNothrow(); 9020 } 9021 9022 OMPLoopDirective::HelperExprs B; 9023 // In presence of clause 'collapse' with number of loops, it will 9024 // define the nested loops number. 9025 unsigned NestedLoopCount = checkOpenMPLoop( 9026 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9027 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9028 VarsWithImplicitDSA, B); 9029 if (NestedLoopCount == 0) 9030 return StmtError(); 9031 9032 assert((CurContext->isDependentContext() || B.builtAll()) && 9033 "omp target teams distribute simd loop exprs were not built"); 9034 9035 if (!CurContext->isDependentContext()) { 9036 // Finalize the clauses that need pre-built expressions for CodeGen. 9037 for (OMPClause *C : Clauses) { 9038 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9039 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9040 B.NumIterations, *this, CurScope, 9041 DSAStack)) 9042 return StmtError(); 9043 } 9044 } 9045 9046 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9047 return StmtError(); 9048 9049 setFunctionHasBranchProtectedScope(); 9050 return OMPTargetTeamsDistributeSimdDirective::Create( 9051 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9052 } 9053 9054 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9055 SourceLocation StartLoc, 9056 SourceLocation LParenLoc, 9057 SourceLocation EndLoc) { 9058 OMPClause *Res = nullptr; 9059 switch (Kind) { 9060 case OMPC_final: 9061 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9062 break; 9063 case OMPC_num_threads: 9064 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9065 break; 9066 case OMPC_safelen: 9067 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9068 break; 9069 case OMPC_simdlen: 9070 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9071 break; 9072 case OMPC_allocator: 9073 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9074 break; 9075 case OMPC_collapse: 9076 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9077 break; 9078 case OMPC_ordered: 9079 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9080 break; 9081 case OMPC_device: 9082 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9083 break; 9084 case OMPC_num_teams: 9085 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9086 break; 9087 case OMPC_thread_limit: 9088 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9089 break; 9090 case OMPC_priority: 9091 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9092 break; 9093 case OMPC_grainsize: 9094 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9095 break; 9096 case OMPC_num_tasks: 9097 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9098 break; 9099 case OMPC_hint: 9100 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9101 break; 9102 case OMPC_if: 9103 case OMPC_default: 9104 case OMPC_proc_bind: 9105 case OMPC_schedule: 9106 case OMPC_private: 9107 case OMPC_firstprivate: 9108 case OMPC_lastprivate: 9109 case OMPC_shared: 9110 case OMPC_reduction: 9111 case OMPC_task_reduction: 9112 case OMPC_in_reduction: 9113 case OMPC_linear: 9114 case OMPC_aligned: 9115 case OMPC_copyin: 9116 case OMPC_copyprivate: 9117 case OMPC_nowait: 9118 case OMPC_untied: 9119 case OMPC_mergeable: 9120 case OMPC_threadprivate: 9121 case OMPC_allocate: 9122 case OMPC_flush: 9123 case OMPC_read: 9124 case OMPC_write: 9125 case OMPC_update: 9126 case OMPC_capture: 9127 case OMPC_seq_cst: 9128 case OMPC_depend: 9129 case OMPC_threads: 9130 case OMPC_simd: 9131 case OMPC_map: 9132 case OMPC_nogroup: 9133 case OMPC_dist_schedule: 9134 case OMPC_defaultmap: 9135 case OMPC_unknown: 9136 case OMPC_uniform: 9137 case OMPC_to: 9138 case OMPC_from: 9139 case OMPC_use_device_ptr: 9140 case OMPC_is_device_ptr: 9141 case OMPC_unified_address: 9142 case OMPC_unified_shared_memory: 9143 case OMPC_reverse_offload: 9144 case OMPC_dynamic_allocators: 9145 case OMPC_atomic_default_mem_order: 9146 llvm_unreachable("Clause is not allowed."); 9147 } 9148 return Res; 9149 } 9150 9151 // An OpenMP directive such as 'target parallel' has two captured regions: 9152 // for the 'target' and 'parallel' respectively. This function returns 9153 // the region in which to capture expressions associated with a clause. 9154 // A return value of OMPD_unknown signifies that the expression should not 9155 // be captured. 9156 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9157 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9158 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9159 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9160 switch (CKind) { 9161 case OMPC_if: 9162 switch (DKind) { 9163 case OMPD_target_parallel: 9164 case OMPD_target_parallel_for: 9165 case OMPD_target_parallel_for_simd: 9166 // If this clause applies to the nested 'parallel' region, capture within 9167 // the 'target' region, otherwise do not capture. 9168 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9169 CaptureRegion = OMPD_target; 9170 break; 9171 case OMPD_target_teams_distribute_parallel_for: 9172 case OMPD_target_teams_distribute_parallel_for_simd: 9173 // If this clause applies to the nested 'parallel' region, capture within 9174 // the 'teams' region, otherwise do not capture. 9175 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9176 CaptureRegion = OMPD_teams; 9177 break; 9178 case OMPD_teams_distribute_parallel_for: 9179 case OMPD_teams_distribute_parallel_for_simd: 9180 CaptureRegion = OMPD_teams; 9181 break; 9182 case OMPD_target_update: 9183 case OMPD_target_enter_data: 9184 case OMPD_target_exit_data: 9185 CaptureRegion = OMPD_task; 9186 break; 9187 case OMPD_cancel: 9188 case OMPD_parallel: 9189 case OMPD_parallel_sections: 9190 case OMPD_parallel_for: 9191 case OMPD_parallel_for_simd: 9192 case OMPD_target: 9193 case OMPD_target_simd: 9194 case OMPD_target_teams: 9195 case OMPD_target_teams_distribute: 9196 case OMPD_target_teams_distribute_simd: 9197 case OMPD_distribute_parallel_for: 9198 case OMPD_distribute_parallel_for_simd: 9199 case OMPD_task: 9200 case OMPD_taskloop: 9201 case OMPD_taskloop_simd: 9202 case OMPD_target_data: 9203 // Do not capture if-clause expressions. 9204 break; 9205 case OMPD_threadprivate: 9206 case OMPD_allocate: 9207 case OMPD_taskyield: 9208 case OMPD_barrier: 9209 case OMPD_taskwait: 9210 case OMPD_cancellation_point: 9211 case OMPD_flush: 9212 case OMPD_declare_reduction: 9213 case OMPD_declare_mapper: 9214 case OMPD_declare_simd: 9215 case OMPD_declare_target: 9216 case OMPD_end_declare_target: 9217 case OMPD_teams: 9218 case OMPD_simd: 9219 case OMPD_for: 9220 case OMPD_for_simd: 9221 case OMPD_sections: 9222 case OMPD_section: 9223 case OMPD_single: 9224 case OMPD_master: 9225 case OMPD_critical: 9226 case OMPD_taskgroup: 9227 case OMPD_distribute: 9228 case OMPD_ordered: 9229 case OMPD_atomic: 9230 case OMPD_distribute_simd: 9231 case OMPD_teams_distribute: 9232 case OMPD_teams_distribute_simd: 9233 case OMPD_requires: 9234 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9235 case OMPD_unknown: 9236 llvm_unreachable("Unknown OpenMP directive"); 9237 } 9238 break; 9239 case OMPC_num_threads: 9240 switch (DKind) { 9241 case OMPD_target_parallel: 9242 case OMPD_target_parallel_for: 9243 case OMPD_target_parallel_for_simd: 9244 CaptureRegion = OMPD_target; 9245 break; 9246 case OMPD_teams_distribute_parallel_for: 9247 case OMPD_teams_distribute_parallel_for_simd: 9248 case OMPD_target_teams_distribute_parallel_for: 9249 case OMPD_target_teams_distribute_parallel_for_simd: 9250 CaptureRegion = OMPD_teams; 9251 break; 9252 case OMPD_parallel: 9253 case OMPD_parallel_sections: 9254 case OMPD_parallel_for: 9255 case OMPD_parallel_for_simd: 9256 case OMPD_distribute_parallel_for: 9257 case OMPD_distribute_parallel_for_simd: 9258 // Do not capture num_threads-clause expressions. 9259 break; 9260 case OMPD_target_data: 9261 case OMPD_target_enter_data: 9262 case OMPD_target_exit_data: 9263 case OMPD_target_update: 9264 case OMPD_target: 9265 case OMPD_target_simd: 9266 case OMPD_target_teams: 9267 case OMPD_target_teams_distribute: 9268 case OMPD_target_teams_distribute_simd: 9269 case OMPD_cancel: 9270 case OMPD_task: 9271 case OMPD_taskloop: 9272 case OMPD_taskloop_simd: 9273 case OMPD_threadprivate: 9274 case OMPD_allocate: 9275 case OMPD_taskyield: 9276 case OMPD_barrier: 9277 case OMPD_taskwait: 9278 case OMPD_cancellation_point: 9279 case OMPD_flush: 9280 case OMPD_declare_reduction: 9281 case OMPD_declare_mapper: 9282 case OMPD_declare_simd: 9283 case OMPD_declare_target: 9284 case OMPD_end_declare_target: 9285 case OMPD_teams: 9286 case OMPD_simd: 9287 case OMPD_for: 9288 case OMPD_for_simd: 9289 case OMPD_sections: 9290 case OMPD_section: 9291 case OMPD_single: 9292 case OMPD_master: 9293 case OMPD_critical: 9294 case OMPD_taskgroup: 9295 case OMPD_distribute: 9296 case OMPD_ordered: 9297 case OMPD_atomic: 9298 case OMPD_distribute_simd: 9299 case OMPD_teams_distribute: 9300 case OMPD_teams_distribute_simd: 9301 case OMPD_requires: 9302 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9303 case OMPD_unknown: 9304 llvm_unreachable("Unknown OpenMP directive"); 9305 } 9306 break; 9307 case OMPC_num_teams: 9308 switch (DKind) { 9309 case OMPD_target_teams: 9310 case OMPD_target_teams_distribute: 9311 case OMPD_target_teams_distribute_simd: 9312 case OMPD_target_teams_distribute_parallel_for: 9313 case OMPD_target_teams_distribute_parallel_for_simd: 9314 CaptureRegion = OMPD_target; 9315 break; 9316 case OMPD_teams_distribute_parallel_for: 9317 case OMPD_teams_distribute_parallel_for_simd: 9318 case OMPD_teams: 9319 case OMPD_teams_distribute: 9320 case OMPD_teams_distribute_simd: 9321 // Do not capture num_teams-clause expressions. 9322 break; 9323 case OMPD_distribute_parallel_for: 9324 case OMPD_distribute_parallel_for_simd: 9325 case OMPD_task: 9326 case OMPD_taskloop: 9327 case OMPD_taskloop_simd: 9328 case OMPD_target_data: 9329 case OMPD_target_enter_data: 9330 case OMPD_target_exit_data: 9331 case OMPD_target_update: 9332 case OMPD_cancel: 9333 case OMPD_parallel: 9334 case OMPD_parallel_sections: 9335 case OMPD_parallel_for: 9336 case OMPD_parallel_for_simd: 9337 case OMPD_target: 9338 case OMPD_target_simd: 9339 case OMPD_target_parallel: 9340 case OMPD_target_parallel_for: 9341 case OMPD_target_parallel_for_simd: 9342 case OMPD_threadprivate: 9343 case OMPD_allocate: 9344 case OMPD_taskyield: 9345 case OMPD_barrier: 9346 case OMPD_taskwait: 9347 case OMPD_cancellation_point: 9348 case OMPD_flush: 9349 case OMPD_declare_reduction: 9350 case OMPD_declare_mapper: 9351 case OMPD_declare_simd: 9352 case OMPD_declare_target: 9353 case OMPD_end_declare_target: 9354 case OMPD_simd: 9355 case OMPD_for: 9356 case OMPD_for_simd: 9357 case OMPD_sections: 9358 case OMPD_section: 9359 case OMPD_single: 9360 case OMPD_master: 9361 case OMPD_critical: 9362 case OMPD_taskgroup: 9363 case OMPD_distribute: 9364 case OMPD_ordered: 9365 case OMPD_atomic: 9366 case OMPD_distribute_simd: 9367 case OMPD_requires: 9368 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9369 case OMPD_unknown: 9370 llvm_unreachable("Unknown OpenMP directive"); 9371 } 9372 break; 9373 case OMPC_thread_limit: 9374 switch (DKind) { 9375 case OMPD_target_teams: 9376 case OMPD_target_teams_distribute: 9377 case OMPD_target_teams_distribute_simd: 9378 case OMPD_target_teams_distribute_parallel_for: 9379 case OMPD_target_teams_distribute_parallel_for_simd: 9380 CaptureRegion = OMPD_target; 9381 break; 9382 case OMPD_teams_distribute_parallel_for: 9383 case OMPD_teams_distribute_parallel_for_simd: 9384 case OMPD_teams: 9385 case OMPD_teams_distribute: 9386 case OMPD_teams_distribute_simd: 9387 // Do not capture thread_limit-clause expressions. 9388 break; 9389 case OMPD_distribute_parallel_for: 9390 case OMPD_distribute_parallel_for_simd: 9391 case OMPD_task: 9392 case OMPD_taskloop: 9393 case OMPD_taskloop_simd: 9394 case OMPD_target_data: 9395 case OMPD_target_enter_data: 9396 case OMPD_target_exit_data: 9397 case OMPD_target_update: 9398 case OMPD_cancel: 9399 case OMPD_parallel: 9400 case OMPD_parallel_sections: 9401 case OMPD_parallel_for: 9402 case OMPD_parallel_for_simd: 9403 case OMPD_target: 9404 case OMPD_target_simd: 9405 case OMPD_target_parallel: 9406 case OMPD_target_parallel_for: 9407 case OMPD_target_parallel_for_simd: 9408 case OMPD_threadprivate: 9409 case OMPD_allocate: 9410 case OMPD_taskyield: 9411 case OMPD_barrier: 9412 case OMPD_taskwait: 9413 case OMPD_cancellation_point: 9414 case OMPD_flush: 9415 case OMPD_declare_reduction: 9416 case OMPD_declare_mapper: 9417 case OMPD_declare_simd: 9418 case OMPD_declare_target: 9419 case OMPD_end_declare_target: 9420 case OMPD_simd: 9421 case OMPD_for: 9422 case OMPD_for_simd: 9423 case OMPD_sections: 9424 case OMPD_section: 9425 case OMPD_single: 9426 case OMPD_master: 9427 case OMPD_critical: 9428 case OMPD_taskgroup: 9429 case OMPD_distribute: 9430 case OMPD_ordered: 9431 case OMPD_atomic: 9432 case OMPD_distribute_simd: 9433 case OMPD_requires: 9434 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9435 case OMPD_unknown: 9436 llvm_unreachable("Unknown OpenMP directive"); 9437 } 9438 break; 9439 case OMPC_schedule: 9440 switch (DKind) { 9441 case OMPD_parallel_for: 9442 case OMPD_parallel_for_simd: 9443 case OMPD_distribute_parallel_for: 9444 case OMPD_distribute_parallel_for_simd: 9445 case OMPD_teams_distribute_parallel_for: 9446 case OMPD_teams_distribute_parallel_for_simd: 9447 case OMPD_target_parallel_for: 9448 case OMPD_target_parallel_for_simd: 9449 case OMPD_target_teams_distribute_parallel_for: 9450 case OMPD_target_teams_distribute_parallel_for_simd: 9451 CaptureRegion = OMPD_parallel; 9452 break; 9453 case OMPD_for: 9454 case OMPD_for_simd: 9455 // Do not capture schedule-clause expressions. 9456 break; 9457 case OMPD_task: 9458 case OMPD_taskloop: 9459 case OMPD_taskloop_simd: 9460 case OMPD_target_data: 9461 case OMPD_target_enter_data: 9462 case OMPD_target_exit_data: 9463 case OMPD_target_update: 9464 case OMPD_teams: 9465 case OMPD_teams_distribute: 9466 case OMPD_teams_distribute_simd: 9467 case OMPD_target_teams_distribute: 9468 case OMPD_target_teams_distribute_simd: 9469 case OMPD_target: 9470 case OMPD_target_simd: 9471 case OMPD_target_parallel: 9472 case OMPD_cancel: 9473 case OMPD_parallel: 9474 case OMPD_parallel_sections: 9475 case OMPD_threadprivate: 9476 case OMPD_allocate: 9477 case OMPD_taskyield: 9478 case OMPD_barrier: 9479 case OMPD_taskwait: 9480 case OMPD_cancellation_point: 9481 case OMPD_flush: 9482 case OMPD_declare_reduction: 9483 case OMPD_declare_mapper: 9484 case OMPD_declare_simd: 9485 case OMPD_declare_target: 9486 case OMPD_end_declare_target: 9487 case OMPD_simd: 9488 case OMPD_sections: 9489 case OMPD_section: 9490 case OMPD_single: 9491 case OMPD_master: 9492 case OMPD_critical: 9493 case OMPD_taskgroup: 9494 case OMPD_distribute: 9495 case OMPD_ordered: 9496 case OMPD_atomic: 9497 case OMPD_distribute_simd: 9498 case OMPD_target_teams: 9499 case OMPD_requires: 9500 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9501 case OMPD_unknown: 9502 llvm_unreachable("Unknown OpenMP directive"); 9503 } 9504 break; 9505 case OMPC_dist_schedule: 9506 switch (DKind) { 9507 case OMPD_teams_distribute_parallel_for: 9508 case OMPD_teams_distribute_parallel_for_simd: 9509 case OMPD_teams_distribute: 9510 case OMPD_teams_distribute_simd: 9511 case OMPD_target_teams_distribute_parallel_for: 9512 case OMPD_target_teams_distribute_parallel_for_simd: 9513 case OMPD_target_teams_distribute: 9514 case OMPD_target_teams_distribute_simd: 9515 CaptureRegion = OMPD_teams; 9516 break; 9517 case OMPD_distribute_parallel_for: 9518 case OMPD_distribute_parallel_for_simd: 9519 case OMPD_distribute: 9520 case OMPD_distribute_simd: 9521 // Do not capture thread_limit-clause expressions. 9522 break; 9523 case OMPD_parallel_for: 9524 case OMPD_parallel_for_simd: 9525 case OMPD_target_parallel_for_simd: 9526 case OMPD_target_parallel_for: 9527 case OMPD_task: 9528 case OMPD_taskloop: 9529 case OMPD_taskloop_simd: 9530 case OMPD_target_data: 9531 case OMPD_target_enter_data: 9532 case OMPD_target_exit_data: 9533 case OMPD_target_update: 9534 case OMPD_teams: 9535 case OMPD_target: 9536 case OMPD_target_simd: 9537 case OMPD_target_parallel: 9538 case OMPD_cancel: 9539 case OMPD_parallel: 9540 case OMPD_parallel_sections: 9541 case OMPD_threadprivate: 9542 case OMPD_allocate: 9543 case OMPD_taskyield: 9544 case OMPD_barrier: 9545 case OMPD_taskwait: 9546 case OMPD_cancellation_point: 9547 case OMPD_flush: 9548 case OMPD_declare_reduction: 9549 case OMPD_declare_mapper: 9550 case OMPD_declare_simd: 9551 case OMPD_declare_target: 9552 case OMPD_end_declare_target: 9553 case OMPD_simd: 9554 case OMPD_for: 9555 case OMPD_for_simd: 9556 case OMPD_sections: 9557 case OMPD_section: 9558 case OMPD_single: 9559 case OMPD_master: 9560 case OMPD_critical: 9561 case OMPD_taskgroup: 9562 case OMPD_ordered: 9563 case OMPD_atomic: 9564 case OMPD_target_teams: 9565 case OMPD_requires: 9566 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9567 case OMPD_unknown: 9568 llvm_unreachable("Unknown OpenMP directive"); 9569 } 9570 break; 9571 case OMPC_device: 9572 switch (DKind) { 9573 case OMPD_target_update: 9574 case OMPD_target_enter_data: 9575 case OMPD_target_exit_data: 9576 case OMPD_target: 9577 case OMPD_target_simd: 9578 case OMPD_target_teams: 9579 case OMPD_target_parallel: 9580 case OMPD_target_teams_distribute: 9581 case OMPD_target_teams_distribute_simd: 9582 case OMPD_target_parallel_for: 9583 case OMPD_target_parallel_for_simd: 9584 case OMPD_target_teams_distribute_parallel_for: 9585 case OMPD_target_teams_distribute_parallel_for_simd: 9586 CaptureRegion = OMPD_task; 9587 break; 9588 case OMPD_target_data: 9589 // Do not capture device-clause expressions. 9590 break; 9591 case OMPD_teams_distribute_parallel_for: 9592 case OMPD_teams_distribute_parallel_for_simd: 9593 case OMPD_teams: 9594 case OMPD_teams_distribute: 9595 case OMPD_teams_distribute_simd: 9596 case OMPD_distribute_parallel_for: 9597 case OMPD_distribute_parallel_for_simd: 9598 case OMPD_task: 9599 case OMPD_taskloop: 9600 case OMPD_taskloop_simd: 9601 case OMPD_cancel: 9602 case OMPD_parallel: 9603 case OMPD_parallel_sections: 9604 case OMPD_parallel_for: 9605 case OMPD_parallel_for_simd: 9606 case OMPD_threadprivate: 9607 case OMPD_allocate: 9608 case OMPD_taskyield: 9609 case OMPD_barrier: 9610 case OMPD_taskwait: 9611 case OMPD_cancellation_point: 9612 case OMPD_flush: 9613 case OMPD_declare_reduction: 9614 case OMPD_declare_mapper: 9615 case OMPD_declare_simd: 9616 case OMPD_declare_target: 9617 case OMPD_end_declare_target: 9618 case OMPD_simd: 9619 case OMPD_for: 9620 case OMPD_for_simd: 9621 case OMPD_sections: 9622 case OMPD_section: 9623 case OMPD_single: 9624 case OMPD_master: 9625 case OMPD_critical: 9626 case OMPD_taskgroup: 9627 case OMPD_distribute: 9628 case OMPD_ordered: 9629 case OMPD_atomic: 9630 case OMPD_distribute_simd: 9631 case OMPD_requires: 9632 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9633 case OMPD_unknown: 9634 llvm_unreachable("Unknown OpenMP directive"); 9635 } 9636 break; 9637 case OMPC_firstprivate: 9638 case OMPC_lastprivate: 9639 case OMPC_reduction: 9640 case OMPC_task_reduction: 9641 case OMPC_in_reduction: 9642 case OMPC_linear: 9643 case OMPC_default: 9644 case OMPC_proc_bind: 9645 case OMPC_final: 9646 case OMPC_safelen: 9647 case OMPC_simdlen: 9648 case OMPC_allocator: 9649 case OMPC_collapse: 9650 case OMPC_private: 9651 case OMPC_shared: 9652 case OMPC_aligned: 9653 case OMPC_copyin: 9654 case OMPC_copyprivate: 9655 case OMPC_ordered: 9656 case OMPC_nowait: 9657 case OMPC_untied: 9658 case OMPC_mergeable: 9659 case OMPC_threadprivate: 9660 case OMPC_allocate: 9661 case OMPC_flush: 9662 case OMPC_read: 9663 case OMPC_write: 9664 case OMPC_update: 9665 case OMPC_capture: 9666 case OMPC_seq_cst: 9667 case OMPC_depend: 9668 case OMPC_threads: 9669 case OMPC_simd: 9670 case OMPC_map: 9671 case OMPC_priority: 9672 case OMPC_grainsize: 9673 case OMPC_nogroup: 9674 case OMPC_num_tasks: 9675 case OMPC_hint: 9676 case OMPC_defaultmap: 9677 case OMPC_unknown: 9678 case OMPC_uniform: 9679 case OMPC_to: 9680 case OMPC_from: 9681 case OMPC_use_device_ptr: 9682 case OMPC_is_device_ptr: 9683 case OMPC_unified_address: 9684 case OMPC_unified_shared_memory: 9685 case OMPC_reverse_offload: 9686 case OMPC_dynamic_allocators: 9687 case OMPC_atomic_default_mem_order: 9688 llvm_unreachable("Unexpected OpenMP clause."); 9689 } 9690 return CaptureRegion; 9691 } 9692 9693 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9694 Expr *Condition, SourceLocation StartLoc, 9695 SourceLocation LParenLoc, 9696 SourceLocation NameModifierLoc, 9697 SourceLocation ColonLoc, 9698 SourceLocation EndLoc) { 9699 Expr *ValExpr = Condition; 9700 Stmt *HelperValStmt = nullptr; 9701 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9702 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9703 !Condition->isInstantiationDependent() && 9704 !Condition->containsUnexpandedParameterPack()) { 9705 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9706 if (Val.isInvalid()) 9707 return nullptr; 9708 9709 ValExpr = Val.get(); 9710 9711 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9712 CaptureRegion = 9713 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9714 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9715 ValExpr = MakeFullExpr(ValExpr).get(); 9716 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9717 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9718 HelperValStmt = buildPreInits(Context, Captures); 9719 } 9720 } 9721 9722 return new (Context) 9723 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9724 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9725 } 9726 9727 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9728 SourceLocation StartLoc, 9729 SourceLocation LParenLoc, 9730 SourceLocation EndLoc) { 9731 Expr *ValExpr = Condition; 9732 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9733 !Condition->isInstantiationDependent() && 9734 !Condition->containsUnexpandedParameterPack()) { 9735 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9736 if (Val.isInvalid()) 9737 return nullptr; 9738 9739 ValExpr = MakeFullExpr(Val.get()).get(); 9740 } 9741 9742 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9743 } 9744 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9745 Expr *Op) { 9746 if (!Op) 9747 return ExprError(); 9748 9749 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9750 public: 9751 IntConvertDiagnoser() 9752 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9753 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9754 QualType T) override { 9755 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9756 } 9757 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9758 QualType T) override { 9759 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9760 } 9761 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9762 QualType T, 9763 QualType ConvTy) override { 9764 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9765 } 9766 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9767 QualType ConvTy) override { 9768 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9769 << ConvTy->isEnumeralType() << ConvTy; 9770 } 9771 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9772 QualType T) override { 9773 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9774 } 9775 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9776 QualType ConvTy) override { 9777 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9778 << ConvTy->isEnumeralType() << ConvTy; 9779 } 9780 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9781 QualType) override { 9782 llvm_unreachable("conversion functions are permitted"); 9783 } 9784 } ConvertDiagnoser; 9785 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9786 } 9787 9788 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9789 OpenMPClauseKind CKind, 9790 bool StrictlyPositive) { 9791 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9792 !ValExpr->isInstantiationDependent()) { 9793 SourceLocation Loc = ValExpr->getExprLoc(); 9794 ExprResult Value = 9795 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9796 if (Value.isInvalid()) 9797 return false; 9798 9799 ValExpr = Value.get(); 9800 // The expression must evaluate to a non-negative integer value. 9801 llvm::APSInt Result; 9802 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9803 Result.isSigned() && 9804 !((!StrictlyPositive && Result.isNonNegative()) || 9805 (StrictlyPositive && Result.isStrictlyPositive()))) { 9806 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9807 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9808 << ValExpr->getSourceRange(); 9809 return false; 9810 } 9811 } 9812 return true; 9813 } 9814 9815 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9816 SourceLocation StartLoc, 9817 SourceLocation LParenLoc, 9818 SourceLocation EndLoc) { 9819 Expr *ValExpr = NumThreads; 9820 Stmt *HelperValStmt = nullptr; 9821 9822 // OpenMP [2.5, Restrictions] 9823 // The num_threads expression must evaluate to a positive integer value. 9824 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9825 /*StrictlyPositive=*/true)) 9826 return nullptr; 9827 9828 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9829 OpenMPDirectiveKind CaptureRegion = 9830 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9831 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9832 ValExpr = MakeFullExpr(ValExpr).get(); 9833 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9834 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9835 HelperValStmt = buildPreInits(Context, Captures); 9836 } 9837 9838 return new (Context) OMPNumThreadsClause( 9839 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9840 } 9841 9842 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9843 OpenMPClauseKind CKind, 9844 bool StrictlyPositive) { 9845 if (!E) 9846 return ExprError(); 9847 if (E->isValueDependent() || E->isTypeDependent() || 9848 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9849 return E; 9850 llvm::APSInt Result; 9851 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9852 if (ICE.isInvalid()) 9853 return ExprError(); 9854 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9855 (!StrictlyPositive && !Result.isNonNegative())) { 9856 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9857 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9858 << E->getSourceRange(); 9859 return ExprError(); 9860 } 9861 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9862 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9863 << E->getSourceRange(); 9864 return ExprError(); 9865 } 9866 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9867 DSAStack->setAssociatedLoops(Result.getExtValue()); 9868 else if (CKind == OMPC_ordered) 9869 DSAStack->setAssociatedLoops(Result.getExtValue()); 9870 return ICE; 9871 } 9872 9873 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9874 SourceLocation LParenLoc, 9875 SourceLocation EndLoc) { 9876 // OpenMP [2.8.1, simd construct, Description] 9877 // The parameter of the safelen clause must be a constant 9878 // positive integer expression. 9879 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9880 if (Safelen.isInvalid()) 9881 return nullptr; 9882 return new (Context) 9883 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9884 } 9885 9886 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9887 SourceLocation LParenLoc, 9888 SourceLocation EndLoc) { 9889 // OpenMP [2.8.1, simd construct, Description] 9890 // The parameter of the simdlen clause must be a constant 9891 // positive integer expression. 9892 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9893 if (Simdlen.isInvalid()) 9894 return nullptr; 9895 return new (Context) 9896 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9897 } 9898 9899 /// Tries to find omp_allocator_handle_t type. 9900 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9901 DSAStackTy *Stack) { 9902 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 9903 if (!OMPAllocatorHandleT.isNull()) 9904 return true; 9905 // Build the predefined allocator expressions. 9906 bool ErrorFound = false; 9907 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 9908 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 9909 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 9910 StringRef Allocator = 9911 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 9912 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 9913 auto *VD = dyn_cast_or_null<ValueDecl>( 9914 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 9915 if (!VD) { 9916 ErrorFound = true; 9917 break; 9918 } 9919 QualType AllocatorType = 9920 VD->getType().getNonLValueExprType(S.getASTContext()); 9921 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 9922 if (!Res.isUsable()) { 9923 ErrorFound = true; 9924 break; 9925 } 9926 if (OMPAllocatorHandleT.isNull()) 9927 OMPAllocatorHandleT = AllocatorType; 9928 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 9929 ErrorFound = true; 9930 break; 9931 } 9932 Stack->setAllocator(AllocatorKind, Res.get()); 9933 } 9934 if (ErrorFound) { 9935 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 9936 return false; 9937 } 9938 OMPAllocatorHandleT.addConst(); 9939 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 9940 return true; 9941 } 9942 9943 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 9944 SourceLocation LParenLoc, 9945 SourceLocation EndLoc) { 9946 // OpenMP [2.11.3, allocate Directive, Description] 9947 // allocator is an expression of omp_allocator_handle_t type. 9948 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 9949 return nullptr; 9950 9951 ExprResult Allocator = DefaultLvalueConversion(A); 9952 if (Allocator.isInvalid()) 9953 return nullptr; 9954 Allocator = PerformImplicitConversion(Allocator.get(), 9955 DSAStack->getOMPAllocatorHandleT(), 9956 Sema::AA_Initializing, 9957 /*AllowExplicit=*/true); 9958 if (Allocator.isInvalid()) 9959 return nullptr; 9960 return new (Context) 9961 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 9962 } 9963 9964 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 9965 SourceLocation StartLoc, 9966 SourceLocation LParenLoc, 9967 SourceLocation EndLoc) { 9968 // OpenMP [2.7.1, loop construct, Description] 9969 // OpenMP [2.8.1, simd construct, Description] 9970 // OpenMP [2.9.6, distribute construct, Description] 9971 // The parameter of the collapse clause must be a constant 9972 // positive integer expression. 9973 ExprResult NumForLoopsResult = 9974 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 9975 if (NumForLoopsResult.isInvalid()) 9976 return nullptr; 9977 return new (Context) 9978 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 9979 } 9980 9981 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 9982 SourceLocation EndLoc, 9983 SourceLocation LParenLoc, 9984 Expr *NumForLoops) { 9985 // OpenMP [2.7.1, loop construct, Description] 9986 // OpenMP [2.8.1, simd construct, Description] 9987 // OpenMP [2.9.6, distribute construct, Description] 9988 // The parameter of the ordered clause must be a constant 9989 // positive integer expression if any. 9990 if (NumForLoops && LParenLoc.isValid()) { 9991 ExprResult NumForLoopsResult = 9992 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 9993 if (NumForLoopsResult.isInvalid()) 9994 return nullptr; 9995 NumForLoops = NumForLoopsResult.get(); 9996 } else { 9997 NumForLoops = nullptr; 9998 } 9999 auto *Clause = OMPOrderedClause::Create( 10000 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10001 StartLoc, LParenLoc, EndLoc); 10002 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10003 return Clause; 10004 } 10005 10006 OMPClause *Sema::ActOnOpenMPSimpleClause( 10007 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10008 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10009 OMPClause *Res = nullptr; 10010 switch (Kind) { 10011 case OMPC_default: 10012 Res = 10013 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10014 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10015 break; 10016 case OMPC_proc_bind: 10017 Res = ActOnOpenMPProcBindClause( 10018 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10019 LParenLoc, EndLoc); 10020 break; 10021 case OMPC_atomic_default_mem_order: 10022 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10023 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10024 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10025 break; 10026 case OMPC_if: 10027 case OMPC_final: 10028 case OMPC_num_threads: 10029 case OMPC_safelen: 10030 case OMPC_simdlen: 10031 case OMPC_allocator: 10032 case OMPC_collapse: 10033 case OMPC_schedule: 10034 case OMPC_private: 10035 case OMPC_firstprivate: 10036 case OMPC_lastprivate: 10037 case OMPC_shared: 10038 case OMPC_reduction: 10039 case OMPC_task_reduction: 10040 case OMPC_in_reduction: 10041 case OMPC_linear: 10042 case OMPC_aligned: 10043 case OMPC_copyin: 10044 case OMPC_copyprivate: 10045 case OMPC_ordered: 10046 case OMPC_nowait: 10047 case OMPC_untied: 10048 case OMPC_mergeable: 10049 case OMPC_threadprivate: 10050 case OMPC_allocate: 10051 case OMPC_flush: 10052 case OMPC_read: 10053 case OMPC_write: 10054 case OMPC_update: 10055 case OMPC_capture: 10056 case OMPC_seq_cst: 10057 case OMPC_depend: 10058 case OMPC_device: 10059 case OMPC_threads: 10060 case OMPC_simd: 10061 case OMPC_map: 10062 case OMPC_num_teams: 10063 case OMPC_thread_limit: 10064 case OMPC_priority: 10065 case OMPC_grainsize: 10066 case OMPC_nogroup: 10067 case OMPC_num_tasks: 10068 case OMPC_hint: 10069 case OMPC_dist_schedule: 10070 case OMPC_defaultmap: 10071 case OMPC_unknown: 10072 case OMPC_uniform: 10073 case OMPC_to: 10074 case OMPC_from: 10075 case OMPC_use_device_ptr: 10076 case OMPC_is_device_ptr: 10077 case OMPC_unified_address: 10078 case OMPC_unified_shared_memory: 10079 case OMPC_reverse_offload: 10080 case OMPC_dynamic_allocators: 10081 llvm_unreachable("Clause is not allowed."); 10082 } 10083 return Res; 10084 } 10085 10086 static std::string 10087 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10088 ArrayRef<unsigned> Exclude = llvm::None) { 10089 SmallString<256> Buffer; 10090 llvm::raw_svector_ostream Out(Buffer); 10091 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10092 unsigned Skipped = Exclude.size(); 10093 auto S = Exclude.begin(), E = Exclude.end(); 10094 for (unsigned I = First; I < Last; ++I) { 10095 if (std::find(S, E, I) != E) { 10096 --Skipped; 10097 continue; 10098 } 10099 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10100 if (I == Bound - Skipped) 10101 Out << " or "; 10102 else if (I != Bound + 1 - Skipped) 10103 Out << ", "; 10104 } 10105 return Out.str(); 10106 } 10107 10108 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10109 SourceLocation KindKwLoc, 10110 SourceLocation StartLoc, 10111 SourceLocation LParenLoc, 10112 SourceLocation EndLoc) { 10113 if (Kind == OMPC_DEFAULT_unknown) { 10114 static_assert(OMPC_DEFAULT_unknown > 0, 10115 "OMPC_DEFAULT_unknown not greater than 0"); 10116 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10117 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10118 /*Last=*/OMPC_DEFAULT_unknown) 10119 << getOpenMPClauseName(OMPC_default); 10120 return nullptr; 10121 } 10122 switch (Kind) { 10123 case OMPC_DEFAULT_none: 10124 DSAStack->setDefaultDSANone(KindKwLoc); 10125 break; 10126 case OMPC_DEFAULT_shared: 10127 DSAStack->setDefaultDSAShared(KindKwLoc); 10128 break; 10129 case OMPC_DEFAULT_unknown: 10130 llvm_unreachable("Clause kind is not allowed."); 10131 break; 10132 } 10133 return new (Context) 10134 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10135 } 10136 10137 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10138 SourceLocation KindKwLoc, 10139 SourceLocation StartLoc, 10140 SourceLocation LParenLoc, 10141 SourceLocation EndLoc) { 10142 if (Kind == OMPC_PROC_BIND_unknown) { 10143 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10144 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10145 /*Last=*/OMPC_PROC_BIND_unknown) 10146 << getOpenMPClauseName(OMPC_proc_bind); 10147 return nullptr; 10148 } 10149 return new (Context) 10150 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10151 } 10152 10153 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10154 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10155 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10156 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10157 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10158 << getListOfPossibleValues( 10159 OMPC_atomic_default_mem_order, /*First=*/0, 10160 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10161 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10162 return nullptr; 10163 } 10164 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10165 LParenLoc, EndLoc); 10166 } 10167 10168 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10169 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10170 SourceLocation StartLoc, SourceLocation LParenLoc, 10171 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10172 SourceLocation EndLoc) { 10173 OMPClause *Res = nullptr; 10174 switch (Kind) { 10175 case OMPC_schedule: 10176 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10177 assert(Argument.size() == NumberOfElements && 10178 ArgumentLoc.size() == NumberOfElements); 10179 Res = ActOnOpenMPScheduleClause( 10180 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10181 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10182 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10183 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10184 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10185 break; 10186 case OMPC_if: 10187 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10188 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10189 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10190 DelimLoc, EndLoc); 10191 break; 10192 case OMPC_dist_schedule: 10193 Res = ActOnOpenMPDistScheduleClause( 10194 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10195 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10196 break; 10197 case OMPC_defaultmap: 10198 enum { Modifier, DefaultmapKind }; 10199 Res = ActOnOpenMPDefaultmapClause( 10200 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10201 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10202 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10203 EndLoc); 10204 break; 10205 case OMPC_final: 10206 case OMPC_num_threads: 10207 case OMPC_safelen: 10208 case OMPC_simdlen: 10209 case OMPC_allocator: 10210 case OMPC_collapse: 10211 case OMPC_default: 10212 case OMPC_proc_bind: 10213 case OMPC_private: 10214 case OMPC_firstprivate: 10215 case OMPC_lastprivate: 10216 case OMPC_shared: 10217 case OMPC_reduction: 10218 case OMPC_task_reduction: 10219 case OMPC_in_reduction: 10220 case OMPC_linear: 10221 case OMPC_aligned: 10222 case OMPC_copyin: 10223 case OMPC_copyprivate: 10224 case OMPC_ordered: 10225 case OMPC_nowait: 10226 case OMPC_untied: 10227 case OMPC_mergeable: 10228 case OMPC_threadprivate: 10229 case OMPC_allocate: 10230 case OMPC_flush: 10231 case OMPC_read: 10232 case OMPC_write: 10233 case OMPC_update: 10234 case OMPC_capture: 10235 case OMPC_seq_cst: 10236 case OMPC_depend: 10237 case OMPC_device: 10238 case OMPC_threads: 10239 case OMPC_simd: 10240 case OMPC_map: 10241 case OMPC_num_teams: 10242 case OMPC_thread_limit: 10243 case OMPC_priority: 10244 case OMPC_grainsize: 10245 case OMPC_nogroup: 10246 case OMPC_num_tasks: 10247 case OMPC_hint: 10248 case OMPC_unknown: 10249 case OMPC_uniform: 10250 case OMPC_to: 10251 case OMPC_from: 10252 case OMPC_use_device_ptr: 10253 case OMPC_is_device_ptr: 10254 case OMPC_unified_address: 10255 case OMPC_unified_shared_memory: 10256 case OMPC_reverse_offload: 10257 case OMPC_dynamic_allocators: 10258 case OMPC_atomic_default_mem_order: 10259 llvm_unreachable("Clause is not allowed."); 10260 } 10261 return Res; 10262 } 10263 10264 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10265 OpenMPScheduleClauseModifier M2, 10266 SourceLocation M1Loc, SourceLocation M2Loc) { 10267 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10268 SmallVector<unsigned, 2> Excluded; 10269 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10270 Excluded.push_back(M2); 10271 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10272 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10273 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10274 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10275 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10276 << getListOfPossibleValues(OMPC_schedule, 10277 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10278 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10279 Excluded) 10280 << getOpenMPClauseName(OMPC_schedule); 10281 return true; 10282 } 10283 return false; 10284 } 10285 10286 OMPClause *Sema::ActOnOpenMPScheduleClause( 10287 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10288 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10289 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10290 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10291 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10292 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10293 return nullptr; 10294 // OpenMP, 2.7.1, Loop Construct, Restrictions 10295 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10296 // but not both. 10297 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10298 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10299 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10300 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10301 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10302 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10303 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10304 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10305 return nullptr; 10306 } 10307 if (Kind == OMPC_SCHEDULE_unknown) { 10308 std::string Values; 10309 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10310 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10311 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10312 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10313 Exclude); 10314 } else { 10315 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10316 /*Last=*/OMPC_SCHEDULE_unknown); 10317 } 10318 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10319 << Values << getOpenMPClauseName(OMPC_schedule); 10320 return nullptr; 10321 } 10322 // OpenMP, 2.7.1, Loop Construct, Restrictions 10323 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10324 // schedule(guided). 10325 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10326 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10327 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10328 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10329 diag::err_omp_schedule_nonmonotonic_static); 10330 return nullptr; 10331 } 10332 Expr *ValExpr = ChunkSize; 10333 Stmt *HelperValStmt = nullptr; 10334 if (ChunkSize) { 10335 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10336 !ChunkSize->isInstantiationDependent() && 10337 !ChunkSize->containsUnexpandedParameterPack()) { 10338 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10339 ExprResult Val = 10340 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10341 if (Val.isInvalid()) 10342 return nullptr; 10343 10344 ValExpr = Val.get(); 10345 10346 // OpenMP [2.7.1, Restrictions] 10347 // chunk_size must be a loop invariant integer expression with a positive 10348 // value. 10349 llvm::APSInt Result; 10350 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10351 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10352 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10353 << "schedule" << 1 << ChunkSize->getSourceRange(); 10354 return nullptr; 10355 } 10356 } else if (getOpenMPCaptureRegionForClause( 10357 DSAStack->getCurrentDirective(), OMPC_schedule) != 10358 OMPD_unknown && 10359 !CurContext->isDependentContext()) { 10360 ValExpr = MakeFullExpr(ValExpr).get(); 10361 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10362 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10363 HelperValStmt = buildPreInits(Context, Captures); 10364 } 10365 } 10366 } 10367 10368 return new (Context) 10369 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10370 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10371 } 10372 10373 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10374 SourceLocation StartLoc, 10375 SourceLocation EndLoc) { 10376 OMPClause *Res = nullptr; 10377 switch (Kind) { 10378 case OMPC_ordered: 10379 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10380 break; 10381 case OMPC_nowait: 10382 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10383 break; 10384 case OMPC_untied: 10385 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10386 break; 10387 case OMPC_mergeable: 10388 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10389 break; 10390 case OMPC_read: 10391 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10392 break; 10393 case OMPC_write: 10394 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10395 break; 10396 case OMPC_update: 10397 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10398 break; 10399 case OMPC_capture: 10400 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10401 break; 10402 case OMPC_seq_cst: 10403 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10404 break; 10405 case OMPC_threads: 10406 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10407 break; 10408 case OMPC_simd: 10409 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10410 break; 10411 case OMPC_nogroup: 10412 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10413 break; 10414 case OMPC_unified_address: 10415 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10416 break; 10417 case OMPC_unified_shared_memory: 10418 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10419 break; 10420 case OMPC_reverse_offload: 10421 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10422 break; 10423 case OMPC_dynamic_allocators: 10424 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10425 break; 10426 case OMPC_if: 10427 case OMPC_final: 10428 case OMPC_num_threads: 10429 case OMPC_safelen: 10430 case OMPC_simdlen: 10431 case OMPC_allocator: 10432 case OMPC_collapse: 10433 case OMPC_schedule: 10434 case OMPC_private: 10435 case OMPC_firstprivate: 10436 case OMPC_lastprivate: 10437 case OMPC_shared: 10438 case OMPC_reduction: 10439 case OMPC_task_reduction: 10440 case OMPC_in_reduction: 10441 case OMPC_linear: 10442 case OMPC_aligned: 10443 case OMPC_copyin: 10444 case OMPC_copyprivate: 10445 case OMPC_default: 10446 case OMPC_proc_bind: 10447 case OMPC_threadprivate: 10448 case OMPC_allocate: 10449 case OMPC_flush: 10450 case OMPC_depend: 10451 case OMPC_device: 10452 case OMPC_map: 10453 case OMPC_num_teams: 10454 case OMPC_thread_limit: 10455 case OMPC_priority: 10456 case OMPC_grainsize: 10457 case OMPC_num_tasks: 10458 case OMPC_hint: 10459 case OMPC_dist_schedule: 10460 case OMPC_defaultmap: 10461 case OMPC_unknown: 10462 case OMPC_uniform: 10463 case OMPC_to: 10464 case OMPC_from: 10465 case OMPC_use_device_ptr: 10466 case OMPC_is_device_ptr: 10467 case OMPC_atomic_default_mem_order: 10468 llvm_unreachable("Clause is not allowed."); 10469 } 10470 return Res; 10471 } 10472 10473 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10474 SourceLocation EndLoc) { 10475 DSAStack->setNowaitRegion(); 10476 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10477 } 10478 10479 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10480 SourceLocation EndLoc) { 10481 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10482 } 10483 10484 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10485 SourceLocation EndLoc) { 10486 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10487 } 10488 10489 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10490 SourceLocation EndLoc) { 10491 return new (Context) OMPReadClause(StartLoc, EndLoc); 10492 } 10493 10494 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10495 SourceLocation EndLoc) { 10496 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10497 } 10498 10499 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10500 SourceLocation EndLoc) { 10501 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10502 } 10503 10504 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10505 SourceLocation EndLoc) { 10506 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10507 } 10508 10509 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10510 SourceLocation EndLoc) { 10511 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10512 } 10513 10514 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10515 SourceLocation EndLoc) { 10516 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10517 } 10518 10519 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 10520 SourceLocation EndLoc) { 10521 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 10522 } 10523 10524 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 10525 SourceLocation EndLoc) { 10526 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 10527 } 10528 10529 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 10530 SourceLocation EndLoc) { 10531 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 10532 } 10533 10534 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 10535 SourceLocation EndLoc) { 10536 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10537 } 10538 10539 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 10540 SourceLocation EndLoc) { 10541 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 10542 } 10543 10544 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 10545 SourceLocation EndLoc) { 10546 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 10547 } 10548 10549 OMPClause *Sema::ActOnOpenMPVarListClause( 10550 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 10551 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 10552 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 10553 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 10554 OpenMPLinearClauseKind LinKind, 10555 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 10556 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 10557 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 10558 SourceLocation StartLoc = Locs.StartLoc; 10559 SourceLocation LParenLoc = Locs.LParenLoc; 10560 SourceLocation EndLoc = Locs.EndLoc; 10561 OMPClause *Res = nullptr; 10562 switch (Kind) { 10563 case OMPC_private: 10564 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10565 break; 10566 case OMPC_firstprivate: 10567 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10568 break; 10569 case OMPC_lastprivate: 10570 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10571 break; 10572 case OMPC_shared: 10573 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10574 break; 10575 case OMPC_reduction: 10576 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10577 EndLoc, ReductionOrMapperIdScopeSpec, 10578 ReductionOrMapperId); 10579 break; 10580 case OMPC_task_reduction: 10581 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10582 EndLoc, ReductionOrMapperIdScopeSpec, 10583 ReductionOrMapperId); 10584 break; 10585 case OMPC_in_reduction: 10586 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10587 EndLoc, ReductionOrMapperIdScopeSpec, 10588 ReductionOrMapperId); 10589 break; 10590 case OMPC_linear: 10591 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10592 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10593 break; 10594 case OMPC_aligned: 10595 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10596 ColonLoc, EndLoc); 10597 break; 10598 case OMPC_copyin: 10599 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10600 break; 10601 case OMPC_copyprivate: 10602 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10603 break; 10604 case OMPC_flush: 10605 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10606 break; 10607 case OMPC_depend: 10608 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10609 StartLoc, LParenLoc, EndLoc); 10610 break; 10611 case OMPC_map: 10612 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10613 ReductionOrMapperIdScopeSpec, 10614 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10615 DepLinMapLoc, ColonLoc, VarList, Locs); 10616 break; 10617 case OMPC_to: 10618 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10619 ReductionOrMapperId, Locs); 10620 break; 10621 case OMPC_from: 10622 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10623 ReductionOrMapperId, Locs); 10624 break; 10625 case OMPC_use_device_ptr: 10626 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10627 break; 10628 case OMPC_is_device_ptr: 10629 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10630 break; 10631 case OMPC_allocate: 10632 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 10633 ColonLoc, EndLoc); 10634 break; 10635 case OMPC_if: 10636 case OMPC_final: 10637 case OMPC_num_threads: 10638 case OMPC_safelen: 10639 case OMPC_simdlen: 10640 case OMPC_allocator: 10641 case OMPC_collapse: 10642 case OMPC_default: 10643 case OMPC_proc_bind: 10644 case OMPC_schedule: 10645 case OMPC_ordered: 10646 case OMPC_nowait: 10647 case OMPC_untied: 10648 case OMPC_mergeable: 10649 case OMPC_threadprivate: 10650 case OMPC_read: 10651 case OMPC_write: 10652 case OMPC_update: 10653 case OMPC_capture: 10654 case OMPC_seq_cst: 10655 case OMPC_device: 10656 case OMPC_threads: 10657 case OMPC_simd: 10658 case OMPC_num_teams: 10659 case OMPC_thread_limit: 10660 case OMPC_priority: 10661 case OMPC_grainsize: 10662 case OMPC_nogroup: 10663 case OMPC_num_tasks: 10664 case OMPC_hint: 10665 case OMPC_dist_schedule: 10666 case OMPC_defaultmap: 10667 case OMPC_unknown: 10668 case OMPC_uniform: 10669 case OMPC_unified_address: 10670 case OMPC_unified_shared_memory: 10671 case OMPC_reverse_offload: 10672 case OMPC_dynamic_allocators: 10673 case OMPC_atomic_default_mem_order: 10674 llvm_unreachable("Clause is not allowed."); 10675 } 10676 return Res; 10677 } 10678 10679 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10680 ExprObjectKind OK, SourceLocation Loc) { 10681 ExprResult Res = BuildDeclRefExpr( 10682 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10683 if (!Res.isUsable()) 10684 return ExprError(); 10685 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10686 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10687 if (!Res.isUsable()) 10688 return ExprError(); 10689 } 10690 if (VK != VK_LValue && Res.get()->isGLValue()) { 10691 Res = DefaultLvalueConversion(Res.get()); 10692 if (!Res.isUsable()) 10693 return ExprError(); 10694 } 10695 return Res; 10696 } 10697 10698 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10699 SourceLocation StartLoc, 10700 SourceLocation LParenLoc, 10701 SourceLocation EndLoc) { 10702 SmallVector<Expr *, 8> Vars; 10703 SmallVector<Expr *, 8> PrivateCopies; 10704 for (Expr *RefExpr : VarList) { 10705 assert(RefExpr && "NULL expr in OpenMP private clause."); 10706 SourceLocation ELoc; 10707 SourceRange ERange; 10708 Expr *SimpleRefExpr = RefExpr; 10709 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10710 if (Res.second) { 10711 // It will be analyzed later. 10712 Vars.push_back(RefExpr); 10713 PrivateCopies.push_back(nullptr); 10714 } 10715 ValueDecl *D = Res.first; 10716 if (!D) 10717 continue; 10718 10719 QualType Type = D->getType(); 10720 auto *VD = dyn_cast<VarDecl>(D); 10721 10722 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10723 // A variable that appears in a private clause must not have an incomplete 10724 // type or a reference type. 10725 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10726 continue; 10727 Type = Type.getNonReferenceType(); 10728 10729 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10730 // A variable that is privatized must not have a const-qualified type 10731 // unless it is of class type with a mutable member. This restriction does 10732 // not apply to the firstprivate clause. 10733 // 10734 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10735 // A variable that appears in a private clause must not have a 10736 // const-qualified type unless it is of class type with a mutable member. 10737 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10738 continue; 10739 10740 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10741 // in a Construct] 10742 // Variables with the predetermined data-sharing attributes may not be 10743 // listed in data-sharing attributes clauses, except for the cases 10744 // listed below. For these exceptions only, listing a predetermined 10745 // variable in a data-sharing attribute clause is allowed and overrides 10746 // the variable's predetermined data-sharing attributes. 10747 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10748 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10749 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10750 << getOpenMPClauseName(OMPC_private); 10751 reportOriginalDsa(*this, DSAStack, D, DVar); 10752 continue; 10753 } 10754 10755 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10756 // Variably modified types are not supported for tasks. 10757 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10758 isOpenMPTaskingDirective(CurrDir)) { 10759 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10760 << getOpenMPClauseName(OMPC_private) << Type 10761 << getOpenMPDirectiveName(CurrDir); 10762 bool IsDecl = 10763 !VD || 10764 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10765 Diag(D->getLocation(), 10766 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10767 << D; 10768 continue; 10769 } 10770 10771 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10772 // A list item cannot appear in both a map clause and a data-sharing 10773 // attribute clause on the same construct 10774 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10775 OpenMPClauseKind ConflictKind; 10776 if (DSAStack->checkMappableExprComponentListsForDecl( 10777 VD, /*CurrentRegionOnly=*/true, 10778 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10779 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10780 ConflictKind = WhereFoundClauseKind; 10781 return true; 10782 })) { 10783 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10784 << getOpenMPClauseName(OMPC_private) 10785 << getOpenMPClauseName(ConflictKind) 10786 << getOpenMPDirectiveName(CurrDir); 10787 reportOriginalDsa(*this, DSAStack, D, DVar); 10788 continue; 10789 } 10790 } 10791 10792 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10793 // A variable of class type (or array thereof) that appears in a private 10794 // clause requires an accessible, unambiguous default constructor for the 10795 // class type. 10796 // Generate helper private variable and initialize it with the default 10797 // value. The address of the original variable is replaced by the address of 10798 // the new private variable in CodeGen. This new variable is not added to 10799 // IdResolver, so the code in the OpenMP region uses original variable for 10800 // proper diagnostics. 10801 Type = Type.getUnqualifiedType(); 10802 VarDecl *VDPrivate = 10803 buildVarDecl(*this, ELoc, Type, D->getName(), 10804 D->hasAttrs() ? &D->getAttrs() : nullptr, 10805 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10806 ActOnUninitializedDecl(VDPrivate); 10807 if (VDPrivate->isInvalidDecl()) 10808 continue; 10809 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10810 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10811 10812 DeclRefExpr *Ref = nullptr; 10813 if (!VD && !CurContext->isDependentContext()) 10814 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10815 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10816 Vars.push_back((VD || CurContext->isDependentContext()) 10817 ? RefExpr->IgnoreParens() 10818 : Ref); 10819 PrivateCopies.push_back(VDPrivateRefExpr); 10820 } 10821 10822 if (Vars.empty()) 10823 return nullptr; 10824 10825 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10826 PrivateCopies); 10827 } 10828 10829 namespace { 10830 class DiagsUninitializedSeveretyRAII { 10831 private: 10832 DiagnosticsEngine &Diags; 10833 SourceLocation SavedLoc; 10834 bool IsIgnored = false; 10835 10836 public: 10837 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10838 bool IsIgnored) 10839 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10840 if (!IsIgnored) { 10841 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10842 /*Map*/ diag::Severity::Ignored, Loc); 10843 } 10844 } 10845 ~DiagsUninitializedSeveretyRAII() { 10846 if (!IsIgnored) 10847 Diags.popMappings(SavedLoc); 10848 } 10849 }; 10850 } 10851 10852 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10853 SourceLocation StartLoc, 10854 SourceLocation LParenLoc, 10855 SourceLocation EndLoc) { 10856 SmallVector<Expr *, 8> Vars; 10857 SmallVector<Expr *, 8> PrivateCopies; 10858 SmallVector<Expr *, 8> Inits; 10859 SmallVector<Decl *, 4> ExprCaptures; 10860 bool IsImplicitClause = 10861 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10862 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10863 10864 for (Expr *RefExpr : VarList) { 10865 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10866 SourceLocation ELoc; 10867 SourceRange ERange; 10868 Expr *SimpleRefExpr = RefExpr; 10869 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10870 if (Res.second) { 10871 // It will be analyzed later. 10872 Vars.push_back(RefExpr); 10873 PrivateCopies.push_back(nullptr); 10874 Inits.push_back(nullptr); 10875 } 10876 ValueDecl *D = Res.first; 10877 if (!D) 10878 continue; 10879 10880 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10881 QualType Type = D->getType(); 10882 auto *VD = dyn_cast<VarDecl>(D); 10883 10884 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10885 // A variable that appears in a private clause must not have an incomplete 10886 // type or a reference type. 10887 if (RequireCompleteType(ELoc, Type, 10888 diag::err_omp_firstprivate_incomplete_type)) 10889 continue; 10890 Type = Type.getNonReferenceType(); 10891 10892 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10893 // A variable of class type (or array thereof) that appears in a private 10894 // clause requires an accessible, unambiguous copy constructor for the 10895 // class type. 10896 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10897 10898 // If an implicit firstprivate variable found it was checked already. 10899 DSAStackTy::DSAVarData TopDVar; 10900 if (!IsImplicitClause) { 10901 DSAStackTy::DSAVarData DVar = 10902 DSAStack->getTopDSA(D, /*FromParent=*/false); 10903 TopDVar = DVar; 10904 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10905 bool IsConstant = ElemType.isConstant(Context); 10906 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10907 // A list item that specifies a given variable may not appear in more 10908 // than one clause on the same directive, except that a variable may be 10909 // specified in both firstprivate and lastprivate clauses. 10910 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10911 // A list item may appear in a firstprivate or lastprivate clause but not 10912 // both. 10913 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10914 (isOpenMPDistributeDirective(CurrDir) || 10915 DVar.CKind != OMPC_lastprivate) && 10916 DVar.RefExpr) { 10917 Diag(ELoc, diag::err_omp_wrong_dsa) 10918 << getOpenMPClauseName(DVar.CKind) 10919 << getOpenMPClauseName(OMPC_firstprivate); 10920 reportOriginalDsa(*this, DSAStack, D, DVar); 10921 continue; 10922 } 10923 10924 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10925 // in a Construct] 10926 // Variables with the predetermined data-sharing attributes may not be 10927 // listed in data-sharing attributes clauses, except for the cases 10928 // listed below. For these exceptions only, listing a predetermined 10929 // variable in a data-sharing attribute clause is allowed and overrides 10930 // the variable's predetermined data-sharing attributes. 10931 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10932 // in a Construct, C/C++, p.2] 10933 // Variables with const-qualified type having no mutable member may be 10934 // listed in a firstprivate clause, even if they are static data members. 10935 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 10936 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 10937 Diag(ELoc, diag::err_omp_wrong_dsa) 10938 << getOpenMPClauseName(DVar.CKind) 10939 << getOpenMPClauseName(OMPC_firstprivate); 10940 reportOriginalDsa(*this, DSAStack, D, DVar); 10941 continue; 10942 } 10943 10944 // OpenMP [2.9.3.4, Restrictions, p.2] 10945 // A list item that is private within a parallel region must not appear 10946 // in a firstprivate clause on a worksharing construct if any of the 10947 // worksharing regions arising from the worksharing construct ever bind 10948 // to any of the parallel regions arising from the parallel construct. 10949 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10950 // A list item that is private within a teams region must not appear in a 10951 // firstprivate clause on a distribute construct if any of the distribute 10952 // regions arising from the distribute construct ever bind to any of the 10953 // teams regions arising from the teams construct. 10954 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10955 // A list item that appears in a reduction clause of a teams construct 10956 // must not appear in a firstprivate clause on a distribute construct if 10957 // any of the distribute regions arising from the distribute construct 10958 // ever bind to any of the teams regions arising from the teams construct. 10959 if ((isOpenMPWorksharingDirective(CurrDir) || 10960 isOpenMPDistributeDirective(CurrDir)) && 10961 !isOpenMPParallelDirective(CurrDir) && 10962 !isOpenMPTeamsDirective(CurrDir)) { 10963 DVar = DSAStack->getImplicitDSA(D, true); 10964 if (DVar.CKind != OMPC_shared && 10965 (isOpenMPParallelDirective(DVar.DKind) || 10966 isOpenMPTeamsDirective(DVar.DKind) || 10967 DVar.DKind == OMPD_unknown)) { 10968 Diag(ELoc, diag::err_omp_required_access) 10969 << getOpenMPClauseName(OMPC_firstprivate) 10970 << getOpenMPClauseName(OMPC_shared); 10971 reportOriginalDsa(*this, DSAStack, D, DVar); 10972 continue; 10973 } 10974 } 10975 // OpenMP [2.9.3.4, Restrictions, p.3] 10976 // A list item that appears in a reduction clause of a parallel construct 10977 // must not appear in a firstprivate clause on a worksharing or task 10978 // construct if any of the worksharing or task regions arising from the 10979 // worksharing or task construct ever bind to any of the parallel regions 10980 // arising from the parallel construct. 10981 // OpenMP [2.9.3.4, Restrictions, p.4] 10982 // A list item that appears in a reduction clause in worksharing 10983 // construct must not appear in a firstprivate clause in a task construct 10984 // encountered during execution of any of the worksharing regions arising 10985 // from the worksharing construct. 10986 if (isOpenMPTaskingDirective(CurrDir)) { 10987 DVar = DSAStack->hasInnermostDSA( 10988 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 10989 [](OpenMPDirectiveKind K) { 10990 return isOpenMPParallelDirective(K) || 10991 isOpenMPWorksharingDirective(K) || 10992 isOpenMPTeamsDirective(K); 10993 }, 10994 /*FromParent=*/true); 10995 if (DVar.CKind == OMPC_reduction && 10996 (isOpenMPParallelDirective(DVar.DKind) || 10997 isOpenMPWorksharingDirective(DVar.DKind) || 10998 isOpenMPTeamsDirective(DVar.DKind))) { 10999 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11000 << getOpenMPDirectiveName(DVar.DKind); 11001 reportOriginalDsa(*this, DSAStack, D, DVar); 11002 continue; 11003 } 11004 } 11005 11006 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11007 // A list item cannot appear in both a map clause and a data-sharing 11008 // attribute clause on the same construct 11009 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11010 OpenMPClauseKind ConflictKind; 11011 if (DSAStack->checkMappableExprComponentListsForDecl( 11012 VD, /*CurrentRegionOnly=*/true, 11013 [&ConflictKind]( 11014 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11015 OpenMPClauseKind WhereFoundClauseKind) { 11016 ConflictKind = WhereFoundClauseKind; 11017 return true; 11018 })) { 11019 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11020 << getOpenMPClauseName(OMPC_firstprivate) 11021 << getOpenMPClauseName(ConflictKind) 11022 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11023 reportOriginalDsa(*this, DSAStack, D, DVar); 11024 continue; 11025 } 11026 } 11027 } 11028 11029 // Variably modified types are not supported for tasks. 11030 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11031 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11032 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11033 << getOpenMPClauseName(OMPC_firstprivate) << Type 11034 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11035 bool IsDecl = 11036 !VD || 11037 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11038 Diag(D->getLocation(), 11039 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11040 << D; 11041 continue; 11042 } 11043 11044 Type = Type.getUnqualifiedType(); 11045 VarDecl *VDPrivate = 11046 buildVarDecl(*this, ELoc, Type, D->getName(), 11047 D->hasAttrs() ? &D->getAttrs() : nullptr, 11048 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11049 // Generate helper private variable and initialize it with the value of the 11050 // original variable. The address of the original variable is replaced by 11051 // the address of the new private variable in the CodeGen. This new variable 11052 // is not added to IdResolver, so the code in the OpenMP region uses 11053 // original variable for proper diagnostics and variable capturing. 11054 Expr *VDInitRefExpr = nullptr; 11055 // For arrays generate initializer for single element and replace it by the 11056 // original array element in CodeGen. 11057 if (Type->isArrayType()) { 11058 VarDecl *VDInit = 11059 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11060 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11061 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11062 ElemType = ElemType.getUnqualifiedType(); 11063 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11064 ".firstprivate.temp"); 11065 InitializedEntity Entity = 11066 InitializedEntity::InitializeVariable(VDInitTemp); 11067 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11068 11069 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11070 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11071 if (Result.isInvalid()) 11072 VDPrivate->setInvalidDecl(); 11073 else 11074 VDPrivate->setInit(Result.getAs<Expr>()); 11075 // Remove temp variable declaration. 11076 Context.Deallocate(VDInitTemp); 11077 } else { 11078 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11079 ".firstprivate.temp"); 11080 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11081 RefExpr->getExprLoc()); 11082 AddInitializerToDecl(VDPrivate, 11083 DefaultLvalueConversion(VDInitRefExpr).get(), 11084 /*DirectInit=*/false); 11085 } 11086 if (VDPrivate->isInvalidDecl()) { 11087 if (IsImplicitClause) { 11088 Diag(RefExpr->getExprLoc(), 11089 diag::note_omp_task_predetermined_firstprivate_here); 11090 } 11091 continue; 11092 } 11093 CurContext->addDecl(VDPrivate); 11094 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11095 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11096 RefExpr->getExprLoc()); 11097 DeclRefExpr *Ref = nullptr; 11098 if (!VD && !CurContext->isDependentContext()) { 11099 if (TopDVar.CKind == OMPC_lastprivate) { 11100 Ref = TopDVar.PrivateCopy; 11101 } else { 11102 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11103 if (!isOpenMPCapturedDecl(D)) 11104 ExprCaptures.push_back(Ref->getDecl()); 11105 } 11106 } 11107 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11108 Vars.push_back((VD || CurContext->isDependentContext()) 11109 ? RefExpr->IgnoreParens() 11110 : Ref); 11111 PrivateCopies.push_back(VDPrivateRefExpr); 11112 Inits.push_back(VDInitRefExpr); 11113 } 11114 11115 if (Vars.empty()) 11116 return nullptr; 11117 11118 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11119 Vars, PrivateCopies, Inits, 11120 buildPreInits(Context, ExprCaptures)); 11121 } 11122 11123 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11124 SourceLocation StartLoc, 11125 SourceLocation LParenLoc, 11126 SourceLocation EndLoc) { 11127 SmallVector<Expr *, 8> Vars; 11128 SmallVector<Expr *, 8> SrcExprs; 11129 SmallVector<Expr *, 8> DstExprs; 11130 SmallVector<Expr *, 8> AssignmentOps; 11131 SmallVector<Decl *, 4> ExprCaptures; 11132 SmallVector<Expr *, 4> ExprPostUpdates; 11133 for (Expr *RefExpr : VarList) { 11134 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11135 SourceLocation ELoc; 11136 SourceRange ERange; 11137 Expr *SimpleRefExpr = RefExpr; 11138 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11139 if (Res.second) { 11140 // It will be analyzed later. 11141 Vars.push_back(RefExpr); 11142 SrcExprs.push_back(nullptr); 11143 DstExprs.push_back(nullptr); 11144 AssignmentOps.push_back(nullptr); 11145 } 11146 ValueDecl *D = Res.first; 11147 if (!D) 11148 continue; 11149 11150 QualType Type = D->getType(); 11151 auto *VD = dyn_cast<VarDecl>(D); 11152 11153 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11154 // A variable that appears in a lastprivate clause must not have an 11155 // incomplete type or a reference type. 11156 if (RequireCompleteType(ELoc, Type, 11157 diag::err_omp_lastprivate_incomplete_type)) 11158 continue; 11159 Type = Type.getNonReferenceType(); 11160 11161 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11162 // A variable that is privatized must not have a const-qualified type 11163 // unless it is of class type with a mutable member. This restriction does 11164 // not apply to the firstprivate clause. 11165 // 11166 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11167 // A variable that appears in a lastprivate clause must not have a 11168 // const-qualified type unless it is of class type with a mutable member. 11169 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11170 continue; 11171 11172 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11173 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11174 // in a Construct] 11175 // Variables with the predetermined data-sharing attributes may not be 11176 // listed in data-sharing attributes clauses, except for the cases 11177 // listed below. 11178 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11179 // A list item may appear in a firstprivate or lastprivate clause but not 11180 // both. 11181 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11182 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11183 (isOpenMPDistributeDirective(CurrDir) || 11184 DVar.CKind != OMPC_firstprivate) && 11185 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11186 Diag(ELoc, diag::err_omp_wrong_dsa) 11187 << getOpenMPClauseName(DVar.CKind) 11188 << getOpenMPClauseName(OMPC_lastprivate); 11189 reportOriginalDsa(*this, DSAStack, D, DVar); 11190 continue; 11191 } 11192 11193 // OpenMP [2.14.3.5, Restrictions, p.2] 11194 // A list item that is private within a parallel region, or that appears in 11195 // the reduction clause of a parallel construct, must not appear in a 11196 // lastprivate clause on a worksharing construct if any of the corresponding 11197 // worksharing regions ever binds to any of the corresponding parallel 11198 // regions. 11199 DSAStackTy::DSAVarData TopDVar = DVar; 11200 if (isOpenMPWorksharingDirective(CurrDir) && 11201 !isOpenMPParallelDirective(CurrDir) && 11202 !isOpenMPTeamsDirective(CurrDir)) { 11203 DVar = DSAStack->getImplicitDSA(D, true); 11204 if (DVar.CKind != OMPC_shared) { 11205 Diag(ELoc, diag::err_omp_required_access) 11206 << getOpenMPClauseName(OMPC_lastprivate) 11207 << getOpenMPClauseName(OMPC_shared); 11208 reportOriginalDsa(*this, DSAStack, D, DVar); 11209 continue; 11210 } 11211 } 11212 11213 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11214 // A variable of class type (or array thereof) that appears in a 11215 // lastprivate clause requires an accessible, unambiguous default 11216 // constructor for the class type, unless the list item is also specified 11217 // in a firstprivate clause. 11218 // A variable of class type (or array thereof) that appears in a 11219 // lastprivate clause requires an accessible, unambiguous copy assignment 11220 // operator for the class type. 11221 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11222 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11223 Type.getUnqualifiedType(), ".lastprivate.src", 11224 D->hasAttrs() ? &D->getAttrs() : nullptr); 11225 DeclRefExpr *PseudoSrcExpr = 11226 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11227 VarDecl *DstVD = 11228 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11229 D->hasAttrs() ? &D->getAttrs() : nullptr); 11230 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11231 // For arrays generate assignment operation for single element and replace 11232 // it by the original array element in CodeGen. 11233 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11234 PseudoDstExpr, PseudoSrcExpr); 11235 if (AssignmentOp.isInvalid()) 11236 continue; 11237 AssignmentOp = 11238 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11239 if (AssignmentOp.isInvalid()) 11240 continue; 11241 11242 DeclRefExpr *Ref = nullptr; 11243 if (!VD && !CurContext->isDependentContext()) { 11244 if (TopDVar.CKind == OMPC_firstprivate) { 11245 Ref = TopDVar.PrivateCopy; 11246 } else { 11247 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11248 if (!isOpenMPCapturedDecl(D)) 11249 ExprCaptures.push_back(Ref->getDecl()); 11250 } 11251 if (TopDVar.CKind == OMPC_firstprivate || 11252 (!isOpenMPCapturedDecl(D) && 11253 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11254 ExprResult RefRes = DefaultLvalueConversion(Ref); 11255 if (!RefRes.isUsable()) 11256 continue; 11257 ExprResult PostUpdateRes = 11258 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11259 RefRes.get()); 11260 if (!PostUpdateRes.isUsable()) 11261 continue; 11262 ExprPostUpdates.push_back( 11263 IgnoredValueConversions(PostUpdateRes.get()).get()); 11264 } 11265 } 11266 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11267 Vars.push_back((VD || CurContext->isDependentContext()) 11268 ? RefExpr->IgnoreParens() 11269 : Ref); 11270 SrcExprs.push_back(PseudoSrcExpr); 11271 DstExprs.push_back(PseudoDstExpr); 11272 AssignmentOps.push_back(AssignmentOp.get()); 11273 } 11274 11275 if (Vars.empty()) 11276 return nullptr; 11277 11278 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11279 Vars, SrcExprs, DstExprs, AssignmentOps, 11280 buildPreInits(Context, ExprCaptures), 11281 buildPostUpdate(*this, ExprPostUpdates)); 11282 } 11283 11284 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11285 SourceLocation StartLoc, 11286 SourceLocation LParenLoc, 11287 SourceLocation EndLoc) { 11288 SmallVector<Expr *, 8> Vars; 11289 for (Expr *RefExpr : VarList) { 11290 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11291 SourceLocation ELoc; 11292 SourceRange ERange; 11293 Expr *SimpleRefExpr = RefExpr; 11294 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11295 if (Res.second) { 11296 // It will be analyzed later. 11297 Vars.push_back(RefExpr); 11298 } 11299 ValueDecl *D = Res.first; 11300 if (!D) 11301 continue; 11302 11303 auto *VD = dyn_cast<VarDecl>(D); 11304 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11305 // in a Construct] 11306 // Variables with the predetermined data-sharing attributes may not be 11307 // listed in data-sharing attributes clauses, except for the cases 11308 // listed below. For these exceptions only, listing a predetermined 11309 // variable in a data-sharing attribute clause is allowed and overrides 11310 // the variable's predetermined data-sharing attributes. 11311 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11312 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11313 DVar.RefExpr) { 11314 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11315 << getOpenMPClauseName(OMPC_shared); 11316 reportOriginalDsa(*this, DSAStack, D, DVar); 11317 continue; 11318 } 11319 11320 DeclRefExpr *Ref = nullptr; 11321 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11322 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11323 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11324 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11325 ? RefExpr->IgnoreParens() 11326 : Ref); 11327 } 11328 11329 if (Vars.empty()) 11330 return nullptr; 11331 11332 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11333 } 11334 11335 namespace { 11336 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11337 DSAStackTy *Stack; 11338 11339 public: 11340 bool VisitDeclRefExpr(DeclRefExpr *E) { 11341 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11342 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11343 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11344 return false; 11345 if (DVar.CKind != OMPC_unknown) 11346 return true; 11347 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11348 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11349 /*FromParent=*/true); 11350 return DVarPrivate.CKind != OMPC_unknown; 11351 } 11352 return false; 11353 } 11354 bool VisitStmt(Stmt *S) { 11355 for (Stmt *Child : S->children()) { 11356 if (Child && Visit(Child)) 11357 return true; 11358 } 11359 return false; 11360 } 11361 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11362 }; 11363 } // namespace 11364 11365 namespace { 11366 // Transform MemberExpression for specified FieldDecl of current class to 11367 // DeclRefExpr to specified OMPCapturedExprDecl. 11368 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11369 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11370 ValueDecl *Field = nullptr; 11371 DeclRefExpr *CapturedExpr = nullptr; 11372 11373 public: 11374 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11375 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11376 11377 ExprResult TransformMemberExpr(MemberExpr *E) { 11378 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11379 E->getMemberDecl() == Field) { 11380 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11381 return CapturedExpr; 11382 } 11383 return BaseTransform::TransformMemberExpr(E); 11384 } 11385 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11386 }; 11387 } // namespace 11388 11389 template <typename T, typename U> 11390 static T filterLookupForUDReductionAndMapper( 11391 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11392 for (U &Set : Lookups) { 11393 for (auto *D : Set) { 11394 if (T Res = Gen(cast<ValueDecl>(D))) 11395 return Res; 11396 } 11397 } 11398 return T(); 11399 } 11400 11401 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11402 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11403 11404 for (auto RD : D->redecls()) { 11405 // Don't bother with extra checks if we already know this one isn't visible. 11406 if (RD == D) 11407 continue; 11408 11409 auto ND = cast<NamedDecl>(RD); 11410 if (LookupResult::isVisible(SemaRef, ND)) 11411 return ND; 11412 } 11413 11414 return nullptr; 11415 } 11416 11417 static void 11418 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11419 SourceLocation Loc, QualType Ty, 11420 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11421 // Find all of the associated namespaces and classes based on the 11422 // arguments we have. 11423 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11424 Sema::AssociatedClassSet AssociatedClasses; 11425 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11426 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11427 AssociatedClasses); 11428 11429 // C++ [basic.lookup.argdep]p3: 11430 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11431 // and let Y be the lookup set produced by argument dependent 11432 // lookup (defined as follows). If X contains [...] then Y is 11433 // empty. Otherwise Y is the set of declarations found in the 11434 // namespaces associated with the argument types as described 11435 // below. The set of declarations found by the lookup of the name 11436 // is the union of X and Y. 11437 // 11438 // Here, we compute Y and add its members to the overloaded 11439 // candidate set. 11440 for (auto *NS : AssociatedNamespaces) { 11441 // When considering an associated namespace, the lookup is the 11442 // same as the lookup performed when the associated namespace is 11443 // used as a qualifier (3.4.3.2) except that: 11444 // 11445 // -- Any using-directives in the associated namespace are 11446 // ignored. 11447 // 11448 // -- Any namespace-scope friend functions declared in 11449 // associated classes are visible within their respective 11450 // namespaces even if they are not visible during an ordinary 11451 // lookup (11.4). 11452 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11453 for (auto *D : R) { 11454 auto *Underlying = D; 11455 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11456 Underlying = USD->getTargetDecl(); 11457 11458 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11459 !isa<OMPDeclareMapperDecl>(Underlying)) 11460 continue; 11461 11462 if (!SemaRef.isVisible(D)) { 11463 D = findAcceptableDecl(SemaRef, D); 11464 if (!D) 11465 continue; 11466 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11467 Underlying = USD->getTargetDecl(); 11468 } 11469 Lookups.emplace_back(); 11470 Lookups.back().addDecl(Underlying); 11471 } 11472 } 11473 } 11474 11475 static ExprResult 11476 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11477 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11478 const DeclarationNameInfo &ReductionId, QualType Ty, 11479 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11480 if (ReductionIdScopeSpec.isInvalid()) 11481 return ExprError(); 11482 SmallVector<UnresolvedSet<8>, 4> Lookups; 11483 if (S) { 11484 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11485 Lookup.suppressDiagnostics(); 11486 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11487 NamedDecl *D = Lookup.getRepresentativeDecl(); 11488 do { 11489 S = S->getParent(); 11490 } while (S && !S->isDeclScope(D)); 11491 if (S) 11492 S = S->getParent(); 11493 Lookups.emplace_back(); 11494 Lookups.back().append(Lookup.begin(), Lookup.end()); 11495 Lookup.clear(); 11496 } 11497 } else if (auto *ULE = 11498 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11499 Lookups.push_back(UnresolvedSet<8>()); 11500 Decl *PrevD = nullptr; 11501 for (NamedDecl *D : ULE->decls()) { 11502 if (D == PrevD) 11503 Lookups.push_back(UnresolvedSet<8>()); 11504 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11505 Lookups.back().addDecl(DRD); 11506 PrevD = D; 11507 } 11508 } 11509 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11510 Ty->isInstantiationDependentType() || 11511 Ty->containsUnexpandedParameterPack() || 11512 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11513 return !D->isInvalidDecl() && 11514 (D->getType()->isDependentType() || 11515 D->getType()->isInstantiationDependentType() || 11516 D->getType()->containsUnexpandedParameterPack()); 11517 })) { 11518 UnresolvedSet<8> ResSet; 11519 for (const UnresolvedSet<8> &Set : Lookups) { 11520 if (Set.empty()) 11521 continue; 11522 ResSet.append(Set.begin(), Set.end()); 11523 // The last item marks the end of all declarations at the specified scope. 11524 ResSet.addDecl(Set[Set.size() - 1]); 11525 } 11526 return UnresolvedLookupExpr::Create( 11527 SemaRef.Context, /*NamingClass=*/nullptr, 11528 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11529 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11530 } 11531 // Lookup inside the classes. 11532 // C++ [over.match.oper]p3: 11533 // For a unary operator @ with an operand of a type whose 11534 // cv-unqualified version is T1, and for a binary operator @ with 11535 // a left operand of a type whose cv-unqualified version is T1 and 11536 // a right operand of a type whose cv-unqualified version is T2, 11537 // three sets of candidate functions, designated member 11538 // candidates, non-member candidates and built-in candidates, are 11539 // constructed as follows: 11540 // -- If T1 is a complete class type or a class currently being 11541 // defined, the set of member candidates is the result of the 11542 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11543 // the set of member candidates is empty. 11544 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11545 Lookup.suppressDiagnostics(); 11546 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11547 // Complete the type if it can be completed. 11548 // If the type is neither complete nor being defined, bail out now. 11549 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11550 TyRec->getDecl()->getDefinition()) { 11551 Lookup.clear(); 11552 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11553 if (Lookup.empty()) { 11554 Lookups.emplace_back(); 11555 Lookups.back().append(Lookup.begin(), Lookup.end()); 11556 } 11557 } 11558 } 11559 // Perform ADL. 11560 if (SemaRef.getLangOpts().CPlusPlus) 11561 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11562 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11563 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11564 if (!D->isInvalidDecl() && 11565 SemaRef.Context.hasSameType(D->getType(), Ty)) 11566 return D; 11567 return nullptr; 11568 })) 11569 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11570 VK_LValue, Loc); 11571 if (SemaRef.getLangOpts().CPlusPlus) { 11572 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11573 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11574 if (!D->isInvalidDecl() && 11575 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11576 !Ty.isMoreQualifiedThan(D->getType())) 11577 return D; 11578 return nullptr; 11579 })) { 11580 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11581 /*DetectVirtual=*/false); 11582 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11583 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11584 VD->getType().getUnqualifiedType()))) { 11585 if (SemaRef.CheckBaseClassAccess( 11586 Loc, VD->getType(), Ty, Paths.front(), 11587 /*DiagID=*/0) != Sema::AR_inaccessible) { 11588 SemaRef.BuildBasePathArray(Paths, BasePath); 11589 return SemaRef.BuildDeclRefExpr( 11590 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11591 } 11592 } 11593 } 11594 } 11595 } 11596 if (ReductionIdScopeSpec.isSet()) { 11597 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11598 return ExprError(); 11599 } 11600 return ExprEmpty(); 11601 } 11602 11603 namespace { 11604 /// Data for the reduction-based clauses. 11605 struct ReductionData { 11606 /// List of original reduction items. 11607 SmallVector<Expr *, 8> Vars; 11608 /// List of private copies of the reduction items. 11609 SmallVector<Expr *, 8> Privates; 11610 /// LHS expressions for the reduction_op expressions. 11611 SmallVector<Expr *, 8> LHSs; 11612 /// RHS expressions for the reduction_op expressions. 11613 SmallVector<Expr *, 8> RHSs; 11614 /// Reduction operation expression. 11615 SmallVector<Expr *, 8> ReductionOps; 11616 /// Taskgroup descriptors for the corresponding reduction items in 11617 /// in_reduction clauses. 11618 SmallVector<Expr *, 8> TaskgroupDescriptors; 11619 /// List of captures for clause. 11620 SmallVector<Decl *, 4> ExprCaptures; 11621 /// List of postupdate expressions. 11622 SmallVector<Expr *, 4> ExprPostUpdates; 11623 ReductionData() = delete; 11624 /// Reserves required memory for the reduction data. 11625 ReductionData(unsigned Size) { 11626 Vars.reserve(Size); 11627 Privates.reserve(Size); 11628 LHSs.reserve(Size); 11629 RHSs.reserve(Size); 11630 ReductionOps.reserve(Size); 11631 TaskgroupDescriptors.reserve(Size); 11632 ExprCaptures.reserve(Size); 11633 ExprPostUpdates.reserve(Size); 11634 } 11635 /// Stores reduction item and reduction operation only (required for dependent 11636 /// reduction item). 11637 void push(Expr *Item, Expr *ReductionOp) { 11638 Vars.emplace_back(Item); 11639 Privates.emplace_back(nullptr); 11640 LHSs.emplace_back(nullptr); 11641 RHSs.emplace_back(nullptr); 11642 ReductionOps.emplace_back(ReductionOp); 11643 TaskgroupDescriptors.emplace_back(nullptr); 11644 } 11645 /// Stores reduction data. 11646 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11647 Expr *TaskgroupDescriptor) { 11648 Vars.emplace_back(Item); 11649 Privates.emplace_back(Private); 11650 LHSs.emplace_back(LHS); 11651 RHSs.emplace_back(RHS); 11652 ReductionOps.emplace_back(ReductionOp); 11653 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11654 } 11655 }; 11656 } // namespace 11657 11658 static bool checkOMPArraySectionConstantForReduction( 11659 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11660 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11661 const Expr *Length = OASE->getLength(); 11662 if (Length == nullptr) { 11663 // For array sections of the form [1:] or [:], we would need to analyze 11664 // the lower bound... 11665 if (OASE->getColonLoc().isValid()) 11666 return false; 11667 11668 // This is an array subscript which has implicit length 1! 11669 SingleElement = true; 11670 ArraySizes.push_back(llvm::APSInt::get(1)); 11671 } else { 11672 Expr::EvalResult Result; 11673 if (!Length->EvaluateAsInt(Result, Context)) 11674 return false; 11675 11676 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11677 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11678 ArraySizes.push_back(ConstantLengthValue); 11679 } 11680 11681 // Get the base of this array section and walk up from there. 11682 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11683 11684 // We require length = 1 for all array sections except the right-most to 11685 // guarantee that the memory region is contiguous and has no holes in it. 11686 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11687 Length = TempOASE->getLength(); 11688 if (Length == nullptr) { 11689 // For array sections of the form [1:] or [:], we would need to analyze 11690 // the lower bound... 11691 if (OASE->getColonLoc().isValid()) 11692 return false; 11693 11694 // This is an array subscript which has implicit length 1! 11695 ArraySizes.push_back(llvm::APSInt::get(1)); 11696 } else { 11697 Expr::EvalResult Result; 11698 if (!Length->EvaluateAsInt(Result, Context)) 11699 return false; 11700 11701 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11702 if (ConstantLengthValue.getSExtValue() != 1) 11703 return false; 11704 11705 ArraySizes.push_back(ConstantLengthValue); 11706 } 11707 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11708 } 11709 11710 // If we have a single element, we don't need to add the implicit lengths. 11711 if (!SingleElement) { 11712 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11713 // Has implicit length 1! 11714 ArraySizes.push_back(llvm::APSInt::get(1)); 11715 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11716 } 11717 } 11718 11719 // This array section can be privatized as a single value or as a constant 11720 // sized array. 11721 return true; 11722 } 11723 11724 static bool actOnOMPReductionKindClause( 11725 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11726 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11727 SourceLocation ColonLoc, SourceLocation EndLoc, 11728 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11729 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11730 DeclarationName DN = ReductionId.getName(); 11731 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11732 BinaryOperatorKind BOK = BO_Comma; 11733 11734 ASTContext &Context = S.Context; 11735 // OpenMP [2.14.3.6, reduction clause] 11736 // C 11737 // reduction-identifier is either an identifier or one of the following 11738 // operators: +, -, *, &, |, ^, && and || 11739 // C++ 11740 // reduction-identifier is either an id-expression or one of the following 11741 // operators: +, -, *, &, |, ^, && and || 11742 switch (OOK) { 11743 case OO_Plus: 11744 case OO_Minus: 11745 BOK = BO_Add; 11746 break; 11747 case OO_Star: 11748 BOK = BO_Mul; 11749 break; 11750 case OO_Amp: 11751 BOK = BO_And; 11752 break; 11753 case OO_Pipe: 11754 BOK = BO_Or; 11755 break; 11756 case OO_Caret: 11757 BOK = BO_Xor; 11758 break; 11759 case OO_AmpAmp: 11760 BOK = BO_LAnd; 11761 break; 11762 case OO_PipePipe: 11763 BOK = BO_LOr; 11764 break; 11765 case OO_New: 11766 case OO_Delete: 11767 case OO_Array_New: 11768 case OO_Array_Delete: 11769 case OO_Slash: 11770 case OO_Percent: 11771 case OO_Tilde: 11772 case OO_Exclaim: 11773 case OO_Equal: 11774 case OO_Less: 11775 case OO_Greater: 11776 case OO_LessEqual: 11777 case OO_GreaterEqual: 11778 case OO_PlusEqual: 11779 case OO_MinusEqual: 11780 case OO_StarEqual: 11781 case OO_SlashEqual: 11782 case OO_PercentEqual: 11783 case OO_CaretEqual: 11784 case OO_AmpEqual: 11785 case OO_PipeEqual: 11786 case OO_LessLess: 11787 case OO_GreaterGreater: 11788 case OO_LessLessEqual: 11789 case OO_GreaterGreaterEqual: 11790 case OO_EqualEqual: 11791 case OO_ExclaimEqual: 11792 case OO_Spaceship: 11793 case OO_PlusPlus: 11794 case OO_MinusMinus: 11795 case OO_Comma: 11796 case OO_ArrowStar: 11797 case OO_Arrow: 11798 case OO_Call: 11799 case OO_Subscript: 11800 case OO_Conditional: 11801 case OO_Coawait: 11802 case NUM_OVERLOADED_OPERATORS: 11803 llvm_unreachable("Unexpected reduction identifier"); 11804 case OO_None: 11805 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11806 if (II->isStr("max")) 11807 BOK = BO_GT; 11808 else if (II->isStr("min")) 11809 BOK = BO_LT; 11810 } 11811 break; 11812 } 11813 SourceRange ReductionIdRange; 11814 if (ReductionIdScopeSpec.isValid()) 11815 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11816 else 11817 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11818 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11819 11820 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11821 bool FirstIter = true; 11822 for (Expr *RefExpr : VarList) { 11823 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11824 // OpenMP [2.1, C/C++] 11825 // A list item is a variable or array section, subject to the restrictions 11826 // specified in Section 2.4 on page 42 and in each of the sections 11827 // describing clauses and directives for which a list appears. 11828 // OpenMP [2.14.3.3, Restrictions, p.1] 11829 // A variable that is part of another variable (as an array or 11830 // structure element) cannot appear in a private clause. 11831 if (!FirstIter && IR != ER) 11832 ++IR; 11833 FirstIter = false; 11834 SourceLocation ELoc; 11835 SourceRange ERange; 11836 Expr *SimpleRefExpr = RefExpr; 11837 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11838 /*AllowArraySection=*/true); 11839 if (Res.second) { 11840 // Try to find 'declare reduction' corresponding construct before using 11841 // builtin/overloaded operators. 11842 QualType Type = Context.DependentTy; 11843 CXXCastPath BasePath; 11844 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11845 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11846 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11847 Expr *ReductionOp = nullptr; 11848 if (S.CurContext->isDependentContext() && 11849 (DeclareReductionRef.isUnset() || 11850 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11851 ReductionOp = DeclareReductionRef.get(); 11852 // It will be analyzed later. 11853 RD.push(RefExpr, ReductionOp); 11854 } 11855 ValueDecl *D = Res.first; 11856 if (!D) 11857 continue; 11858 11859 Expr *TaskgroupDescriptor = nullptr; 11860 QualType Type; 11861 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11862 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11863 if (ASE) { 11864 Type = ASE->getType().getNonReferenceType(); 11865 } else if (OASE) { 11866 QualType BaseType = 11867 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11868 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11869 Type = ATy->getElementType(); 11870 else 11871 Type = BaseType->getPointeeType(); 11872 Type = Type.getNonReferenceType(); 11873 } else { 11874 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11875 } 11876 auto *VD = dyn_cast<VarDecl>(D); 11877 11878 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11879 // A variable that appears in a private clause must not have an incomplete 11880 // type or a reference type. 11881 if (S.RequireCompleteType(ELoc, D->getType(), 11882 diag::err_omp_reduction_incomplete_type)) 11883 continue; 11884 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11885 // A list item that appears in a reduction clause must not be 11886 // const-qualified. 11887 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11888 /*AcceptIfMutable*/ false, ASE || OASE)) 11889 continue; 11890 11891 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11892 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11893 // If a list-item is a reference type then it must bind to the same object 11894 // for all threads of the team. 11895 if (!ASE && !OASE) { 11896 if (VD) { 11897 VarDecl *VDDef = VD->getDefinition(); 11898 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11899 DSARefChecker Check(Stack); 11900 if (Check.Visit(VDDef->getInit())) { 11901 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11902 << getOpenMPClauseName(ClauseKind) << ERange; 11903 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11904 continue; 11905 } 11906 } 11907 } 11908 11909 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11910 // in a Construct] 11911 // Variables with the predetermined data-sharing attributes may not be 11912 // listed in data-sharing attributes clauses, except for the cases 11913 // listed below. For these exceptions only, listing a predetermined 11914 // variable in a data-sharing attribute clause is allowed and overrides 11915 // the variable's predetermined data-sharing attributes. 11916 // OpenMP [2.14.3.6, Restrictions, p.3] 11917 // Any number of reduction clauses can be specified on the directive, 11918 // but a list item can appear only once in the reduction clauses for that 11919 // directive. 11920 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11921 if (DVar.CKind == OMPC_reduction) { 11922 S.Diag(ELoc, diag::err_omp_once_referenced) 11923 << getOpenMPClauseName(ClauseKind); 11924 if (DVar.RefExpr) 11925 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 11926 continue; 11927 } 11928 if (DVar.CKind != OMPC_unknown) { 11929 S.Diag(ELoc, diag::err_omp_wrong_dsa) 11930 << getOpenMPClauseName(DVar.CKind) 11931 << getOpenMPClauseName(OMPC_reduction); 11932 reportOriginalDsa(S, Stack, D, DVar); 11933 continue; 11934 } 11935 11936 // OpenMP [2.14.3.6, Restrictions, p.1] 11937 // A list item that appears in a reduction clause of a worksharing 11938 // construct must be shared in the parallel regions to which any of the 11939 // worksharing regions arising from the worksharing construct bind. 11940 if (isOpenMPWorksharingDirective(CurrDir) && 11941 !isOpenMPParallelDirective(CurrDir) && 11942 !isOpenMPTeamsDirective(CurrDir)) { 11943 DVar = Stack->getImplicitDSA(D, true); 11944 if (DVar.CKind != OMPC_shared) { 11945 S.Diag(ELoc, diag::err_omp_required_access) 11946 << getOpenMPClauseName(OMPC_reduction) 11947 << getOpenMPClauseName(OMPC_shared); 11948 reportOriginalDsa(S, Stack, D, DVar); 11949 continue; 11950 } 11951 } 11952 } 11953 11954 // Try to find 'declare reduction' corresponding construct before using 11955 // builtin/overloaded operators. 11956 CXXCastPath BasePath; 11957 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11958 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11959 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11960 if (DeclareReductionRef.isInvalid()) 11961 continue; 11962 if (S.CurContext->isDependentContext() && 11963 (DeclareReductionRef.isUnset() || 11964 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 11965 RD.push(RefExpr, DeclareReductionRef.get()); 11966 continue; 11967 } 11968 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 11969 // Not allowed reduction identifier is found. 11970 S.Diag(ReductionId.getBeginLoc(), 11971 diag::err_omp_unknown_reduction_identifier) 11972 << Type << ReductionIdRange; 11973 continue; 11974 } 11975 11976 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11977 // The type of a list item that appears in a reduction clause must be valid 11978 // for the reduction-identifier. For a max or min reduction in C, the type 11979 // of the list item must be an allowed arithmetic data type: char, int, 11980 // float, double, or _Bool, possibly modified with long, short, signed, or 11981 // unsigned. For a max or min reduction in C++, the type of the list item 11982 // must be an allowed arithmetic data type: char, wchar_t, int, float, 11983 // double, or bool, possibly modified with long, short, signed, or unsigned. 11984 if (DeclareReductionRef.isUnset()) { 11985 if ((BOK == BO_GT || BOK == BO_LT) && 11986 !(Type->isScalarType() || 11987 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 11988 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 11989 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 11990 if (!ASE && !OASE) { 11991 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11992 VarDecl::DeclarationOnly; 11993 S.Diag(D->getLocation(), 11994 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11995 << D; 11996 } 11997 continue; 11998 } 11999 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12000 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12001 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12002 << getOpenMPClauseName(ClauseKind); 12003 if (!ASE && !OASE) { 12004 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12005 VarDecl::DeclarationOnly; 12006 S.Diag(D->getLocation(), 12007 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12008 << D; 12009 } 12010 continue; 12011 } 12012 } 12013 12014 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12015 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12016 D->hasAttrs() ? &D->getAttrs() : nullptr); 12017 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12018 D->hasAttrs() ? &D->getAttrs() : nullptr); 12019 QualType PrivateTy = Type; 12020 12021 // Try if we can determine constant lengths for all array sections and avoid 12022 // the VLA. 12023 bool ConstantLengthOASE = false; 12024 if (OASE) { 12025 bool SingleElement; 12026 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12027 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12028 Context, OASE, SingleElement, ArraySizes); 12029 12030 // If we don't have a single element, we must emit a constant array type. 12031 if (ConstantLengthOASE && !SingleElement) { 12032 for (llvm::APSInt &Size : ArraySizes) 12033 PrivateTy = Context.getConstantArrayType( 12034 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12035 } 12036 } 12037 12038 if ((OASE && !ConstantLengthOASE) || 12039 (!OASE && !ASE && 12040 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12041 if (!Context.getTargetInfo().isVLASupported() && 12042 S.shouldDiagnoseTargetSupportFromOpenMP()) { 12043 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12044 S.Diag(ELoc, diag::note_vla_unsupported); 12045 continue; 12046 } 12047 // For arrays/array sections only: 12048 // Create pseudo array type for private copy. The size for this array will 12049 // be generated during codegen. 12050 // For array subscripts or single variables Private Ty is the same as Type 12051 // (type of the variable or single array element). 12052 PrivateTy = Context.getVariableArrayType( 12053 Type, 12054 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12055 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12056 } else if (!ASE && !OASE && 12057 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12058 PrivateTy = D->getType().getNonReferenceType(); 12059 } 12060 // Private copy. 12061 VarDecl *PrivateVD = 12062 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12063 D->hasAttrs() ? &D->getAttrs() : nullptr, 12064 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12065 // Add initializer for private variable. 12066 Expr *Init = nullptr; 12067 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12068 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12069 if (DeclareReductionRef.isUsable()) { 12070 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12071 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12072 if (DRD->getInitializer()) { 12073 Init = DRDRef; 12074 RHSVD->setInit(DRDRef); 12075 RHSVD->setInitStyle(VarDecl::CallInit); 12076 } 12077 } else { 12078 switch (BOK) { 12079 case BO_Add: 12080 case BO_Xor: 12081 case BO_Or: 12082 case BO_LOr: 12083 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12084 if (Type->isScalarType() || Type->isAnyComplexType()) 12085 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12086 break; 12087 case BO_Mul: 12088 case BO_LAnd: 12089 if (Type->isScalarType() || Type->isAnyComplexType()) { 12090 // '*' and '&&' reduction ops - initializer is '1'. 12091 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12092 } 12093 break; 12094 case BO_And: { 12095 // '&' reduction op - initializer is '~0'. 12096 QualType OrigType = Type; 12097 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12098 Type = ComplexTy->getElementType(); 12099 if (Type->isRealFloatingType()) { 12100 llvm::APFloat InitValue = 12101 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12102 /*isIEEE=*/true); 12103 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12104 Type, ELoc); 12105 } else if (Type->isScalarType()) { 12106 uint64_t Size = Context.getTypeSize(Type); 12107 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12108 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12109 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12110 } 12111 if (Init && OrigType->isAnyComplexType()) { 12112 // Init = 0xFFFF + 0xFFFFi; 12113 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12114 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12115 } 12116 Type = OrigType; 12117 break; 12118 } 12119 case BO_LT: 12120 case BO_GT: { 12121 // 'min' reduction op - initializer is 'Largest representable number in 12122 // the reduction list item type'. 12123 // 'max' reduction op - initializer is 'Least representable number in 12124 // the reduction list item type'. 12125 if (Type->isIntegerType() || Type->isPointerType()) { 12126 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12127 uint64_t Size = Context.getTypeSize(Type); 12128 QualType IntTy = 12129 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12130 llvm::APInt InitValue = 12131 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12132 : llvm::APInt::getMinValue(Size) 12133 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12134 : llvm::APInt::getMaxValue(Size); 12135 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12136 if (Type->isPointerType()) { 12137 // Cast to pointer type. 12138 ExprResult CastExpr = S.BuildCStyleCastExpr( 12139 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12140 if (CastExpr.isInvalid()) 12141 continue; 12142 Init = CastExpr.get(); 12143 } 12144 } else if (Type->isRealFloatingType()) { 12145 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12146 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12147 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12148 Type, ELoc); 12149 } 12150 break; 12151 } 12152 case BO_PtrMemD: 12153 case BO_PtrMemI: 12154 case BO_MulAssign: 12155 case BO_Div: 12156 case BO_Rem: 12157 case BO_Sub: 12158 case BO_Shl: 12159 case BO_Shr: 12160 case BO_LE: 12161 case BO_GE: 12162 case BO_EQ: 12163 case BO_NE: 12164 case BO_Cmp: 12165 case BO_AndAssign: 12166 case BO_XorAssign: 12167 case BO_OrAssign: 12168 case BO_Assign: 12169 case BO_AddAssign: 12170 case BO_SubAssign: 12171 case BO_DivAssign: 12172 case BO_RemAssign: 12173 case BO_ShlAssign: 12174 case BO_ShrAssign: 12175 case BO_Comma: 12176 llvm_unreachable("Unexpected reduction operation"); 12177 } 12178 } 12179 if (Init && DeclareReductionRef.isUnset()) 12180 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12181 else if (!Init) 12182 S.ActOnUninitializedDecl(RHSVD); 12183 if (RHSVD->isInvalidDecl()) 12184 continue; 12185 if (!RHSVD->hasInit() && 12186 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12187 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12188 << Type << ReductionIdRange; 12189 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12190 VarDecl::DeclarationOnly; 12191 S.Diag(D->getLocation(), 12192 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12193 << D; 12194 continue; 12195 } 12196 // Store initializer for single element in private copy. Will be used during 12197 // codegen. 12198 PrivateVD->setInit(RHSVD->getInit()); 12199 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12200 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12201 ExprResult ReductionOp; 12202 if (DeclareReductionRef.isUsable()) { 12203 QualType RedTy = DeclareReductionRef.get()->getType(); 12204 QualType PtrRedTy = Context.getPointerType(RedTy); 12205 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12206 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12207 if (!BasePath.empty()) { 12208 LHS = S.DefaultLvalueConversion(LHS.get()); 12209 RHS = S.DefaultLvalueConversion(RHS.get()); 12210 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12211 CK_UncheckedDerivedToBase, LHS.get(), 12212 &BasePath, LHS.get()->getValueKind()); 12213 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12214 CK_UncheckedDerivedToBase, RHS.get(), 12215 &BasePath, RHS.get()->getValueKind()); 12216 } 12217 FunctionProtoType::ExtProtoInfo EPI; 12218 QualType Params[] = {PtrRedTy, PtrRedTy}; 12219 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12220 auto *OVE = new (Context) OpaqueValueExpr( 12221 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12222 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12223 Expr *Args[] = {LHS.get(), RHS.get()}; 12224 ReductionOp = 12225 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12226 } else { 12227 ReductionOp = S.BuildBinOp( 12228 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12229 if (ReductionOp.isUsable()) { 12230 if (BOK != BO_LT && BOK != BO_GT) { 12231 ReductionOp = 12232 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12233 BO_Assign, LHSDRE, ReductionOp.get()); 12234 } else { 12235 auto *ConditionalOp = new (Context) 12236 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12237 Type, VK_LValue, OK_Ordinary); 12238 ReductionOp = 12239 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12240 BO_Assign, LHSDRE, ConditionalOp); 12241 } 12242 if (ReductionOp.isUsable()) 12243 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12244 /*DiscardedValue*/ false); 12245 } 12246 if (!ReductionOp.isUsable()) 12247 continue; 12248 } 12249 12250 // OpenMP [2.15.4.6, Restrictions, p.2] 12251 // A list item that appears in an in_reduction clause of a task construct 12252 // must appear in a task_reduction clause of a construct associated with a 12253 // taskgroup region that includes the participating task in its taskgroup 12254 // set. The construct associated with the innermost region that meets this 12255 // condition must specify the same reduction-identifier as the in_reduction 12256 // clause. 12257 if (ClauseKind == OMPC_in_reduction) { 12258 SourceRange ParentSR; 12259 BinaryOperatorKind ParentBOK; 12260 const Expr *ParentReductionOp; 12261 Expr *ParentBOKTD, *ParentReductionOpTD; 12262 DSAStackTy::DSAVarData ParentBOKDSA = 12263 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12264 ParentBOKTD); 12265 DSAStackTy::DSAVarData ParentReductionOpDSA = 12266 Stack->getTopMostTaskgroupReductionData( 12267 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12268 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12269 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12270 if (!IsParentBOK && !IsParentReductionOp) { 12271 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12272 continue; 12273 } 12274 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12275 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12276 IsParentReductionOp) { 12277 bool EmitError = true; 12278 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12279 llvm::FoldingSetNodeID RedId, ParentRedId; 12280 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12281 DeclareReductionRef.get()->Profile(RedId, Context, 12282 /*Canonical=*/true); 12283 EmitError = RedId != ParentRedId; 12284 } 12285 if (EmitError) { 12286 S.Diag(ReductionId.getBeginLoc(), 12287 diag::err_omp_reduction_identifier_mismatch) 12288 << ReductionIdRange << RefExpr->getSourceRange(); 12289 S.Diag(ParentSR.getBegin(), 12290 diag::note_omp_previous_reduction_identifier) 12291 << ParentSR 12292 << (IsParentBOK ? ParentBOKDSA.RefExpr 12293 : ParentReductionOpDSA.RefExpr) 12294 ->getSourceRange(); 12295 continue; 12296 } 12297 } 12298 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12299 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12300 } 12301 12302 DeclRefExpr *Ref = nullptr; 12303 Expr *VarsExpr = RefExpr->IgnoreParens(); 12304 if (!VD && !S.CurContext->isDependentContext()) { 12305 if (ASE || OASE) { 12306 TransformExprToCaptures RebuildToCapture(S, D); 12307 VarsExpr = 12308 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12309 Ref = RebuildToCapture.getCapturedExpr(); 12310 } else { 12311 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12312 } 12313 if (!S.isOpenMPCapturedDecl(D)) { 12314 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12315 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12316 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12317 if (!RefRes.isUsable()) 12318 continue; 12319 ExprResult PostUpdateRes = 12320 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12321 RefRes.get()); 12322 if (!PostUpdateRes.isUsable()) 12323 continue; 12324 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12325 Stack->getCurrentDirective() == OMPD_taskgroup) { 12326 S.Diag(RefExpr->getExprLoc(), 12327 diag::err_omp_reduction_non_addressable_expression) 12328 << RefExpr->getSourceRange(); 12329 continue; 12330 } 12331 RD.ExprPostUpdates.emplace_back( 12332 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12333 } 12334 } 12335 } 12336 // All reduction items are still marked as reduction (to do not increase 12337 // code base size). 12338 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12339 if (CurrDir == OMPD_taskgroup) { 12340 if (DeclareReductionRef.isUsable()) 12341 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12342 DeclareReductionRef.get()); 12343 else 12344 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12345 } 12346 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12347 TaskgroupDescriptor); 12348 } 12349 return RD.Vars.empty(); 12350 } 12351 12352 OMPClause *Sema::ActOnOpenMPReductionClause( 12353 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12354 SourceLocation ColonLoc, SourceLocation EndLoc, 12355 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12356 ArrayRef<Expr *> UnresolvedReductions) { 12357 ReductionData RD(VarList.size()); 12358 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12359 StartLoc, LParenLoc, ColonLoc, EndLoc, 12360 ReductionIdScopeSpec, ReductionId, 12361 UnresolvedReductions, RD)) 12362 return nullptr; 12363 12364 return OMPReductionClause::Create( 12365 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12366 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12367 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12368 buildPreInits(Context, RD.ExprCaptures), 12369 buildPostUpdate(*this, RD.ExprPostUpdates)); 12370 } 12371 12372 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12373 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12374 SourceLocation ColonLoc, SourceLocation EndLoc, 12375 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12376 ArrayRef<Expr *> UnresolvedReductions) { 12377 ReductionData RD(VarList.size()); 12378 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12379 StartLoc, LParenLoc, ColonLoc, EndLoc, 12380 ReductionIdScopeSpec, ReductionId, 12381 UnresolvedReductions, RD)) 12382 return nullptr; 12383 12384 return OMPTaskReductionClause::Create( 12385 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12386 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12387 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12388 buildPreInits(Context, RD.ExprCaptures), 12389 buildPostUpdate(*this, RD.ExprPostUpdates)); 12390 } 12391 12392 OMPClause *Sema::ActOnOpenMPInReductionClause( 12393 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12394 SourceLocation ColonLoc, SourceLocation EndLoc, 12395 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12396 ArrayRef<Expr *> UnresolvedReductions) { 12397 ReductionData RD(VarList.size()); 12398 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12399 StartLoc, LParenLoc, ColonLoc, EndLoc, 12400 ReductionIdScopeSpec, ReductionId, 12401 UnresolvedReductions, RD)) 12402 return nullptr; 12403 12404 return OMPInReductionClause::Create( 12405 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12406 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12407 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12408 buildPreInits(Context, RD.ExprCaptures), 12409 buildPostUpdate(*this, RD.ExprPostUpdates)); 12410 } 12411 12412 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12413 SourceLocation LinLoc) { 12414 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12415 LinKind == OMPC_LINEAR_unknown) { 12416 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12417 return true; 12418 } 12419 return false; 12420 } 12421 12422 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12423 OpenMPLinearClauseKind LinKind, 12424 QualType Type) { 12425 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12426 // A variable must not have an incomplete type or a reference type. 12427 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12428 return true; 12429 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12430 !Type->isReferenceType()) { 12431 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12432 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12433 return true; 12434 } 12435 Type = Type.getNonReferenceType(); 12436 12437 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12438 // A variable that is privatized must not have a const-qualified type 12439 // unless it is of class type with a mutable member. This restriction does 12440 // not apply to the firstprivate clause. 12441 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12442 return true; 12443 12444 // A list item must be of integral or pointer type. 12445 Type = Type.getUnqualifiedType().getCanonicalType(); 12446 const auto *Ty = Type.getTypePtrOrNull(); 12447 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12448 !Ty->isPointerType())) { 12449 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12450 if (D) { 12451 bool IsDecl = 12452 !VD || 12453 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12454 Diag(D->getLocation(), 12455 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12456 << D; 12457 } 12458 return true; 12459 } 12460 return false; 12461 } 12462 12463 OMPClause *Sema::ActOnOpenMPLinearClause( 12464 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12465 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12466 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12467 SmallVector<Expr *, 8> Vars; 12468 SmallVector<Expr *, 8> Privates; 12469 SmallVector<Expr *, 8> Inits; 12470 SmallVector<Decl *, 4> ExprCaptures; 12471 SmallVector<Expr *, 4> ExprPostUpdates; 12472 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12473 LinKind = OMPC_LINEAR_val; 12474 for (Expr *RefExpr : VarList) { 12475 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12476 SourceLocation ELoc; 12477 SourceRange ERange; 12478 Expr *SimpleRefExpr = RefExpr; 12479 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12480 if (Res.second) { 12481 // It will be analyzed later. 12482 Vars.push_back(RefExpr); 12483 Privates.push_back(nullptr); 12484 Inits.push_back(nullptr); 12485 } 12486 ValueDecl *D = Res.first; 12487 if (!D) 12488 continue; 12489 12490 QualType Type = D->getType(); 12491 auto *VD = dyn_cast<VarDecl>(D); 12492 12493 // OpenMP [2.14.3.7, linear clause] 12494 // A list-item cannot appear in more than one linear clause. 12495 // A list-item that appears in a linear clause cannot appear in any 12496 // other data-sharing attribute clause. 12497 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12498 if (DVar.RefExpr) { 12499 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12500 << getOpenMPClauseName(OMPC_linear); 12501 reportOriginalDsa(*this, DSAStack, D, DVar); 12502 continue; 12503 } 12504 12505 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12506 continue; 12507 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12508 12509 // Build private copy of original var. 12510 VarDecl *Private = 12511 buildVarDecl(*this, ELoc, Type, D->getName(), 12512 D->hasAttrs() ? &D->getAttrs() : nullptr, 12513 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12514 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12515 // Build var to save initial value. 12516 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12517 Expr *InitExpr; 12518 DeclRefExpr *Ref = nullptr; 12519 if (!VD && !CurContext->isDependentContext()) { 12520 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12521 if (!isOpenMPCapturedDecl(D)) { 12522 ExprCaptures.push_back(Ref->getDecl()); 12523 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12524 ExprResult RefRes = DefaultLvalueConversion(Ref); 12525 if (!RefRes.isUsable()) 12526 continue; 12527 ExprResult PostUpdateRes = 12528 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12529 SimpleRefExpr, RefRes.get()); 12530 if (!PostUpdateRes.isUsable()) 12531 continue; 12532 ExprPostUpdates.push_back( 12533 IgnoredValueConversions(PostUpdateRes.get()).get()); 12534 } 12535 } 12536 } 12537 if (LinKind == OMPC_LINEAR_uval) 12538 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12539 else 12540 InitExpr = VD ? SimpleRefExpr : Ref; 12541 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12542 /*DirectInit=*/false); 12543 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12544 12545 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12546 Vars.push_back((VD || CurContext->isDependentContext()) 12547 ? RefExpr->IgnoreParens() 12548 : Ref); 12549 Privates.push_back(PrivateRef); 12550 Inits.push_back(InitRef); 12551 } 12552 12553 if (Vars.empty()) 12554 return nullptr; 12555 12556 Expr *StepExpr = Step; 12557 Expr *CalcStepExpr = nullptr; 12558 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12559 !Step->isInstantiationDependent() && 12560 !Step->containsUnexpandedParameterPack()) { 12561 SourceLocation StepLoc = Step->getBeginLoc(); 12562 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12563 if (Val.isInvalid()) 12564 return nullptr; 12565 StepExpr = Val.get(); 12566 12567 // Build var to save the step value. 12568 VarDecl *SaveVar = 12569 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12570 ExprResult SaveRef = 12571 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12572 ExprResult CalcStep = 12573 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12574 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12575 12576 // Warn about zero linear step (it would be probably better specified as 12577 // making corresponding variables 'const'). 12578 llvm::APSInt Result; 12579 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12580 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12581 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12582 << (Vars.size() > 1); 12583 if (!IsConstant && CalcStep.isUsable()) { 12584 // Calculate the step beforehand instead of doing this on each iteration. 12585 // (This is not used if the number of iterations may be kfold-ed). 12586 CalcStepExpr = CalcStep.get(); 12587 } 12588 } 12589 12590 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12591 ColonLoc, EndLoc, Vars, Privates, Inits, 12592 StepExpr, CalcStepExpr, 12593 buildPreInits(Context, ExprCaptures), 12594 buildPostUpdate(*this, ExprPostUpdates)); 12595 } 12596 12597 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12598 Expr *NumIterations, Sema &SemaRef, 12599 Scope *S, DSAStackTy *Stack) { 12600 // Walk the vars and build update/final expressions for the CodeGen. 12601 SmallVector<Expr *, 8> Updates; 12602 SmallVector<Expr *, 8> Finals; 12603 Expr *Step = Clause.getStep(); 12604 Expr *CalcStep = Clause.getCalcStep(); 12605 // OpenMP [2.14.3.7, linear clause] 12606 // If linear-step is not specified it is assumed to be 1. 12607 if (!Step) 12608 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12609 else if (CalcStep) 12610 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12611 bool HasErrors = false; 12612 auto CurInit = Clause.inits().begin(); 12613 auto CurPrivate = Clause.privates().begin(); 12614 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12615 for (Expr *RefExpr : Clause.varlists()) { 12616 SourceLocation ELoc; 12617 SourceRange ERange; 12618 Expr *SimpleRefExpr = RefExpr; 12619 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12620 ValueDecl *D = Res.first; 12621 if (Res.second || !D) { 12622 Updates.push_back(nullptr); 12623 Finals.push_back(nullptr); 12624 HasErrors = true; 12625 continue; 12626 } 12627 auto &&Info = Stack->isLoopControlVariable(D); 12628 // OpenMP [2.15.11, distribute simd Construct] 12629 // A list item may not appear in a linear clause, unless it is the loop 12630 // iteration variable. 12631 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12632 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12633 SemaRef.Diag(ELoc, 12634 diag::err_omp_linear_distribute_var_non_loop_iteration); 12635 Updates.push_back(nullptr); 12636 Finals.push_back(nullptr); 12637 HasErrors = true; 12638 continue; 12639 } 12640 Expr *InitExpr = *CurInit; 12641 12642 // Build privatized reference to the current linear var. 12643 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12644 Expr *CapturedRef; 12645 if (LinKind == OMPC_LINEAR_uval) 12646 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12647 else 12648 CapturedRef = 12649 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12650 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12651 /*RefersToCapture=*/true); 12652 12653 // Build update: Var = InitExpr + IV * Step 12654 ExprResult Update; 12655 if (!Info.first) 12656 Update = 12657 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12658 InitExpr, IV, Step, /* Subtract */ false); 12659 else 12660 Update = *CurPrivate; 12661 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12662 /*DiscardedValue*/ false); 12663 12664 // Build final: Var = InitExpr + NumIterations * Step 12665 ExprResult Final; 12666 if (!Info.first) 12667 Final = 12668 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12669 InitExpr, NumIterations, Step, /*Subtract=*/false); 12670 else 12671 Final = *CurPrivate; 12672 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12673 /*DiscardedValue*/ false); 12674 12675 if (!Update.isUsable() || !Final.isUsable()) { 12676 Updates.push_back(nullptr); 12677 Finals.push_back(nullptr); 12678 HasErrors = true; 12679 } else { 12680 Updates.push_back(Update.get()); 12681 Finals.push_back(Final.get()); 12682 } 12683 ++CurInit; 12684 ++CurPrivate; 12685 } 12686 Clause.setUpdates(Updates); 12687 Clause.setFinals(Finals); 12688 return HasErrors; 12689 } 12690 12691 OMPClause *Sema::ActOnOpenMPAlignedClause( 12692 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12693 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12694 SmallVector<Expr *, 8> Vars; 12695 for (Expr *RefExpr : VarList) { 12696 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12697 SourceLocation ELoc; 12698 SourceRange ERange; 12699 Expr *SimpleRefExpr = RefExpr; 12700 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12701 if (Res.second) { 12702 // It will be analyzed later. 12703 Vars.push_back(RefExpr); 12704 } 12705 ValueDecl *D = Res.first; 12706 if (!D) 12707 continue; 12708 12709 QualType QType = D->getType(); 12710 auto *VD = dyn_cast<VarDecl>(D); 12711 12712 // OpenMP [2.8.1, simd construct, Restrictions] 12713 // The type of list items appearing in the aligned clause must be 12714 // array, pointer, reference to array, or reference to pointer. 12715 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12716 const Type *Ty = QType.getTypePtrOrNull(); 12717 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12718 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12719 << QType << getLangOpts().CPlusPlus << ERange; 12720 bool IsDecl = 12721 !VD || 12722 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12723 Diag(D->getLocation(), 12724 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12725 << D; 12726 continue; 12727 } 12728 12729 // OpenMP [2.8.1, simd construct, Restrictions] 12730 // A list-item cannot appear in more than one aligned clause. 12731 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12732 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12733 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12734 << getOpenMPClauseName(OMPC_aligned); 12735 continue; 12736 } 12737 12738 DeclRefExpr *Ref = nullptr; 12739 if (!VD && isOpenMPCapturedDecl(D)) 12740 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12741 Vars.push_back(DefaultFunctionArrayConversion( 12742 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12743 .get()); 12744 } 12745 12746 // OpenMP [2.8.1, simd construct, Description] 12747 // The parameter of the aligned clause, alignment, must be a constant 12748 // positive integer expression. 12749 // If no optional parameter is specified, implementation-defined default 12750 // alignments for SIMD instructions on the target platforms are assumed. 12751 if (Alignment != nullptr) { 12752 ExprResult AlignResult = 12753 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12754 if (AlignResult.isInvalid()) 12755 return nullptr; 12756 Alignment = AlignResult.get(); 12757 } 12758 if (Vars.empty()) 12759 return nullptr; 12760 12761 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12762 EndLoc, Vars, Alignment); 12763 } 12764 12765 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12766 SourceLocation StartLoc, 12767 SourceLocation LParenLoc, 12768 SourceLocation EndLoc) { 12769 SmallVector<Expr *, 8> Vars; 12770 SmallVector<Expr *, 8> SrcExprs; 12771 SmallVector<Expr *, 8> DstExprs; 12772 SmallVector<Expr *, 8> AssignmentOps; 12773 for (Expr *RefExpr : VarList) { 12774 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12775 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12776 // It will be analyzed later. 12777 Vars.push_back(RefExpr); 12778 SrcExprs.push_back(nullptr); 12779 DstExprs.push_back(nullptr); 12780 AssignmentOps.push_back(nullptr); 12781 continue; 12782 } 12783 12784 SourceLocation ELoc = RefExpr->getExprLoc(); 12785 // OpenMP [2.1, C/C++] 12786 // A list item is a variable name. 12787 // OpenMP [2.14.4.1, Restrictions, p.1] 12788 // A list item that appears in a copyin clause must be threadprivate. 12789 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12790 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12791 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12792 << 0 << RefExpr->getSourceRange(); 12793 continue; 12794 } 12795 12796 Decl *D = DE->getDecl(); 12797 auto *VD = cast<VarDecl>(D); 12798 12799 QualType Type = VD->getType(); 12800 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12801 // It will be analyzed later. 12802 Vars.push_back(DE); 12803 SrcExprs.push_back(nullptr); 12804 DstExprs.push_back(nullptr); 12805 AssignmentOps.push_back(nullptr); 12806 continue; 12807 } 12808 12809 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12810 // A list item that appears in a copyin clause must be threadprivate. 12811 if (!DSAStack->isThreadPrivate(VD)) { 12812 Diag(ELoc, diag::err_omp_required_access) 12813 << getOpenMPClauseName(OMPC_copyin) 12814 << getOpenMPDirectiveName(OMPD_threadprivate); 12815 continue; 12816 } 12817 12818 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12819 // A variable of class type (or array thereof) that appears in a 12820 // copyin clause requires an accessible, unambiguous copy assignment 12821 // operator for the class type. 12822 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12823 VarDecl *SrcVD = 12824 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12825 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12826 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12827 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12828 VarDecl *DstVD = 12829 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12830 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12831 DeclRefExpr *PseudoDstExpr = 12832 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12833 // For arrays generate assignment operation for single element and replace 12834 // it by the original array element in CodeGen. 12835 ExprResult AssignmentOp = 12836 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12837 PseudoSrcExpr); 12838 if (AssignmentOp.isInvalid()) 12839 continue; 12840 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12841 /*DiscardedValue*/ false); 12842 if (AssignmentOp.isInvalid()) 12843 continue; 12844 12845 DSAStack->addDSA(VD, DE, OMPC_copyin); 12846 Vars.push_back(DE); 12847 SrcExprs.push_back(PseudoSrcExpr); 12848 DstExprs.push_back(PseudoDstExpr); 12849 AssignmentOps.push_back(AssignmentOp.get()); 12850 } 12851 12852 if (Vars.empty()) 12853 return nullptr; 12854 12855 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12856 SrcExprs, DstExprs, AssignmentOps); 12857 } 12858 12859 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12860 SourceLocation StartLoc, 12861 SourceLocation LParenLoc, 12862 SourceLocation EndLoc) { 12863 SmallVector<Expr *, 8> Vars; 12864 SmallVector<Expr *, 8> SrcExprs; 12865 SmallVector<Expr *, 8> DstExprs; 12866 SmallVector<Expr *, 8> AssignmentOps; 12867 for (Expr *RefExpr : VarList) { 12868 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12869 SourceLocation ELoc; 12870 SourceRange ERange; 12871 Expr *SimpleRefExpr = RefExpr; 12872 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12873 if (Res.second) { 12874 // It will be analyzed later. 12875 Vars.push_back(RefExpr); 12876 SrcExprs.push_back(nullptr); 12877 DstExprs.push_back(nullptr); 12878 AssignmentOps.push_back(nullptr); 12879 } 12880 ValueDecl *D = Res.first; 12881 if (!D) 12882 continue; 12883 12884 QualType Type = D->getType(); 12885 auto *VD = dyn_cast<VarDecl>(D); 12886 12887 // OpenMP [2.14.4.2, Restrictions, p.2] 12888 // A list item that appears in a copyprivate clause may not appear in a 12889 // private or firstprivate clause on the single construct. 12890 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12891 DSAStackTy::DSAVarData DVar = 12892 DSAStack->getTopDSA(D, /*FromParent=*/false); 12893 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12894 DVar.RefExpr) { 12895 Diag(ELoc, diag::err_omp_wrong_dsa) 12896 << getOpenMPClauseName(DVar.CKind) 12897 << getOpenMPClauseName(OMPC_copyprivate); 12898 reportOriginalDsa(*this, DSAStack, D, DVar); 12899 continue; 12900 } 12901 12902 // OpenMP [2.11.4.2, Restrictions, p.1] 12903 // All list items that appear in a copyprivate clause must be either 12904 // threadprivate or private in the enclosing context. 12905 if (DVar.CKind == OMPC_unknown) { 12906 DVar = DSAStack->getImplicitDSA(D, false); 12907 if (DVar.CKind == OMPC_shared) { 12908 Diag(ELoc, diag::err_omp_required_access) 12909 << getOpenMPClauseName(OMPC_copyprivate) 12910 << "threadprivate or private in the enclosing context"; 12911 reportOriginalDsa(*this, DSAStack, D, DVar); 12912 continue; 12913 } 12914 } 12915 } 12916 12917 // Variably modified types are not supported. 12918 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12919 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12920 << getOpenMPClauseName(OMPC_copyprivate) << Type 12921 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12922 bool IsDecl = 12923 !VD || 12924 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12925 Diag(D->getLocation(), 12926 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12927 << D; 12928 continue; 12929 } 12930 12931 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12932 // A variable of class type (or array thereof) that appears in a 12933 // copyin clause requires an accessible, unambiguous copy assignment 12934 // operator for the class type. 12935 Type = Context.getBaseElementType(Type.getNonReferenceType()) 12936 .getUnqualifiedType(); 12937 VarDecl *SrcVD = 12938 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 12939 D->hasAttrs() ? &D->getAttrs() : nullptr); 12940 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 12941 VarDecl *DstVD = 12942 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 12943 D->hasAttrs() ? &D->getAttrs() : nullptr); 12944 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12945 ExprResult AssignmentOp = BuildBinOp( 12946 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 12947 if (AssignmentOp.isInvalid()) 12948 continue; 12949 AssignmentOp = 12950 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12951 if (AssignmentOp.isInvalid()) 12952 continue; 12953 12954 // No need to mark vars as copyprivate, they are already threadprivate or 12955 // implicitly private. 12956 assert(VD || isOpenMPCapturedDecl(D)); 12957 Vars.push_back( 12958 VD ? RefExpr->IgnoreParens() 12959 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 12960 SrcExprs.push_back(PseudoSrcExpr); 12961 DstExprs.push_back(PseudoDstExpr); 12962 AssignmentOps.push_back(AssignmentOp.get()); 12963 } 12964 12965 if (Vars.empty()) 12966 return nullptr; 12967 12968 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12969 Vars, SrcExprs, DstExprs, AssignmentOps); 12970 } 12971 12972 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 12973 SourceLocation StartLoc, 12974 SourceLocation LParenLoc, 12975 SourceLocation EndLoc) { 12976 if (VarList.empty()) 12977 return nullptr; 12978 12979 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 12980 } 12981 12982 OMPClause * 12983 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 12984 SourceLocation DepLoc, SourceLocation ColonLoc, 12985 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12986 SourceLocation LParenLoc, SourceLocation EndLoc) { 12987 if (DSAStack->getCurrentDirective() == OMPD_ordered && 12988 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 12989 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12990 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 12991 return nullptr; 12992 } 12993 if (DSAStack->getCurrentDirective() != OMPD_ordered && 12994 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 12995 DepKind == OMPC_DEPEND_sink)) { 12996 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 12997 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12998 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12999 /*Last=*/OMPC_DEPEND_unknown, Except) 13000 << getOpenMPClauseName(OMPC_depend); 13001 return nullptr; 13002 } 13003 SmallVector<Expr *, 8> Vars; 13004 DSAStackTy::OperatorOffsetTy OpsOffs; 13005 llvm::APSInt DepCounter(/*BitWidth=*/32); 13006 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13007 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13008 if (const Expr *OrderedCountExpr = 13009 DSAStack->getParentOrderedRegionParam().first) { 13010 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13011 TotalDepCount.setIsUnsigned(/*Val=*/true); 13012 } 13013 } 13014 for (Expr *RefExpr : VarList) { 13015 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13016 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13017 // It will be analyzed later. 13018 Vars.push_back(RefExpr); 13019 continue; 13020 } 13021 13022 SourceLocation ELoc = RefExpr->getExprLoc(); 13023 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13024 if (DepKind == OMPC_DEPEND_sink) { 13025 if (DSAStack->getParentOrderedRegionParam().first && 13026 DepCounter >= TotalDepCount) { 13027 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13028 continue; 13029 } 13030 ++DepCounter; 13031 // OpenMP [2.13.9, Summary] 13032 // depend(dependence-type : vec), where dependence-type is: 13033 // 'sink' and where vec is the iteration vector, which has the form: 13034 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13035 // where n is the value specified by the ordered clause in the loop 13036 // directive, xi denotes the loop iteration variable of the i-th nested 13037 // loop associated with the loop directive, and di is a constant 13038 // non-negative integer. 13039 if (CurContext->isDependentContext()) { 13040 // It will be analyzed later. 13041 Vars.push_back(RefExpr); 13042 continue; 13043 } 13044 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13045 OverloadedOperatorKind OOK = OO_None; 13046 SourceLocation OOLoc; 13047 Expr *LHS = SimpleExpr; 13048 Expr *RHS = nullptr; 13049 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13050 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13051 OOLoc = BO->getOperatorLoc(); 13052 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13053 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13054 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13055 OOK = OCE->getOperator(); 13056 OOLoc = OCE->getOperatorLoc(); 13057 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13058 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13059 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13060 OOK = MCE->getMethodDecl() 13061 ->getNameInfo() 13062 .getName() 13063 .getCXXOverloadedOperator(); 13064 OOLoc = MCE->getCallee()->getExprLoc(); 13065 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13066 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13067 } 13068 SourceLocation ELoc; 13069 SourceRange ERange; 13070 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13071 if (Res.second) { 13072 // It will be analyzed later. 13073 Vars.push_back(RefExpr); 13074 } 13075 ValueDecl *D = Res.first; 13076 if (!D) 13077 continue; 13078 13079 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13080 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13081 continue; 13082 } 13083 if (RHS) { 13084 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13085 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13086 if (RHSRes.isInvalid()) 13087 continue; 13088 } 13089 if (!CurContext->isDependentContext() && 13090 DSAStack->getParentOrderedRegionParam().first && 13091 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13092 const ValueDecl *VD = 13093 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13094 if (VD) 13095 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13096 << 1 << VD; 13097 else 13098 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13099 continue; 13100 } 13101 OpsOffs.emplace_back(RHS, OOK); 13102 } else { 13103 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13104 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13105 (ASE && 13106 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13107 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13108 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13109 << RefExpr->getSourceRange(); 13110 continue; 13111 } 13112 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 13113 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 13114 ExprResult Res = 13115 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 13116 getDiagnostics().setSuppressAllDiagnostics(Suppress); 13117 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13118 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13119 << RefExpr->getSourceRange(); 13120 continue; 13121 } 13122 } 13123 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13124 } 13125 13126 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13127 TotalDepCount > VarList.size() && 13128 DSAStack->getParentOrderedRegionParam().first && 13129 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13130 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13131 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13132 } 13133 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13134 Vars.empty()) 13135 return nullptr; 13136 13137 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13138 DepKind, DepLoc, ColonLoc, Vars, 13139 TotalDepCount.getZExtValue()); 13140 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13141 DSAStack->isParentOrderedRegion()) 13142 DSAStack->addDoacrossDependClause(C, OpsOffs); 13143 return C; 13144 } 13145 13146 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13147 SourceLocation LParenLoc, 13148 SourceLocation EndLoc) { 13149 Expr *ValExpr = Device; 13150 Stmt *HelperValStmt = nullptr; 13151 13152 // OpenMP [2.9.1, Restrictions] 13153 // The device expression must evaluate to a non-negative integer value. 13154 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13155 /*StrictlyPositive=*/false)) 13156 return nullptr; 13157 13158 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13159 OpenMPDirectiveKind CaptureRegion = 13160 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13161 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13162 ValExpr = MakeFullExpr(ValExpr).get(); 13163 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13164 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13165 HelperValStmt = buildPreInits(Context, Captures); 13166 } 13167 13168 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13169 StartLoc, LParenLoc, EndLoc); 13170 } 13171 13172 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13173 DSAStackTy *Stack, QualType QTy, 13174 bool FullCheck = true) { 13175 NamedDecl *ND; 13176 if (QTy->isIncompleteType(&ND)) { 13177 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13178 return false; 13179 } 13180 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13181 !QTy.isTrivialType(SemaRef.Context)) 13182 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13183 return true; 13184 } 13185 13186 /// Return true if it can be proven that the provided array expression 13187 /// (array section or array subscript) does NOT specify the whole size of the 13188 /// array whose base type is \a BaseQTy. 13189 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13190 const Expr *E, 13191 QualType BaseQTy) { 13192 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13193 13194 // If this is an array subscript, it refers to the whole size if the size of 13195 // the dimension is constant and equals 1. Also, an array section assumes the 13196 // format of an array subscript if no colon is used. 13197 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13198 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13199 return ATy->getSize().getSExtValue() != 1; 13200 // Size can't be evaluated statically. 13201 return false; 13202 } 13203 13204 assert(OASE && "Expecting array section if not an array subscript."); 13205 const Expr *LowerBound = OASE->getLowerBound(); 13206 const Expr *Length = OASE->getLength(); 13207 13208 // If there is a lower bound that does not evaluates to zero, we are not 13209 // covering the whole dimension. 13210 if (LowerBound) { 13211 Expr::EvalResult Result; 13212 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13213 return false; // Can't get the integer value as a constant. 13214 13215 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13216 if (ConstLowerBound.getSExtValue()) 13217 return true; 13218 } 13219 13220 // If we don't have a length we covering the whole dimension. 13221 if (!Length) 13222 return false; 13223 13224 // If the base is a pointer, we don't have a way to get the size of the 13225 // pointee. 13226 if (BaseQTy->isPointerType()) 13227 return false; 13228 13229 // We can only check if the length is the same as the size of the dimension 13230 // if we have a constant array. 13231 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13232 if (!CATy) 13233 return false; 13234 13235 Expr::EvalResult Result; 13236 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13237 return false; // Can't get the integer value as a constant. 13238 13239 llvm::APSInt ConstLength = Result.Val.getInt(); 13240 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13241 } 13242 13243 // Return true if it can be proven that the provided array expression (array 13244 // section or array subscript) does NOT specify a single element of the array 13245 // whose base type is \a BaseQTy. 13246 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13247 const Expr *E, 13248 QualType BaseQTy) { 13249 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13250 13251 // An array subscript always refer to a single element. Also, an array section 13252 // assumes the format of an array subscript if no colon is used. 13253 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13254 return false; 13255 13256 assert(OASE && "Expecting array section if not an array subscript."); 13257 const Expr *Length = OASE->getLength(); 13258 13259 // If we don't have a length we have to check if the array has unitary size 13260 // for this dimension. Also, we should always expect a length if the base type 13261 // is pointer. 13262 if (!Length) { 13263 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13264 return ATy->getSize().getSExtValue() != 1; 13265 // We cannot assume anything. 13266 return false; 13267 } 13268 13269 // Check if the length evaluates to 1. 13270 Expr::EvalResult Result; 13271 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13272 return false; // Can't get the integer value as a constant. 13273 13274 llvm::APSInt ConstLength = Result.Val.getInt(); 13275 return ConstLength.getSExtValue() != 1; 13276 } 13277 13278 // Return the expression of the base of the mappable expression or null if it 13279 // cannot be determined and do all the necessary checks to see if the expression 13280 // is valid as a standalone mappable expression. In the process, record all the 13281 // components of the expression. 13282 static const Expr *checkMapClauseExpressionBase( 13283 Sema &SemaRef, Expr *E, 13284 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13285 OpenMPClauseKind CKind, bool NoDiagnose) { 13286 SourceLocation ELoc = E->getExprLoc(); 13287 SourceRange ERange = E->getSourceRange(); 13288 13289 // The base of elements of list in a map clause have to be either: 13290 // - a reference to variable or field. 13291 // - a member expression. 13292 // - an array expression. 13293 // 13294 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13295 // reference to 'r'. 13296 // 13297 // If we have: 13298 // 13299 // struct SS { 13300 // Bla S; 13301 // foo() { 13302 // #pragma omp target map (S.Arr[:12]); 13303 // } 13304 // } 13305 // 13306 // We want to retrieve the member expression 'this->S'; 13307 13308 const Expr *RelevantExpr = nullptr; 13309 13310 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13311 // If a list item is an array section, it must specify contiguous storage. 13312 // 13313 // For this restriction it is sufficient that we make sure only references 13314 // to variables or fields and array expressions, and that no array sections 13315 // exist except in the rightmost expression (unless they cover the whole 13316 // dimension of the array). E.g. these would be invalid: 13317 // 13318 // r.ArrS[3:5].Arr[6:7] 13319 // 13320 // r.ArrS[3:5].x 13321 // 13322 // but these would be valid: 13323 // r.ArrS[3].Arr[6:7] 13324 // 13325 // r.ArrS[3].x 13326 13327 bool AllowUnitySizeArraySection = true; 13328 bool AllowWholeSizeArraySection = true; 13329 13330 while (!RelevantExpr) { 13331 E = E->IgnoreParenImpCasts(); 13332 13333 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13334 if (!isa<VarDecl>(CurE->getDecl())) 13335 return nullptr; 13336 13337 RelevantExpr = CurE; 13338 13339 // If we got a reference to a declaration, we should not expect any array 13340 // section before that. 13341 AllowUnitySizeArraySection = false; 13342 AllowWholeSizeArraySection = false; 13343 13344 // Record the component. 13345 CurComponents.emplace_back(CurE, CurE->getDecl()); 13346 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13347 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13348 13349 if (isa<CXXThisExpr>(BaseE)) 13350 // We found a base expression: this->Val. 13351 RelevantExpr = CurE; 13352 else 13353 E = BaseE; 13354 13355 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13356 if (!NoDiagnose) { 13357 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13358 << CurE->getSourceRange(); 13359 return nullptr; 13360 } 13361 if (RelevantExpr) 13362 return nullptr; 13363 continue; 13364 } 13365 13366 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13367 13368 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13369 // A bit-field cannot appear in a map clause. 13370 // 13371 if (FD->isBitField()) { 13372 if (!NoDiagnose) { 13373 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13374 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13375 return nullptr; 13376 } 13377 if (RelevantExpr) 13378 return nullptr; 13379 continue; 13380 } 13381 13382 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13383 // If the type of a list item is a reference to a type T then the type 13384 // will be considered to be T for all purposes of this clause. 13385 QualType CurType = BaseE->getType().getNonReferenceType(); 13386 13387 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13388 // A list item cannot be a variable that is a member of a structure with 13389 // a union type. 13390 // 13391 if (CurType->isUnionType()) { 13392 if (!NoDiagnose) { 13393 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13394 << CurE->getSourceRange(); 13395 return nullptr; 13396 } 13397 continue; 13398 } 13399 13400 // If we got a member expression, we should not expect any array section 13401 // before that: 13402 // 13403 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13404 // If a list item is an element of a structure, only the rightmost symbol 13405 // of the variable reference can be an array section. 13406 // 13407 AllowUnitySizeArraySection = false; 13408 AllowWholeSizeArraySection = false; 13409 13410 // Record the component. 13411 CurComponents.emplace_back(CurE, FD); 13412 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13413 E = CurE->getBase()->IgnoreParenImpCasts(); 13414 13415 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13416 if (!NoDiagnose) { 13417 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13418 << 0 << CurE->getSourceRange(); 13419 return nullptr; 13420 } 13421 continue; 13422 } 13423 13424 // If we got an array subscript that express the whole dimension we 13425 // can have any array expressions before. If it only expressing part of 13426 // the dimension, we can only have unitary-size array expressions. 13427 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13428 E->getType())) 13429 AllowWholeSizeArraySection = false; 13430 13431 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13432 Expr::EvalResult Result; 13433 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13434 if (!Result.Val.getInt().isNullValue()) { 13435 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13436 diag::err_omp_invalid_map_this_expr); 13437 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13438 diag::note_omp_invalid_subscript_on_this_ptr_map); 13439 } 13440 } 13441 RelevantExpr = TE; 13442 } 13443 13444 // Record the component - we don't have any declaration associated. 13445 CurComponents.emplace_back(CurE, nullptr); 13446 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13447 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13448 E = CurE->getBase()->IgnoreParenImpCasts(); 13449 13450 QualType CurType = 13451 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13452 13453 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13454 // If the type of a list item is a reference to a type T then the type 13455 // will be considered to be T for all purposes of this clause. 13456 if (CurType->isReferenceType()) 13457 CurType = CurType->getPointeeType(); 13458 13459 bool IsPointer = CurType->isAnyPointerType(); 13460 13461 if (!IsPointer && !CurType->isArrayType()) { 13462 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13463 << 0 << CurE->getSourceRange(); 13464 return nullptr; 13465 } 13466 13467 bool NotWhole = 13468 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13469 bool NotUnity = 13470 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13471 13472 if (AllowWholeSizeArraySection) { 13473 // Any array section is currently allowed. Allowing a whole size array 13474 // section implies allowing a unity array section as well. 13475 // 13476 // If this array section refers to the whole dimension we can still 13477 // accept other array sections before this one, except if the base is a 13478 // pointer. Otherwise, only unitary sections are accepted. 13479 if (NotWhole || IsPointer) 13480 AllowWholeSizeArraySection = false; 13481 } else if (AllowUnitySizeArraySection && NotUnity) { 13482 // A unity or whole array section is not allowed and that is not 13483 // compatible with the properties of the current array section. 13484 SemaRef.Diag( 13485 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13486 << CurE->getSourceRange(); 13487 return nullptr; 13488 } 13489 13490 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13491 Expr::EvalResult ResultR; 13492 Expr::EvalResult ResultL; 13493 if (CurE->getLength()->EvaluateAsInt(ResultR, 13494 SemaRef.getASTContext())) { 13495 if (!ResultR.Val.getInt().isOneValue()) { 13496 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13497 diag::err_omp_invalid_map_this_expr); 13498 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13499 diag::note_omp_invalid_length_on_this_ptr_mapping); 13500 } 13501 } 13502 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13503 ResultL, SemaRef.getASTContext())) { 13504 if (!ResultL.Val.getInt().isNullValue()) { 13505 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13506 diag::err_omp_invalid_map_this_expr); 13507 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13508 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13509 } 13510 } 13511 RelevantExpr = TE; 13512 } 13513 13514 // Record the component - we don't have any declaration associated. 13515 CurComponents.emplace_back(CurE, nullptr); 13516 } else { 13517 if (!NoDiagnose) { 13518 // If nothing else worked, this is not a valid map clause expression. 13519 SemaRef.Diag( 13520 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13521 << ERange; 13522 } 13523 return nullptr; 13524 } 13525 } 13526 13527 return RelevantExpr; 13528 } 13529 13530 // Return true if expression E associated with value VD has conflicts with other 13531 // map information. 13532 static bool checkMapConflicts( 13533 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13534 bool CurrentRegionOnly, 13535 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13536 OpenMPClauseKind CKind) { 13537 assert(VD && E); 13538 SourceLocation ELoc = E->getExprLoc(); 13539 SourceRange ERange = E->getSourceRange(); 13540 13541 // In order to easily check the conflicts we need to match each component of 13542 // the expression under test with the components of the expressions that are 13543 // already in the stack. 13544 13545 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13546 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13547 "Map clause expression with unexpected base!"); 13548 13549 // Variables to help detecting enclosing problems in data environment nests. 13550 bool IsEnclosedByDataEnvironmentExpr = false; 13551 const Expr *EnclosingExpr = nullptr; 13552 13553 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13554 VD, CurrentRegionOnly, 13555 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13556 ERange, CKind, &EnclosingExpr, 13557 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13558 StackComponents, 13559 OpenMPClauseKind) { 13560 assert(!StackComponents.empty() && 13561 "Map clause expression with no components!"); 13562 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13563 "Map clause expression with unexpected base!"); 13564 (void)VD; 13565 13566 // The whole expression in the stack. 13567 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13568 13569 // Expressions must start from the same base. Here we detect at which 13570 // point both expressions diverge from each other and see if we can 13571 // detect if the memory referred to both expressions is contiguous and 13572 // do not overlap. 13573 auto CI = CurComponents.rbegin(); 13574 auto CE = CurComponents.rend(); 13575 auto SI = StackComponents.rbegin(); 13576 auto SE = StackComponents.rend(); 13577 for (; CI != CE && SI != SE; ++CI, ++SI) { 13578 13579 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13580 // At most one list item can be an array item derived from a given 13581 // variable in map clauses of the same construct. 13582 if (CurrentRegionOnly && 13583 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13584 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13585 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13586 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13587 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13588 diag::err_omp_multiple_array_items_in_map_clause) 13589 << CI->getAssociatedExpression()->getSourceRange(); 13590 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13591 diag::note_used_here) 13592 << SI->getAssociatedExpression()->getSourceRange(); 13593 return true; 13594 } 13595 13596 // Do both expressions have the same kind? 13597 if (CI->getAssociatedExpression()->getStmtClass() != 13598 SI->getAssociatedExpression()->getStmtClass()) 13599 break; 13600 13601 // Are we dealing with different variables/fields? 13602 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13603 break; 13604 } 13605 // Check if the extra components of the expressions in the enclosing 13606 // data environment are redundant for the current base declaration. 13607 // If they are, the maps completely overlap, which is legal. 13608 for (; SI != SE; ++SI) { 13609 QualType Type; 13610 if (const auto *ASE = 13611 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13612 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13613 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13614 SI->getAssociatedExpression())) { 13615 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13616 Type = 13617 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13618 } 13619 if (Type.isNull() || Type->isAnyPointerType() || 13620 checkArrayExpressionDoesNotReferToWholeSize( 13621 SemaRef, SI->getAssociatedExpression(), Type)) 13622 break; 13623 } 13624 13625 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13626 // List items of map clauses in the same construct must not share 13627 // original storage. 13628 // 13629 // If the expressions are exactly the same or one is a subset of the 13630 // other, it means they are sharing storage. 13631 if (CI == CE && SI == SE) { 13632 if (CurrentRegionOnly) { 13633 if (CKind == OMPC_map) { 13634 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13635 } else { 13636 assert(CKind == OMPC_to || CKind == OMPC_from); 13637 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13638 << ERange; 13639 } 13640 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13641 << RE->getSourceRange(); 13642 return true; 13643 } 13644 // If we find the same expression in the enclosing data environment, 13645 // that is legal. 13646 IsEnclosedByDataEnvironmentExpr = true; 13647 return false; 13648 } 13649 13650 QualType DerivedType = 13651 std::prev(CI)->getAssociatedDeclaration()->getType(); 13652 SourceLocation DerivedLoc = 13653 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13654 13655 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13656 // If the type of a list item is a reference to a type T then the type 13657 // will be considered to be T for all purposes of this clause. 13658 DerivedType = DerivedType.getNonReferenceType(); 13659 13660 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13661 // A variable for which the type is pointer and an array section 13662 // derived from that variable must not appear as list items of map 13663 // clauses of the same construct. 13664 // 13665 // Also, cover one of the cases in: 13666 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13667 // If any part of the original storage of a list item has corresponding 13668 // storage in the device data environment, all of the original storage 13669 // must have corresponding storage in the device data environment. 13670 // 13671 if (DerivedType->isAnyPointerType()) { 13672 if (CI == CE || SI == SE) { 13673 SemaRef.Diag( 13674 DerivedLoc, 13675 diag::err_omp_pointer_mapped_along_with_derived_section) 13676 << DerivedLoc; 13677 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13678 << RE->getSourceRange(); 13679 return true; 13680 } 13681 if (CI->getAssociatedExpression()->getStmtClass() != 13682 SI->getAssociatedExpression()->getStmtClass() || 13683 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13684 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13685 assert(CI != CE && SI != SE); 13686 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13687 << DerivedLoc; 13688 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13689 << RE->getSourceRange(); 13690 return true; 13691 } 13692 } 13693 13694 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13695 // List items of map clauses in the same construct must not share 13696 // original storage. 13697 // 13698 // An expression is a subset of the other. 13699 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13700 if (CKind == OMPC_map) { 13701 if (CI != CE || SI != SE) { 13702 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13703 // a pointer. 13704 auto Begin = 13705 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13706 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13707 auto It = Begin; 13708 while (It != End && !It->getAssociatedDeclaration()) 13709 std::advance(It, 1); 13710 assert(It != End && 13711 "Expected at least one component with the declaration."); 13712 if (It != Begin && It->getAssociatedDeclaration() 13713 ->getType() 13714 .getCanonicalType() 13715 ->isAnyPointerType()) { 13716 IsEnclosedByDataEnvironmentExpr = false; 13717 EnclosingExpr = nullptr; 13718 return false; 13719 } 13720 } 13721 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13722 } else { 13723 assert(CKind == OMPC_to || CKind == OMPC_from); 13724 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13725 << ERange; 13726 } 13727 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13728 << RE->getSourceRange(); 13729 return true; 13730 } 13731 13732 // The current expression uses the same base as other expression in the 13733 // data environment but does not contain it completely. 13734 if (!CurrentRegionOnly && SI != SE) 13735 EnclosingExpr = RE; 13736 13737 // The current expression is a subset of the expression in the data 13738 // environment. 13739 IsEnclosedByDataEnvironmentExpr |= 13740 (!CurrentRegionOnly && CI != CE && SI == SE); 13741 13742 return false; 13743 }); 13744 13745 if (CurrentRegionOnly) 13746 return FoundError; 13747 13748 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13749 // If any part of the original storage of a list item has corresponding 13750 // storage in the device data environment, all of the original storage must 13751 // have corresponding storage in the device data environment. 13752 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13753 // If a list item is an element of a structure, and a different element of 13754 // the structure has a corresponding list item in the device data environment 13755 // prior to a task encountering the construct associated with the map clause, 13756 // then the list item must also have a corresponding list item in the device 13757 // data environment prior to the task encountering the construct. 13758 // 13759 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13760 SemaRef.Diag(ELoc, 13761 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13762 << ERange; 13763 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13764 << EnclosingExpr->getSourceRange(); 13765 return true; 13766 } 13767 13768 return FoundError; 13769 } 13770 13771 // Look up the user-defined mapper given the mapper name and mapped type, and 13772 // build a reference to it. 13773 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13774 CXXScopeSpec &MapperIdScopeSpec, 13775 const DeclarationNameInfo &MapperId, 13776 QualType Type, 13777 Expr *UnresolvedMapper) { 13778 if (MapperIdScopeSpec.isInvalid()) 13779 return ExprError(); 13780 // Find all user-defined mappers with the given MapperId. 13781 SmallVector<UnresolvedSet<8>, 4> Lookups; 13782 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13783 Lookup.suppressDiagnostics(); 13784 if (S) { 13785 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13786 NamedDecl *D = Lookup.getRepresentativeDecl(); 13787 while (S && !S->isDeclScope(D)) 13788 S = S->getParent(); 13789 if (S) 13790 S = S->getParent(); 13791 Lookups.emplace_back(); 13792 Lookups.back().append(Lookup.begin(), Lookup.end()); 13793 Lookup.clear(); 13794 } 13795 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13796 // Extract the user-defined mappers with the given MapperId. 13797 Lookups.push_back(UnresolvedSet<8>()); 13798 for (NamedDecl *D : ULE->decls()) { 13799 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13800 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13801 Lookups.back().addDecl(DMD); 13802 } 13803 } 13804 // Defer the lookup for dependent types. The results will be passed through 13805 // UnresolvedMapper on instantiation. 13806 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13807 Type->isInstantiationDependentType() || 13808 Type->containsUnexpandedParameterPack() || 13809 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13810 return !D->isInvalidDecl() && 13811 (D->getType()->isDependentType() || 13812 D->getType()->isInstantiationDependentType() || 13813 D->getType()->containsUnexpandedParameterPack()); 13814 })) { 13815 UnresolvedSet<8> URS; 13816 for (const UnresolvedSet<8> &Set : Lookups) { 13817 if (Set.empty()) 13818 continue; 13819 URS.append(Set.begin(), Set.end()); 13820 } 13821 return UnresolvedLookupExpr::Create( 13822 SemaRef.Context, /*NamingClass=*/nullptr, 13823 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13824 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13825 } 13826 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13827 // The type must be of struct, union or class type in C and C++ 13828 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13829 return ExprEmpty(); 13830 SourceLocation Loc = MapperId.getLoc(); 13831 // Perform argument dependent lookup. 13832 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13833 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13834 // Return the first user-defined mapper with the desired type. 13835 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13836 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13837 if (!D->isInvalidDecl() && 13838 SemaRef.Context.hasSameType(D->getType(), Type)) 13839 return D; 13840 return nullptr; 13841 })) 13842 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13843 // Find the first user-defined mapper with a type derived from the desired 13844 // type. 13845 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13846 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13847 if (!D->isInvalidDecl() && 13848 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13849 !Type.isMoreQualifiedThan(D->getType())) 13850 return D; 13851 return nullptr; 13852 })) { 13853 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13854 /*DetectVirtual=*/false); 13855 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13856 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13857 VD->getType().getUnqualifiedType()))) { 13858 if (SemaRef.CheckBaseClassAccess( 13859 Loc, VD->getType(), Type, Paths.front(), 13860 /*DiagID=*/0) != Sema::AR_inaccessible) { 13861 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13862 } 13863 } 13864 } 13865 } 13866 // Report error if a mapper is specified, but cannot be found. 13867 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13868 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13869 << Type << MapperId.getName(); 13870 return ExprError(); 13871 } 13872 return ExprEmpty(); 13873 } 13874 13875 namespace { 13876 // Utility struct that gathers all the related lists associated with a mappable 13877 // expression. 13878 struct MappableVarListInfo { 13879 // The list of expressions. 13880 ArrayRef<Expr *> VarList; 13881 // The list of processed expressions. 13882 SmallVector<Expr *, 16> ProcessedVarList; 13883 // The mappble components for each expression. 13884 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13885 // The base declaration of the variable. 13886 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13887 // The reference to the user-defined mapper associated with every expression. 13888 SmallVector<Expr *, 16> UDMapperList; 13889 13890 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13891 // We have a list of components and base declarations for each entry in the 13892 // variable list. 13893 VarComponents.reserve(VarList.size()); 13894 VarBaseDeclarations.reserve(VarList.size()); 13895 } 13896 }; 13897 } 13898 13899 // Check the validity of the provided variable list for the provided clause kind 13900 // \a CKind. In the check process the valid expressions, mappable expression 13901 // components, variables, and user-defined mappers are extracted and used to 13902 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13903 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13904 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13905 static void checkMappableExpressionList( 13906 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13907 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13908 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13909 ArrayRef<Expr *> UnresolvedMappers, 13910 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13911 bool IsMapTypeImplicit = false) { 13912 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13913 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13914 "Unexpected clause kind with mappable expressions!"); 13915 13916 // If the identifier of user-defined mapper is not specified, it is "default". 13917 // We do not change the actual name in this clause to distinguish whether a 13918 // mapper is specified explicitly, i.e., it is not explicitly specified when 13919 // MapperId.getName() is empty. 13920 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13921 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 13922 MapperId.setName(DeclNames.getIdentifier( 13923 &SemaRef.getASTContext().Idents.get("default"))); 13924 } 13925 13926 // Iterators to find the current unresolved mapper expression. 13927 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 13928 bool UpdateUMIt = false; 13929 Expr *UnresolvedMapper = nullptr; 13930 13931 // Keep track of the mappable components and base declarations in this clause. 13932 // Each entry in the list is going to have a list of components associated. We 13933 // record each set of the components so that we can build the clause later on. 13934 // In the end we should have the same amount of declarations and component 13935 // lists. 13936 13937 for (Expr *RE : MVLI.VarList) { 13938 assert(RE && "Null expr in omp to/from/map clause"); 13939 SourceLocation ELoc = RE->getExprLoc(); 13940 13941 // Find the current unresolved mapper expression. 13942 if (UpdateUMIt && UMIt != UMEnd) { 13943 UMIt++; 13944 assert( 13945 UMIt != UMEnd && 13946 "Expect the size of UnresolvedMappers to match with that of VarList"); 13947 } 13948 UpdateUMIt = true; 13949 if (UMIt != UMEnd) 13950 UnresolvedMapper = *UMIt; 13951 13952 const Expr *VE = RE->IgnoreParenLValueCasts(); 13953 13954 if (VE->isValueDependent() || VE->isTypeDependent() || 13955 VE->isInstantiationDependent() || 13956 VE->containsUnexpandedParameterPack()) { 13957 // Try to find the associated user-defined mapper. 13958 ExprResult ER = buildUserDefinedMapperRef( 13959 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13960 VE->getType().getCanonicalType(), UnresolvedMapper); 13961 if (ER.isInvalid()) 13962 continue; 13963 MVLI.UDMapperList.push_back(ER.get()); 13964 // We can only analyze this information once the missing information is 13965 // resolved. 13966 MVLI.ProcessedVarList.push_back(RE); 13967 continue; 13968 } 13969 13970 Expr *SimpleExpr = RE->IgnoreParenCasts(); 13971 13972 if (!RE->IgnoreParenImpCasts()->isLValue()) { 13973 SemaRef.Diag(ELoc, 13974 diag::err_omp_expected_named_var_member_or_array_expression) 13975 << RE->getSourceRange(); 13976 continue; 13977 } 13978 13979 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 13980 ValueDecl *CurDeclaration = nullptr; 13981 13982 // Obtain the array or member expression bases if required. Also, fill the 13983 // components array with all the components identified in the process. 13984 const Expr *BE = checkMapClauseExpressionBase( 13985 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 13986 if (!BE) 13987 continue; 13988 13989 assert(!CurComponents.empty() && 13990 "Invalid mappable expression information."); 13991 13992 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 13993 // Add store "this" pointer to class in DSAStackTy for future checking 13994 DSAS->addMappedClassesQualTypes(TE->getType()); 13995 // Try to find the associated user-defined mapper. 13996 ExprResult ER = buildUserDefinedMapperRef( 13997 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13998 VE->getType().getCanonicalType(), UnresolvedMapper); 13999 if (ER.isInvalid()) 14000 continue; 14001 MVLI.UDMapperList.push_back(ER.get()); 14002 // Skip restriction checking for variable or field declarations 14003 MVLI.ProcessedVarList.push_back(RE); 14004 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14005 MVLI.VarComponents.back().append(CurComponents.begin(), 14006 CurComponents.end()); 14007 MVLI.VarBaseDeclarations.push_back(nullptr); 14008 continue; 14009 } 14010 14011 // For the following checks, we rely on the base declaration which is 14012 // expected to be associated with the last component. The declaration is 14013 // expected to be a variable or a field (if 'this' is being mapped). 14014 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14015 assert(CurDeclaration && "Null decl on map clause."); 14016 assert( 14017 CurDeclaration->isCanonicalDecl() && 14018 "Expecting components to have associated only canonical declarations."); 14019 14020 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14021 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14022 14023 assert((VD || FD) && "Only variables or fields are expected here!"); 14024 (void)FD; 14025 14026 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14027 // threadprivate variables cannot appear in a map clause. 14028 // OpenMP 4.5 [2.10.5, target update Construct] 14029 // threadprivate variables cannot appear in a from clause. 14030 if (VD && DSAS->isThreadPrivate(VD)) { 14031 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14032 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14033 << getOpenMPClauseName(CKind); 14034 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14035 continue; 14036 } 14037 14038 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14039 // A list item cannot appear in both a map clause and a data-sharing 14040 // attribute clause on the same construct. 14041 14042 // Check conflicts with other map clause expressions. We check the conflicts 14043 // with the current construct separately from the enclosing data 14044 // environment, because the restrictions are different. We only have to 14045 // check conflicts across regions for the map clauses. 14046 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14047 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14048 break; 14049 if (CKind == OMPC_map && 14050 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14051 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14052 break; 14053 14054 // OpenMP 4.5 [2.10.5, target update Construct] 14055 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14056 // If the type of a list item is a reference to a type T then the type will 14057 // be considered to be T for all purposes of this clause. 14058 auto I = llvm::find_if( 14059 CurComponents, 14060 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14061 return MC.getAssociatedDeclaration(); 14062 }); 14063 assert(I != CurComponents.end() && "Null decl on map clause."); 14064 QualType Type = 14065 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14066 14067 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14068 // A list item in a to or from clause must have a mappable type. 14069 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14070 // A list item must have a mappable type. 14071 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14072 DSAS, Type)) 14073 continue; 14074 14075 if (CKind == OMPC_map) { 14076 // target enter data 14077 // OpenMP [2.10.2, Restrictions, p. 99] 14078 // A map-type must be specified in all map clauses and must be either 14079 // to or alloc. 14080 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14081 if (DKind == OMPD_target_enter_data && 14082 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14083 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14084 << (IsMapTypeImplicit ? 1 : 0) 14085 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14086 << getOpenMPDirectiveName(DKind); 14087 continue; 14088 } 14089 14090 // target exit_data 14091 // OpenMP [2.10.3, Restrictions, p. 102] 14092 // A map-type must be specified in all map clauses and must be either 14093 // from, release, or delete. 14094 if (DKind == OMPD_target_exit_data && 14095 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14096 MapType == OMPC_MAP_delete)) { 14097 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14098 << (IsMapTypeImplicit ? 1 : 0) 14099 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14100 << getOpenMPDirectiveName(DKind); 14101 continue; 14102 } 14103 14104 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14105 // A list item cannot appear in both a map clause and a data-sharing 14106 // attribute clause on the same construct 14107 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 14108 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14109 if (isOpenMPPrivate(DVar.CKind)) { 14110 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14111 << getOpenMPClauseName(DVar.CKind) 14112 << getOpenMPClauseName(OMPC_map) 14113 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14114 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14115 continue; 14116 } 14117 } 14118 } 14119 14120 // Try to find the associated user-defined mapper. 14121 ExprResult ER = buildUserDefinedMapperRef( 14122 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14123 Type.getCanonicalType(), UnresolvedMapper); 14124 if (ER.isInvalid()) 14125 continue; 14126 MVLI.UDMapperList.push_back(ER.get()); 14127 14128 // Save the current expression. 14129 MVLI.ProcessedVarList.push_back(RE); 14130 14131 // Store the components in the stack so that they can be used to check 14132 // against other clauses later on. 14133 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14134 /*WhereFoundClauseKind=*/OMPC_map); 14135 14136 // Save the components and declaration to create the clause. For purposes of 14137 // the clause creation, any component list that has has base 'this' uses 14138 // null as base declaration. 14139 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14140 MVLI.VarComponents.back().append(CurComponents.begin(), 14141 CurComponents.end()); 14142 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14143 : CurDeclaration); 14144 } 14145 } 14146 14147 OMPClause *Sema::ActOnOpenMPMapClause( 14148 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14149 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14150 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14151 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14152 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14153 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14154 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14155 OMPC_MAP_MODIFIER_unknown, 14156 OMPC_MAP_MODIFIER_unknown}; 14157 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14158 14159 // Process map-type-modifiers, flag errors for duplicate modifiers. 14160 unsigned Count = 0; 14161 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14162 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14163 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14164 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14165 continue; 14166 } 14167 assert(Count < OMPMapClause::NumberOfModifiers && 14168 "Modifiers exceed the allowed number of map type modifiers"); 14169 Modifiers[Count] = MapTypeModifiers[I]; 14170 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14171 ++Count; 14172 } 14173 14174 MappableVarListInfo MVLI(VarList); 14175 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14176 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14177 MapType, IsMapTypeImplicit); 14178 14179 // We need to produce a map clause even if we don't have variables so that 14180 // other diagnostics related with non-existing map clauses are accurate. 14181 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14182 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14183 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14184 MapperIdScopeSpec.getWithLocInContext(Context), 14185 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14186 } 14187 14188 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14189 TypeResult ParsedType) { 14190 assert(ParsedType.isUsable()); 14191 14192 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14193 if (ReductionType.isNull()) 14194 return QualType(); 14195 14196 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14197 // A type name in a declare reduction directive cannot be a function type, an 14198 // array type, a reference type, or a type qualified with const, volatile or 14199 // restrict. 14200 if (ReductionType.hasQualifiers()) { 14201 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14202 return QualType(); 14203 } 14204 14205 if (ReductionType->isFunctionType()) { 14206 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14207 return QualType(); 14208 } 14209 if (ReductionType->isReferenceType()) { 14210 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14211 return QualType(); 14212 } 14213 if (ReductionType->isArrayType()) { 14214 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14215 return QualType(); 14216 } 14217 return ReductionType; 14218 } 14219 14220 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14221 Scope *S, DeclContext *DC, DeclarationName Name, 14222 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14223 AccessSpecifier AS, Decl *PrevDeclInScope) { 14224 SmallVector<Decl *, 8> Decls; 14225 Decls.reserve(ReductionTypes.size()); 14226 14227 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14228 forRedeclarationInCurContext()); 14229 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14230 // A reduction-identifier may not be re-declared in the current scope for the 14231 // same type or for a type that is compatible according to the base language 14232 // rules. 14233 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14234 OMPDeclareReductionDecl *PrevDRD = nullptr; 14235 bool InCompoundScope = true; 14236 if (S != nullptr) { 14237 // Find previous declaration with the same name not referenced in other 14238 // declarations. 14239 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14240 InCompoundScope = 14241 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14242 LookupName(Lookup, S); 14243 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14244 /*AllowInlineNamespace=*/false); 14245 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14246 LookupResult::Filter Filter = Lookup.makeFilter(); 14247 while (Filter.hasNext()) { 14248 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14249 if (InCompoundScope) { 14250 auto I = UsedAsPrevious.find(PrevDecl); 14251 if (I == UsedAsPrevious.end()) 14252 UsedAsPrevious[PrevDecl] = false; 14253 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14254 UsedAsPrevious[D] = true; 14255 } 14256 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14257 PrevDecl->getLocation(); 14258 } 14259 Filter.done(); 14260 if (InCompoundScope) { 14261 for (const auto &PrevData : UsedAsPrevious) { 14262 if (!PrevData.second) { 14263 PrevDRD = PrevData.first; 14264 break; 14265 } 14266 } 14267 } 14268 } else if (PrevDeclInScope != nullptr) { 14269 auto *PrevDRDInScope = PrevDRD = 14270 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14271 do { 14272 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14273 PrevDRDInScope->getLocation(); 14274 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14275 } while (PrevDRDInScope != nullptr); 14276 } 14277 for (const auto &TyData : ReductionTypes) { 14278 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14279 bool Invalid = false; 14280 if (I != PreviousRedeclTypes.end()) { 14281 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14282 << TyData.first; 14283 Diag(I->second, diag::note_previous_definition); 14284 Invalid = true; 14285 } 14286 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14287 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14288 Name, TyData.first, PrevDRD); 14289 DC->addDecl(DRD); 14290 DRD->setAccess(AS); 14291 Decls.push_back(DRD); 14292 if (Invalid) 14293 DRD->setInvalidDecl(); 14294 else 14295 PrevDRD = DRD; 14296 } 14297 14298 return DeclGroupPtrTy::make( 14299 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14300 } 14301 14302 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14303 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14304 14305 // Enter new function scope. 14306 PushFunctionScope(); 14307 setFunctionHasBranchProtectedScope(); 14308 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14309 14310 if (S != nullptr) 14311 PushDeclContext(S, DRD); 14312 else 14313 CurContext = DRD; 14314 14315 PushExpressionEvaluationContext( 14316 ExpressionEvaluationContext::PotentiallyEvaluated); 14317 14318 QualType ReductionType = DRD->getType(); 14319 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14320 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14321 // uses semantics of argument handles by value, but it should be passed by 14322 // reference. C lang does not support references, so pass all parameters as 14323 // pointers. 14324 // Create 'T omp_in;' variable. 14325 VarDecl *OmpInParm = 14326 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14327 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14328 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14329 // uses semantics of argument handles by value, but it should be passed by 14330 // reference. C lang does not support references, so pass all parameters as 14331 // pointers. 14332 // Create 'T omp_out;' variable. 14333 VarDecl *OmpOutParm = 14334 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14335 if (S != nullptr) { 14336 PushOnScopeChains(OmpInParm, S); 14337 PushOnScopeChains(OmpOutParm, S); 14338 } else { 14339 DRD->addDecl(OmpInParm); 14340 DRD->addDecl(OmpOutParm); 14341 } 14342 Expr *InE = 14343 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14344 Expr *OutE = 14345 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14346 DRD->setCombinerData(InE, OutE); 14347 } 14348 14349 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14350 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14351 DiscardCleanupsInEvaluationContext(); 14352 PopExpressionEvaluationContext(); 14353 14354 PopDeclContext(); 14355 PopFunctionScopeInfo(); 14356 14357 if (Combiner != nullptr) 14358 DRD->setCombiner(Combiner); 14359 else 14360 DRD->setInvalidDecl(); 14361 } 14362 14363 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14364 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14365 14366 // Enter new function scope. 14367 PushFunctionScope(); 14368 setFunctionHasBranchProtectedScope(); 14369 14370 if (S != nullptr) 14371 PushDeclContext(S, DRD); 14372 else 14373 CurContext = DRD; 14374 14375 PushExpressionEvaluationContext( 14376 ExpressionEvaluationContext::PotentiallyEvaluated); 14377 14378 QualType ReductionType = DRD->getType(); 14379 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14380 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14381 // uses semantics of argument handles by value, but it should be passed by 14382 // reference. C lang does not support references, so pass all parameters as 14383 // pointers. 14384 // Create 'T omp_priv;' variable. 14385 VarDecl *OmpPrivParm = 14386 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14387 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14388 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14389 // uses semantics of argument handles by value, but it should be passed by 14390 // reference. C lang does not support references, so pass all parameters as 14391 // pointers. 14392 // Create 'T omp_orig;' variable. 14393 VarDecl *OmpOrigParm = 14394 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14395 if (S != nullptr) { 14396 PushOnScopeChains(OmpPrivParm, S); 14397 PushOnScopeChains(OmpOrigParm, S); 14398 } else { 14399 DRD->addDecl(OmpPrivParm); 14400 DRD->addDecl(OmpOrigParm); 14401 } 14402 Expr *OrigE = 14403 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14404 Expr *PrivE = 14405 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14406 DRD->setInitializerData(OrigE, PrivE); 14407 return OmpPrivParm; 14408 } 14409 14410 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14411 VarDecl *OmpPrivParm) { 14412 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14413 DiscardCleanupsInEvaluationContext(); 14414 PopExpressionEvaluationContext(); 14415 14416 PopDeclContext(); 14417 PopFunctionScopeInfo(); 14418 14419 if (Initializer != nullptr) { 14420 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14421 } else if (OmpPrivParm->hasInit()) { 14422 DRD->setInitializer(OmpPrivParm->getInit(), 14423 OmpPrivParm->isDirectInit() 14424 ? OMPDeclareReductionDecl::DirectInit 14425 : OMPDeclareReductionDecl::CopyInit); 14426 } else { 14427 DRD->setInvalidDecl(); 14428 } 14429 } 14430 14431 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14432 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14433 for (Decl *D : DeclReductions.get()) { 14434 if (IsValid) { 14435 if (S) 14436 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14437 /*AddToContext=*/false); 14438 } else { 14439 D->setInvalidDecl(); 14440 } 14441 } 14442 return DeclReductions; 14443 } 14444 14445 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14446 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14447 QualType T = TInfo->getType(); 14448 if (D.isInvalidType()) 14449 return true; 14450 14451 if (getLangOpts().CPlusPlus) { 14452 // Check that there are no default arguments (C++ only). 14453 CheckExtraCXXDefaultArguments(D); 14454 } 14455 14456 return CreateParsedType(T, TInfo); 14457 } 14458 14459 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14460 TypeResult ParsedType) { 14461 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14462 14463 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14464 assert(!MapperType.isNull() && "Expect valid mapper type"); 14465 14466 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14467 // The type must be of struct, union or class type in C and C++ 14468 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14469 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14470 return QualType(); 14471 } 14472 return MapperType; 14473 } 14474 14475 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14476 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14477 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14478 Decl *PrevDeclInScope) { 14479 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14480 forRedeclarationInCurContext()); 14481 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14482 // A mapper-identifier may not be redeclared in the current scope for the 14483 // same type or for a type that is compatible according to the base language 14484 // rules. 14485 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14486 OMPDeclareMapperDecl *PrevDMD = nullptr; 14487 bool InCompoundScope = true; 14488 if (S != nullptr) { 14489 // Find previous declaration with the same name not referenced in other 14490 // declarations. 14491 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14492 InCompoundScope = 14493 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14494 LookupName(Lookup, S); 14495 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14496 /*AllowInlineNamespace=*/false); 14497 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14498 LookupResult::Filter Filter = Lookup.makeFilter(); 14499 while (Filter.hasNext()) { 14500 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14501 if (InCompoundScope) { 14502 auto I = UsedAsPrevious.find(PrevDecl); 14503 if (I == UsedAsPrevious.end()) 14504 UsedAsPrevious[PrevDecl] = false; 14505 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14506 UsedAsPrevious[D] = true; 14507 } 14508 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14509 PrevDecl->getLocation(); 14510 } 14511 Filter.done(); 14512 if (InCompoundScope) { 14513 for (const auto &PrevData : UsedAsPrevious) { 14514 if (!PrevData.second) { 14515 PrevDMD = PrevData.first; 14516 break; 14517 } 14518 } 14519 } 14520 } else if (PrevDeclInScope) { 14521 auto *PrevDMDInScope = PrevDMD = 14522 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14523 do { 14524 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14525 PrevDMDInScope->getLocation(); 14526 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14527 } while (PrevDMDInScope != nullptr); 14528 } 14529 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14530 bool Invalid = false; 14531 if (I != PreviousRedeclTypes.end()) { 14532 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14533 << MapperType << Name; 14534 Diag(I->second, diag::note_previous_definition); 14535 Invalid = true; 14536 } 14537 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14538 MapperType, VN, PrevDMD); 14539 DC->addDecl(DMD); 14540 DMD->setAccess(AS); 14541 if (Invalid) 14542 DMD->setInvalidDecl(); 14543 14544 // Enter new function scope. 14545 PushFunctionScope(); 14546 setFunctionHasBranchProtectedScope(); 14547 14548 CurContext = DMD; 14549 14550 return DMD; 14551 } 14552 14553 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14554 Scope *S, 14555 QualType MapperType, 14556 SourceLocation StartLoc, 14557 DeclarationName VN) { 14558 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14559 if (S) 14560 PushOnScopeChains(VD, S); 14561 else 14562 DMD->addDecl(VD); 14563 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14564 DMD->setMapperVarRef(MapperVarRefExpr); 14565 } 14566 14567 Sema::DeclGroupPtrTy 14568 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14569 ArrayRef<OMPClause *> ClauseList) { 14570 PopDeclContext(); 14571 PopFunctionScopeInfo(); 14572 14573 if (D) { 14574 if (S) 14575 PushOnScopeChains(D, S, /*AddToContext=*/false); 14576 D->CreateClauses(Context, ClauseList); 14577 } 14578 14579 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14580 } 14581 14582 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14583 SourceLocation StartLoc, 14584 SourceLocation LParenLoc, 14585 SourceLocation EndLoc) { 14586 Expr *ValExpr = NumTeams; 14587 Stmt *HelperValStmt = nullptr; 14588 14589 // OpenMP [teams Constrcut, Restrictions] 14590 // The num_teams expression must evaluate to a positive integer value. 14591 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14592 /*StrictlyPositive=*/true)) 14593 return nullptr; 14594 14595 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14596 OpenMPDirectiveKind CaptureRegion = 14597 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14598 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14599 ValExpr = MakeFullExpr(ValExpr).get(); 14600 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14601 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14602 HelperValStmt = buildPreInits(Context, Captures); 14603 } 14604 14605 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14606 StartLoc, LParenLoc, EndLoc); 14607 } 14608 14609 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14610 SourceLocation StartLoc, 14611 SourceLocation LParenLoc, 14612 SourceLocation EndLoc) { 14613 Expr *ValExpr = ThreadLimit; 14614 Stmt *HelperValStmt = nullptr; 14615 14616 // OpenMP [teams Constrcut, Restrictions] 14617 // The thread_limit expression must evaluate to a positive integer value. 14618 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14619 /*StrictlyPositive=*/true)) 14620 return nullptr; 14621 14622 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14623 OpenMPDirectiveKind CaptureRegion = 14624 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14625 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14626 ValExpr = MakeFullExpr(ValExpr).get(); 14627 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14628 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14629 HelperValStmt = buildPreInits(Context, Captures); 14630 } 14631 14632 return new (Context) OMPThreadLimitClause( 14633 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14634 } 14635 14636 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14637 SourceLocation StartLoc, 14638 SourceLocation LParenLoc, 14639 SourceLocation EndLoc) { 14640 Expr *ValExpr = Priority; 14641 14642 // OpenMP [2.9.1, task Constrcut] 14643 // The priority-value is a non-negative numerical scalar expression. 14644 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14645 /*StrictlyPositive=*/false)) 14646 return nullptr; 14647 14648 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14649 } 14650 14651 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14652 SourceLocation StartLoc, 14653 SourceLocation LParenLoc, 14654 SourceLocation EndLoc) { 14655 Expr *ValExpr = Grainsize; 14656 14657 // OpenMP [2.9.2, taskloop Constrcut] 14658 // The parameter of the grainsize clause must be a positive integer 14659 // expression. 14660 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14661 /*StrictlyPositive=*/true)) 14662 return nullptr; 14663 14664 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14665 } 14666 14667 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14668 SourceLocation StartLoc, 14669 SourceLocation LParenLoc, 14670 SourceLocation EndLoc) { 14671 Expr *ValExpr = NumTasks; 14672 14673 // OpenMP [2.9.2, taskloop Constrcut] 14674 // The parameter of the num_tasks clause must be a positive integer 14675 // expression. 14676 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14677 /*StrictlyPositive=*/true)) 14678 return nullptr; 14679 14680 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14681 } 14682 14683 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14684 SourceLocation LParenLoc, 14685 SourceLocation EndLoc) { 14686 // OpenMP [2.13.2, critical construct, Description] 14687 // ... where hint-expression is an integer constant expression that evaluates 14688 // to a valid lock hint. 14689 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14690 if (HintExpr.isInvalid()) 14691 return nullptr; 14692 return new (Context) 14693 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14694 } 14695 14696 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14697 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14698 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14699 SourceLocation EndLoc) { 14700 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14701 std::string Values; 14702 Values += "'"; 14703 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14704 Values += "'"; 14705 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14706 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14707 return nullptr; 14708 } 14709 Expr *ValExpr = ChunkSize; 14710 Stmt *HelperValStmt = nullptr; 14711 if (ChunkSize) { 14712 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14713 !ChunkSize->isInstantiationDependent() && 14714 !ChunkSize->containsUnexpandedParameterPack()) { 14715 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14716 ExprResult Val = 14717 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14718 if (Val.isInvalid()) 14719 return nullptr; 14720 14721 ValExpr = Val.get(); 14722 14723 // OpenMP [2.7.1, Restrictions] 14724 // chunk_size must be a loop invariant integer expression with a positive 14725 // value. 14726 llvm::APSInt Result; 14727 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14728 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14729 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14730 << "dist_schedule" << ChunkSize->getSourceRange(); 14731 return nullptr; 14732 } 14733 } else if (getOpenMPCaptureRegionForClause( 14734 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14735 OMPD_unknown && 14736 !CurContext->isDependentContext()) { 14737 ValExpr = MakeFullExpr(ValExpr).get(); 14738 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14739 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14740 HelperValStmt = buildPreInits(Context, Captures); 14741 } 14742 } 14743 } 14744 14745 return new (Context) 14746 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14747 Kind, ValExpr, HelperValStmt); 14748 } 14749 14750 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14751 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14752 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14753 SourceLocation KindLoc, SourceLocation EndLoc) { 14754 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14755 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14756 std::string Value; 14757 SourceLocation Loc; 14758 Value += "'"; 14759 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14760 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14761 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14762 Loc = MLoc; 14763 } else { 14764 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14765 OMPC_DEFAULTMAP_scalar); 14766 Loc = KindLoc; 14767 } 14768 Value += "'"; 14769 Diag(Loc, diag::err_omp_unexpected_clause_value) 14770 << Value << getOpenMPClauseName(OMPC_defaultmap); 14771 return nullptr; 14772 } 14773 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14774 14775 return new (Context) 14776 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14777 } 14778 14779 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14780 DeclContext *CurLexicalContext = getCurLexicalContext(); 14781 if (!CurLexicalContext->isFileContext() && 14782 !CurLexicalContext->isExternCContext() && 14783 !CurLexicalContext->isExternCXXContext() && 14784 !isa<CXXRecordDecl>(CurLexicalContext) && 14785 !isa<ClassTemplateDecl>(CurLexicalContext) && 14786 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14787 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14788 Diag(Loc, diag::err_omp_region_not_file_context); 14789 return false; 14790 } 14791 ++DeclareTargetNestingLevel; 14792 return true; 14793 } 14794 14795 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14796 assert(DeclareTargetNestingLevel > 0 && 14797 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14798 --DeclareTargetNestingLevel; 14799 } 14800 14801 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14802 CXXScopeSpec &ScopeSpec, 14803 const DeclarationNameInfo &Id, 14804 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14805 NamedDeclSetType &SameDirectiveDecls) { 14806 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14807 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14808 14809 if (Lookup.isAmbiguous()) 14810 return; 14811 Lookup.suppressDiagnostics(); 14812 14813 if (!Lookup.isSingleResult()) { 14814 VarOrFuncDeclFilterCCC CCC(*this); 14815 if (TypoCorrection Corrected = 14816 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 14817 CTK_ErrorRecovery)) { 14818 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14819 << Id.getName()); 14820 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14821 return; 14822 } 14823 14824 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14825 return; 14826 } 14827 14828 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14829 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14830 isa<FunctionTemplateDecl>(ND)) { 14831 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14832 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14833 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14834 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14835 cast<ValueDecl>(ND)); 14836 if (!Res) { 14837 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14838 ND->addAttr(A); 14839 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14840 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14841 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14842 } else if (*Res != MT) { 14843 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14844 << Id.getName(); 14845 } 14846 } else { 14847 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14848 } 14849 } 14850 14851 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14852 Sema &SemaRef, Decl *D) { 14853 if (!D || !isa<VarDecl>(D)) 14854 return; 14855 auto *VD = cast<VarDecl>(D); 14856 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14857 return; 14858 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14859 SemaRef.Diag(SL, diag::note_used_here) << SR; 14860 } 14861 14862 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14863 Sema &SemaRef, DSAStackTy *Stack, 14864 ValueDecl *VD) { 14865 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14866 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14867 /*FullCheck=*/false); 14868 } 14869 14870 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14871 SourceLocation IdLoc) { 14872 if (!D || D->isInvalidDecl()) 14873 return; 14874 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14875 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14876 if (auto *VD = dyn_cast<VarDecl>(D)) { 14877 // Only global variables can be marked as declare target. 14878 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14879 !VD->isStaticDataMember()) 14880 return; 14881 // 2.10.6: threadprivate variable cannot appear in a declare target 14882 // directive. 14883 if (DSAStack->isThreadPrivate(VD)) { 14884 Diag(SL, diag::err_omp_threadprivate_in_target); 14885 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14886 return; 14887 } 14888 } 14889 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14890 D = FTD->getTemplatedDecl(); 14891 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14892 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14893 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14894 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14895 assert(IdLoc.isValid() && "Source location is expected"); 14896 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14897 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14898 return; 14899 } 14900 } 14901 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14902 // Problem if any with var declared with incomplete type will be reported 14903 // as normal, so no need to check it here. 14904 if ((E || !VD->getType()->isIncompleteType()) && 14905 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14906 return; 14907 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14908 // Checking declaration inside declare target region. 14909 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14910 isa<FunctionTemplateDecl>(D)) { 14911 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14912 Context, OMPDeclareTargetDeclAttr::MT_To); 14913 D->addAttr(A); 14914 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14915 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14916 } 14917 return; 14918 } 14919 } 14920 if (!E) 14921 return; 14922 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 14923 } 14924 14925 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 14926 CXXScopeSpec &MapperIdScopeSpec, 14927 DeclarationNameInfo &MapperId, 14928 const OMPVarListLocTy &Locs, 14929 ArrayRef<Expr *> UnresolvedMappers) { 14930 MappableVarListInfo MVLI(VarList); 14931 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 14932 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14933 if (MVLI.ProcessedVarList.empty()) 14934 return nullptr; 14935 14936 return OMPToClause::Create( 14937 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14938 MVLI.VarComponents, MVLI.UDMapperList, 14939 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14940 } 14941 14942 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 14943 CXXScopeSpec &MapperIdScopeSpec, 14944 DeclarationNameInfo &MapperId, 14945 const OMPVarListLocTy &Locs, 14946 ArrayRef<Expr *> UnresolvedMappers) { 14947 MappableVarListInfo MVLI(VarList); 14948 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 14949 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14950 if (MVLI.ProcessedVarList.empty()) 14951 return nullptr; 14952 14953 return OMPFromClause::Create( 14954 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14955 MVLI.VarComponents, MVLI.UDMapperList, 14956 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14957 } 14958 14959 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 14960 const OMPVarListLocTy &Locs) { 14961 MappableVarListInfo MVLI(VarList); 14962 SmallVector<Expr *, 8> PrivateCopies; 14963 SmallVector<Expr *, 8> Inits; 14964 14965 for (Expr *RefExpr : VarList) { 14966 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 14967 SourceLocation ELoc; 14968 SourceRange ERange; 14969 Expr *SimpleRefExpr = RefExpr; 14970 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14971 if (Res.second) { 14972 // It will be analyzed later. 14973 MVLI.ProcessedVarList.push_back(RefExpr); 14974 PrivateCopies.push_back(nullptr); 14975 Inits.push_back(nullptr); 14976 } 14977 ValueDecl *D = Res.first; 14978 if (!D) 14979 continue; 14980 14981 QualType Type = D->getType(); 14982 Type = Type.getNonReferenceType().getUnqualifiedType(); 14983 14984 auto *VD = dyn_cast<VarDecl>(D); 14985 14986 // Item should be a pointer or reference to pointer. 14987 if (!Type->isPointerType()) { 14988 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 14989 << 0 << RefExpr->getSourceRange(); 14990 continue; 14991 } 14992 14993 // Build the private variable and the expression that refers to it. 14994 auto VDPrivate = 14995 buildVarDecl(*this, ELoc, Type, D->getName(), 14996 D->hasAttrs() ? &D->getAttrs() : nullptr, 14997 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14998 if (VDPrivate->isInvalidDecl()) 14999 continue; 15000 15001 CurContext->addDecl(VDPrivate); 15002 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15003 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15004 15005 // Add temporary variable to initialize the private copy of the pointer. 15006 VarDecl *VDInit = 15007 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15008 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15009 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15010 AddInitializerToDecl(VDPrivate, 15011 DefaultLvalueConversion(VDInitRefExpr).get(), 15012 /*DirectInit=*/false); 15013 15014 // If required, build a capture to implement the privatization initialized 15015 // with the current list item value. 15016 DeclRefExpr *Ref = nullptr; 15017 if (!VD) 15018 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15019 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15020 PrivateCopies.push_back(VDPrivateRefExpr); 15021 Inits.push_back(VDInitRefExpr); 15022 15023 // We need to add a data sharing attribute for this variable to make sure it 15024 // is correctly captured. A variable that shows up in a use_device_ptr has 15025 // similar properties of a first private variable. 15026 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15027 15028 // Create a mappable component for the list item. List items in this clause 15029 // only need a component. 15030 MVLI.VarBaseDeclarations.push_back(D); 15031 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15032 MVLI.VarComponents.back().push_back( 15033 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15034 } 15035 15036 if (MVLI.ProcessedVarList.empty()) 15037 return nullptr; 15038 15039 return OMPUseDevicePtrClause::Create( 15040 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15041 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15042 } 15043 15044 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15045 const OMPVarListLocTy &Locs) { 15046 MappableVarListInfo MVLI(VarList); 15047 for (Expr *RefExpr : VarList) { 15048 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15049 SourceLocation ELoc; 15050 SourceRange ERange; 15051 Expr *SimpleRefExpr = RefExpr; 15052 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15053 if (Res.second) { 15054 // It will be analyzed later. 15055 MVLI.ProcessedVarList.push_back(RefExpr); 15056 } 15057 ValueDecl *D = Res.first; 15058 if (!D) 15059 continue; 15060 15061 QualType Type = D->getType(); 15062 // item should be a pointer or array or reference to pointer or array 15063 if (!Type.getNonReferenceType()->isPointerType() && 15064 !Type.getNonReferenceType()->isArrayType()) { 15065 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15066 << 0 << RefExpr->getSourceRange(); 15067 continue; 15068 } 15069 15070 // Check if the declaration in the clause does not show up in any data 15071 // sharing attribute. 15072 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15073 if (isOpenMPPrivate(DVar.CKind)) { 15074 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15075 << getOpenMPClauseName(DVar.CKind) 15076 << getOpenMPClauseName(OMPC_is_device_ptr) 15077 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15078 reportOriginalDsa(*this, DSAStack, D, DVar); 15079 continue; 15080 } 15081 15082 const Expr *ConflictExpr; 15083 if (DSAStack->checkMappableExprComponentListsForDecl( 15084 D, /*CurrentRegionOnly=*/true, 15085 [&ConflictExpr]( 15086 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15087 OpenMPClauseKind) -> bool { 15088 ConflictExpr = R.front().getAssociatedExpression(); 15089 return true; 15090 })) { 15091 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15092 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15093 << ConflictExpr->getSourceRange(); 15094 continue; 15095 } 15096 15097 // Store the components in the stack so that they can be used to check 15098 // against other clauses later on. 15099 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15100 DSAStack->addMappableExpressionComponents( 15101 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15102 15103 // Record the expression we've just processed. 15104 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15105 15106 // Create a mappable component for the list item. List items in this clause 15107 // only need a component. We use a null declaration to signal fields in 15108 // 'this'. 15109 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15110 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15111 "Unexpected device pointer expression!"); 15112 MVLI.VarBaseDeclarations.push_back( 15113 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15114 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15115 MVLI.VarComponents.back().push_back(MC); 15116 } 15117 15118 if (MVLI.ProcessedVarList.empty()) 15119 return nullptr; 15120 15121 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15122 MVLI.VarBaseDeclarations, 15123 MVLI.VarComponents); 15124 } 15125 15126 OMPClause *Sema::ActOnOpenMPAllocateClause( 15127 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15128 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15129 if (Allocator) { 15130 // OpenMP [2.11.4 allocate Clause, Description] 15131 // allocator is an expression of omp_allocator_handle_t type. 15132 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15133 return nullptr; 15134 15135 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15136 if (AllocatorRes.isInvalid()) 15137 return nullptr; 15138 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15139 DSAStack->getOMPAllocatorHandleT(), 15140 Sema::AA_Initializing, 15141 /*AllowExplicit=*/true); 15142 if (AllocatorRes.isInvalid()) 15143 return nullptr; 15144 Allocator = AllocatorRes.get(); 15145 } else { 15146 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15147 // allocate clauses that appear on a target construct or on constructs in a 15148 // target region must specify an allocator expression unless a requires 15149 // directive with the dynamic_allocators clause is present in the same 15150 // compilation unit. 15151 if (LangOpts.OpenMPIsDevice && 15152 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15153 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15154 } 15155 // Analyze and build list of variables. 15156 SmallVector<Expr *, 8> Vars; 15157 for (Expr *RefExpr : VarList) { 15158 assert(RefExpr && "NULL expr in OpenMP private clause."); 15159 SourceLocation ELoc; 15160 SourceRange ERange; 15161 Expr *SimpleRefExpr = RefExpr; 15162 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15163 if (Res.second) { 15164 // It will be analyzed later. 15165 Vars.push_back(RefExpr); 15166 } 15167 ValueDecl *D = Res.first; 15168 if (!D) 15169 continue; 15170 15171 auto *VD = dyn_cast<VarDecl>(D); 15172 DeclRefExpr *Ref = nullptr; 15173 if (!VD && !CurContext->isDependentContext()) 15174 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15175 Vars.push_back((VD || CurContext->isDependentContext()) 15176 ? RefExpr->IgnoreParens() 15177 : Ref); 15178 } 15179 15180 if (Vars.empty()) 15181 return nullptr; 15182 15183 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15184 ColonLoc, EndLoc, Vars); 15185 } 15186