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/Basic/PartialDiagnostic.h" 27 #include "clang/Sema/Initialization.h" 28 #include "clang/Sema/Lookup.h" 29 #include "clang/Sema/Scope.h" 30 #include "clang/Sema/ScopeInfo.h" 31 #include "clang/Sema/SemaInternal.h" 32 #include "llvm/ADT/IndexedMap.h" 33 #include "llvm/ADT/PointerEmbeddedInt.h" 34 #include "llvm/Frontend/OpenMP/OMPConstants.h" 35 using namespace clang; 36 using namespace llvm::omp; 37 38 //===----------------------------------------------------------------------===// 39 // Stack of data-sharing attributes for variables 40 //===----------------------------------------------------------------------===// 41 42 static const Expr *checkMapClauseExpressionBase( 43 Sema &SemaRef, Expr *E, 44 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 45 OpenMPClauseKind CKind, bool NoDiagnose); 46 47 namespace { 48 /// Default data sharing attributes, which can be applied to directive. 49 enum DefaultDataSharingAttributes { 50 DSA_unspecified = 0, /// Data sharing attribute not specified. 51 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 52 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 53 }; 54 55 /// Stack for tracking declarations used in OpenMP directives and 56 /// clauses and their data-sharing attributes. 57 class DSAStackTy { 58 public: 59 struct DSAVarData { 60 OpenMPDirectiveKind DKind = OMPD_unknown; 61 OpenMPClauseKind CKind = OMPC_unknown; 62 const Expr *RefExpr = nullptr; 63 DeclRefExpr *PrivateCopy = nullptr; 64 SourceLocation ImplicitDSALoc; 65 DSAVarData() = default; 66 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 67 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 68 SourceLocation ImplicitDSALoc) 69 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 70 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 71 }; 72 using OperatorOffsetTy = 73 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 74 using DoacrossDependMapTy = 75 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 76 77 private: 78 struct DSAInfo { 79 OpenMPClauseKind Attributes = OMPC_unknown; 80 /// Pointer to a reference expression and a flag which shows that the 81 /// variable is marked as lastprivate(true) or not (false). 82 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 83 DeclRefExpr *PrivateCopy = nullptr; 84 }; 85 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 86 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 87 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 88 using LoopControlVariablesMapTy = 89 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 90 /// Struct that associates a component with the clause kind where they are 91 /// found. 92 struct MappedExprComponentTy { 93 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 94 OpenMPClauseKind Kind = OMPC_unknown; 95 }; 96 using MappedExprComponentsTy = 97 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 98 using CriticalsWithHintsTy = 99 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 100 struct ReductionData { 101 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 102 SourceRange ReductionRange; 103 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 104 ReductionData() = default; 105 void set(BinaryOperatorKind BO, SourceRange RR) { 106 ReductionRange = RR; 107 ReductionOp = BO; 108 } 109 void set(const Expr *RefExpr, SourceRange RR) { 110 ReductionRange = RR; 111 ReductionOp = RefExpr; 112 } 113 }; 114 using DeclReductionMapTy = 115 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 116 struct DefaultmapInfo { 117 OpenMPDefaultmapClauseModifier ImplicitBehavior = 118 OMPC_DEFAULTMAP_MODIFIER_unknown; 119 SourceLocation SLoc; 120 DefaultmapInfo() = default; 121 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 122 : ImplicitBehavior(M), SLoc(Loc) {} 123 }; 124 125 struct SharingMapTy { 126 DeclSAMapTy SharingMap; 127 DeclReductionMapTy ReductionMap; 128 UsedRefMapTy AlignedMap; 129 UsedRefMapTy NontemporalMap; 130 MappedExprComponentsTy MappedExprComponents; 131 LoopControlVariablesMapTy LCVMap; 132 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 133 SourceLocation DefaultAttrLoc; 134 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 135 OpenMPDirectiveKind Directive = OMPD_unknown; 136 DeclarationNameInfo DirectiveName; 137 Scope *CurScope = nullptr; 138 SourceLocation ConstructLoc; 139 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 140 /// get the data (loop counters etc.) about enclosing loop-based construct. 141 /// This data is required during codegen. 142 DoacrossDependMapTy DoacrossDepends; 143 /// First argument (Expr *) contains optional argument of the 144 /// 'ordered' clause, the second one is true if the regions has 'ordered' 145 /// clause, false otherwise. 146 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 147 unsigned AssociatedLoops = 1; 148 bool HasMutipleLoops = false; 149 const Decl *PossiblyLoopCounter = nullptr; 150 bool NowaitRegion = false; 151 bool CancelRegion = false; 152 bool LoopStart = false; 153 bool BodyComplete = false; 154 SourceLocation InnerTeamsRegionLoc; 155 /// Reference to the taskgroup task_reduction reference expression. 156 Expr *TaskgroupReductionRef = nullptr; 157 llvm::DenseSet<QualType> MappedClassesQualTypes; 158 /// List of globals marked as declare target link in this target region 159 /// (isOpenMPTargetExecutionDirective(Directive) == true). 160 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 161 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 162 Scope *CurScope, SourceLocation Loc) 163 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 164 ConstructLoc(Loc) {} 165 SharingMapTy() = default; 166 }; 167 168 using StackTy = SmallVector<SharingMapTy, 4>; 169 170 /// Stack of used declaration and their data-sharing attributes. 171 DeclSAMapTy Threadprivates; 172 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 173 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 174 /// true, if check for DSA must be from parent directive, false, if 175 /// from current directive. 176 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 177 Sema &SemaRef; 178 bool ForceCapturing = false; 179 /// true if all the variables in the target executable directives must be 180 /// captured by reference. 181 bool ForceCaptureByReferenceInTargetExecutable = false; 182 CriticalsWithHintsTy Criticals; 183 unsigned IgnoredStackElements = 0; 184 185 /// Iterators over the stack iterate in order from innermost to outermost 186 /// directive. 187 using const_iterator = StackTy::const_reverse_iterator; 188 const_iterator begin() const { 189 return Stack.empty() ? const_iterator() 190 : Stack.back().first.rbegin() + IgnoredStackElements; 191 } 192 const_iterator end() const { 193 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 194 } 195 using iterator = StackTy::reverse_iterator; 196 iterator begin() { 197 return Stack.empty() ? iterator() 198 : Stack.back().first.rbegin() + IgnoredStackElements; 199 } 200 iterator end() { 201 return Stack.empty() ? iterator() : Stack.back().first.rend(); 202 } 203 204 // Convenience operations to get at the elements of the stack. 205 206 bool isStackEmpty() const { 207 return Stack.empty() || 208 Stack.back().second != CurrentNonCapturingFunctionScope || 209 Stack.back().first.size() <= IgnoredStackElements; 210 } 211 size_t getStackSize() const { 212 return isStackEmpty() ? 0 213 : Stack.back().first.size() - IgnoredStackElements; 214 } 215 216 SharingMapTy *getTopOfStackOrNull() { 217 size_t Size = getStackSize(); 218 if (Size == 0) 219 return nullptr; 220 return &Stack.back().first[Size - 1]; 221 } 222 const SharingMapTy *getTopOfStackOrNull() const { 223 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 224 } 225 SharingMapTy &getTopOfStack() { 226 assert(!isStackEmpty() && "no current directive"); 227 return *getTopOfStackOrNull(); 228 } 229 const SharingMapTy &getTopOfStack() const { 230 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 231 } 232 233 SharingMapTy *getSecondOnStackOrNull() { 234 size_t Size = getStackSize(); 235 if (Size <= 1) 236 return nullptr; 237 return &Stack.back().first[Size - 2]; 238 } 239 const SharingMapTy *getSecondOnStackOrNull() const { 240 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 241 } 242 243 /// Get the stack element at a certain level (previously returned by 244 /// \c getNestingLevel). 245 /// 246 /// Note that nesting levels count from outermost to innermost, and this is 247 /// the reverse of our iteration order where new inner levels are pushed at 248 /// the front of the stack. 249 SharingMapTy &getStackElemAtLevel(unsigned Level) { 250 assert(Level < getStackSize() && "no such stack element"); 251 return Stack.back().first[Level]; 252 } 253 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 254 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 255 } 256 257 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 258 259 /// Checks if the variable is a local for OpenMP region. 260 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 261 262 /// Vector of previously declared requires directives 263 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 264 /// omp_allocator_handle_t type. 265 QualType OMPAllocatorHandleT; 266 /// Expression for the predefined allocators. 267 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 268 nullptr}; 269 /// Vector of previously encountered target directives 270 SmallVector<SourceLocation, 2> TargetLocations; 271 272 public: 273 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 274 275 /// Sets omp_allocator_handle_t type. 276 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 277 /// Gets omp_allocator_handle_t type. 278 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 279 /// Sets the given default allocator. 280 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 281 Expr *Allocator) { 282 OMPPredefinedAllocators[AllocatorKind] = Allocator; 283 } 284 /// Returns the specified default allocator. 285 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 286 return OMPPredefinedAllocators[AllocatorKind]; 287 } 288 289 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 290 OpenMPClauseKind getClauseParsingMode() const { 291 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 292 return ClauseKindMode; 293 } 294 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 295 296 bool isBodyComplete() const { 297 const SharingMapTy *Top = getTopOfStackOrNull(); 298 return Top && Top->BodyComplete; 299 } 300 void setBodyComplete() { 301 getTopOfStack().BodyComplete = true; 302 } 303 304 bool isForceVarCapturing() const { return ForceCapturing; } 305 void setForceVarCapturing(bool V) { ForceCapturing = V; } 306 307 void setForceCaptureByReferenceInTargetExecutable(bool V) { 308 ForceCaptureByReferenceInTargetExecutable = V; 309 } 310 bool isForceCaptureByReferenceInTargetExecutable() const { 311 return ForceCaptureByReferenceInTargetExecutable; 312 } 313 314 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 315 Scope *CurScope, SourceLocation Loc) { 316 assert(!IgnoredStackElements && 317 "cannot change stack while ignoring elements"); 318 if (Stack.empty() || 319 Stack.back().second != CurrentNonCapturingFunctionScope) 320 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 321 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 322 Stack.back().first.back().DefaultAttrLoc = Loc; 323 } 324 325 void pop() { 326 assert(!IgnoredStackElements && 327 "cannot change stack while ignoring elements"); 328 assert(!Stack.back().first.empty() && 329 "Data-sharing attributes stack is empty!"); 330 Stack.back().first.pop_back(); 331 } 332 333 /// RAII object to temporarily leave the scope of a directive when we want to 334 /// logically operate in its parent. 335 class ParentDirectiveScope { 336 DSAStackTy &Self; 337 bool Active; 338 public: 339 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 340 : Self(Self), Active(false) { 341 if (Activate) 342 enable(); 343 } 344 ~ParentDirectiveScope() { disable(); } 345 void disable() { 346 if (Active) { 347 --Self.IgnoredStackElements; 348 Active = false; 349 } 350 } 351 void enable() { 352 if (!Active) { 353 ++Self.IgnoredStackElements; 354 Active = true; 355 } 356 } 357 }; 358 359 /// Marks that we're started loop parsing. 360 void loopInit() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = true; 364 } 365 /// Start capturing of the variables in the loop context. 366 void loopStart() { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 getTopOfStack().LoopStart = false; 370 } 371 /// true, if variables are captured, false otherwise. 372 bool isLoopStarted() const { 373 assert(isOpenMPLoopDirective(getCurrentDirective()) && 374 "Expected loop-based directive."); 375 return !getTopOfStack().LoopStart; 376 } 377 /// Marks (or clears) declaration as possibly loop counter. 378 void resetPossibleLoopCounter(const Decl *D = nullptr) { 379 getTopOfStack().PossiblyLoopCounter = 380 D ? D->getCanonicalDecl() : D; 381 } 382 /// Gets the possible loop counter decl. 383 const Decl *getPossiblyLoopCunter() const { 384 return getTopOfStack().PossiblyLoopCounter; 385 } 386 /// Start new OpenMP region stack in new non-capturing function. 387 void pushFunction() { 388 assert(!IgnoredStackElements && 389 "cannot change stack while ignoring elements"); 390 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 391 assert(!isa<CapturingScopeInfo>(CurFnScope)); 392 CurrentNonCapturingFunctionScope = CurFnScope; 393 } 394 /// Pop region stack for non-capturing function. 395 void popFunction(const FunctionScopeInfo *OldFSI) { 396 assert(!IgnoredStackElements && 397 "cannot change stack while ignoring elements"); 398 if (!Stack.empty() && Stack.back().second == OldFSI) { 399 assert(Stack.back().first.empty()); 400 Stack.pop_back(); 401 } 402 CurrentNonCapturingFunctionScope = nullptr; 403 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 404 if (!isa<CapturingScopeInfo>(FSI)) { 405 CurrentNonCapturingFunctionScope = FSI; 406 break; 407 } 408 } 409 } 410 411 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 412 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 413 } 414 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 415 getCriticalWithHint(const DeclarationNameInfo &Name) const { 416 auto I = Criticals.find(Name.getAsString()); 417 if (I != Criticals.end()) 418 return I->second; 419 return std::make_pair(nullptr, llvm::APSInt()); 420 } 421 /// If 'aligned' declaration for given variable \a D was not seen yet, 422 /// add it and return NULL; otherwise return previous occurrence's expression 423 /// for diagnostics. 424 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 425 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 426 /// add it and return NULL; otherwise return previous occurrence's expression 427 /// for diagnostics. 428 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 429 430 /// Register specified variable as loop control variable. 431 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 432 /// Check if the specified variable is a loop control variable for 433 /// current region. 434 /// \return The index of the loop control variable in the list of associated 435 /// for-loops (from outer to inner). 436 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 437 /// Check if the specified variable is a loop control variable for 438 /// parent region. 439 /// \return The index of the loop control variable in the list of associated 440 /// for-loops (from outer to inner). 441 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 442 /// Get the loop control variable for the I-th loop (or nullptr) in 443 /// parent directive. 444 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 445 446 /// Adds explicit data sharing attribute to the specified declaration. 447 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 448 DeclRefExpr *PrivateCopy = nullptr); 449 450 /// Adds additional information for the reduction items with the reduction id 451 /// represented as an operator. 452 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 453 BinaryOperatorKind BOK); 454 /// Adds additional information for the reduction items with the reduction id 455 /// represented as reduction identifier. 456 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 457 const Expr *ReductionRef); 458 /// Returns the location and reduction operation from the innermost parent 459 /// region for the given \p D. 460 const DSAVarData 461 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 462 BinaryOperatorKind &BOK, 463 Expr *&TaskgroupDescriptor) const; 464 /// Returns the location and reduction operation from the innermost parent 465 /// region for the given \p D. 466 const DSAVarData 467 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 468 const Expr *&ReductionRef, 469 Expr *&TaskgroupDescriptor) const; 470 /// Return reduction reference expression for the current taskgroup. 471 Expr *getTaskgroupReductionRef() const { 472 assert(getTopOfStack().Directive == OMPD_taskgroup && 473 "taskgroup reference expression requested for non taskgroup " 474 "directive."); 475 return getTopOfStack().TaskgroupReductionRef; 476 } 477 /// Checks if the given \p VD declaration is actually a taskgroup reduction 478 /// descriptor variable at the \p Level of OpenMP regions. 479 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 480 return getStackElemAtLevel(Level).TaskgroupReductionRef && 481 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 482 ->getDecl() == VD; 483 } 484 485 /// Returns data sharing attributes from top of the stack for the 486 /// specified declaration. 487 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 488 /// Returns data-sharing attributes for the specified declaration. 489 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 490 /// Checks if the specified variables has data-sharing attributes which 491 /// match specified \a CPred predicate in any directive which matches \a DPred 492 /// predicate. 493 const DSAVarData 494 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 495 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 496 bool FromParent) const; 497 /// Checks if the specified variables has data-sharing attributes which 498 /// match specified \a CPred predicate in any innermost directive which 499 /// matches \a DPred predicate. 500 const DSAVarData 501 hasInnermostDSA(ValueDecl *D, 502 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 503 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 504 bool FromParent) const; 505 /// Checks if the specified variables has explicit data-sharing 506 /// attributes which match specified \a CPred predicate at the specified 507 /// OpenMP region. 508 bool hasExplicitDSA(const ValueDecl *D, 509 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 510 unsigned Level, bool NotLastprivate = false) const; 511 512 /// Returns true if the directive at level \Level matches in the 513 /// specified \a DPred predicate. 514 bool hasExplicitDirective( 515 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 516 unsigned Level) const; 517 518 /// Finds a directive which matches specified \a DPred predicate. 519 bool hasDirective( 520 const llvm::function_ref<bool( 521 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 522 DPred, 523 bool FromParent) const; 524 525 /// Returns currently analyzed directive. 526 OpenMPDirectiveKind getCurrentDirective() const { 527 const SharingMapTy *Top = getTopOfStackOrNull(); 528 return Top ? Top->Directive : OMPD_unknown; 529 } 530 /// Returns directive kind at specified level. 531 OpenMPDirectiveKind getDirective(unsigned Level) const { 532 assert(!isStackEmpty() && "No directive at specified level."); 533 return getStackElemAtLevel(Level).Directive; 534 } 535 /// Returns the capture region at the specified level. 536 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 537 unsigned OpenMPCaptureLevel) const { 538 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 539 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 540 return CaptureRegions[OpenMPCaptureLevel]; 541 } 542 /// Returns parent directive. 543 OpenMPDirectiveKind getParentDirective() const { 544 const SharingMapTy *Parent = getSecondOnStackOrNull(); 545 return Parent ? Parent->Directive : OMPD_unknown; 546 } 547 548 /// Add requires decl to internal vector 549 void addRequiresDecl(OMPRequiresDecl *RD) { 550 RequiresDecls.push_back(RD); 551 } 552 553 /// Checks if the defined 'requires' directive has specified type of clause. 554 template <typename ClauseType> 555 bool hasRequiresDeclWithClause() { 556 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 557 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 558 return isa<ClauseType>(C); 559 }); 560 }); 561 } 562 563 /// Checks for a duplicate clause amongst previously declared requires 564 /// directives 565 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 566 bool IsDuplicate = false; 567 for (OMPClause *CNew : ClauseList) { 568 for (const OMPRequiresDecl *D : RequiresDecls) { 569 for (const OMPClause *CPrev : D->clauselists()) { 570 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 571 SemaRef.Diag(CNew->getBeginLoc(), 572 diag::err_omp_requires_clause_redeclaration) 573 << getOpenMPClauseName(CNew->getClauseKind()); 574 SemaRef.Diag(CPrev->getBeginLoc(), 575 diag::note_omp_requires_previous_clause) 576 << getOpenMPClauseName(CPrev->getClauseKind()); 577 IsDuplicate = true; 578 } 579 } 580 } 581 } 582 return IsDuplicate; 583 } 584 585 /// Add location of previously encountered target to internal vector 586 void addTargetDirLocation(SourceLocation LocStart) { 587 TargetLocations.push_back(LocStart); 588 } 589 590 // Return previously encountered target region locations. 591 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 592 return TargetLocations; 593 } 594 595 /// Set default data sharing attribute to none. 596 void setDefaultDSANone(SourceLocation Loc) { 597 getTopOfStack().DefaultAttr = DSA_none; 598 getTopOfStack().DefaultAttrLoc = Loc; 599 } 600 /// Set default data sharing attribute to shared. 601 void setDefaultDSAShared(SourceLocation Loc) { 602 getTopOfStack().DefaultAttr = DSA_shared; 603 getTopOfStack().DefaultAttrLoc = Loc; 604 } 605 /// Set default data mapping attribute to Modifier:Kind 606 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 607 OpenMPDefaultmapClauseKind Kind, 608 SourceLocation Loc) { 609 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 610 DMI.ImplicitBehavior = M; 611 DMI.SLoc = Loc; 612 } 613 /// Check whether the implicit-behavior has been set in defaultmap 614 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 615 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 616 OMPC_DEFAULTMAP_MODIFIER_unknown; 617 } 618 619 DefaultDataSharingAttributes getDefaultDSA() const { 620 return isStackEmpty() ? DSA_unspecified 621 : getTopOfStack().DefaultAttr; 622 } 623 SourceLocation getDefaultDSALocation() const { 624 return isStackEmpty() ? SourceLocation() 625 : getTopOfStack().DefaultAttrLoc; 626 } 627 OpenMPDefaultmapClauseModifier 628 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 629 return isStackEmpty() 630 ? OMPC_DEFAULTMAP_MODIFIER_unknown 631 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 632 } 633 OpenMPDefaultmapClauseModifier 634 getDefaultmapModifierAtLevel(unsigned Level, 635 OpenMPDefaultmapClauseKind Kind) const { 636 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 637 } 638 bool isDefaultmapCapturedByRef(unsigned Level, 639 OpenMPDefaultmapClauseKind Kind) const { 640 OpenMPDefaultmapClauseModifier M = 641 getDefaultmapModifierAtLevel(Level, Kind); 642 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 643 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 644 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 645 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 646 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 647 } 648 return true; 649 } 650 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 651 OpenMPDefaultmapClauseKind Kind) { 652 switch (Kind) { 653 case OMPC_DEFAULTMAP_scalar: 654 case OMPC_DEFAULTMAP_pointer: 655 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 656 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 657 (M == OMPC_DEFAULTMAP_MODIFIER_default); 658 case OMPC_DEFAULTMAP_aggregate: 659 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 660 default: 661 break; 662 } 663 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 664 } 665 bool mustBeFirstprivateAtLevel(unsigned Level, 666 OpenMPDefaultmapClauseKind Kind) const { 667 OpenMPDefaultmapClauseModifier M = 668 getDefaultmapModifierAtLevel(Level, Kind); 669 return mustBeFirstprivateBase(M, Kind); 670 } 671 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 672 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 673 return mustBeFirstprivateBase(M, Kind); 674 } 675 676 /// Checks if the specified variable is a threadprivate. 677 bool isThreadPrivate(VarDecl *D) { 678 const DSAVarData DVar = getTopDSA(D, false); 679 return isOpenMPThreadPrivate(DVar.CKind); 680 } 681 682 /// Marks current region as ordered (it has an 'ordered' clause). 683 void setOrderedRegion(bool IsOrdered, const Expr *Param, 684 OMPOrderedClause *Clause) { 685 if (IsOrdered) 686 getTopOfStack().OrderedRegion.emplace(Param, Clause); 687 else 688 getTopOfStack().OrderedRegion.reset(); 689 } 690 /// Returns true, if region is ordered (has associated 'ordered' clause), 691 /// false - otherwise. 692 bool isOrderedRegion() const { 693 if (const SharingMapTy *Top = getTopOfStackOrNull()) 694 return Top->OrderedRegion.hasValue(); 695 return false; 696 } 697 /// Returns optional parameter for the ordered region. 698 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 699 if (const SharingMapTy *Top = getTopOfStackOrNull()) 700 if (Top->OrderedRegion.hasValue()) 701 return Top->OrderedRegion.getValue(); 702 return std::make_pair(nullptr, nullptr); 703 } 704 /// Returns true, if parent region is ordered (has associated 705 /// 'ordered' clause), false - otherwise. 706 bool isParentOrderedRegion() const { 707 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 708 return Parent->OrderedRegion.hasValue(); 709 return false; 710 } 711 /// Returns optional parameter for the ordered region. 712 std::pair<const Expr *, OMPOrderedClause *> 713 getParentOrderedRegionParam() const { 714 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 715 if (Parent->OrderedRegion.hasValue()) 716 return Parent->OrderedRegion.getValue(); 717 return std::make_pair(nullptr, nullptr); 718 } 719 /// Marks current region as nowait (it has a 'nowait' clause). 720 void setNowaitRegion(bool IsNowait = true) { 721 getTopOfStack().NowaitRegion = IsNowait; 722 } 723 /// Returns true, if parent region is nowait (has associated 724 /// 'nowait' clause), false - otherwise. 725 bool isParentNowaitRegion() const { 726 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 727 return Parent->NowaitRegion; 728 return false; 729 } 730 /// Marks parent region as cancel region. 731 void setParentCancelRegion(bool Cancel = true) { 732 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 733 Parent->CancelRegion |= Cancel; 734 } 735 /// Return true if current region has inner cancel construct. 736 bool isCancelRegion() const { 737 const SharingMapTy *Top = getTopOfStackOrNull(); 738 return Top ? Top->CancelRegion : false; 739 } 740 741 /// Set collapse value for the region. 742 void setAssociatedLoops(unsigned Val) { 743 getTopOfStack().AssociatedLoops = Val; 744 if (Val > 1) 745 getTopOfStack().HasMutipleLoops = true; 746 } 747 /// Return collapse value for region. 748 unsigned getAssociatedLoops() const { 749 const SharingMapTy *Top = getTopOfStackOrNull(); 750 return Top ? Top->AssociatedLoops : 0; 751 } 752 /// Returns true if the construct is associated with multiple loops. 753 bool hasMutipleLoops() const { 754 const SharingMapTy *Top = getTopOfStackOrNull(); 755 return Top ? Top->HasMutipleLoops : false; 756 } 757 758 /// Marks current target region as one with closely nested teams 759 /// region. 760 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 761 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 762 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 763 } 764 /// Returns true, if current region has closely nested teams region. 765 bool hasInnerTeamsRegion() const { 766 return getInnerTeamsRegionLoc().isValid(); 767 } 768 /// Returns location of the nested teams region (if any). 769 SourceLocation getInnerTeamsRegionLoc() const { 770 const SharingMapTy *Top = getTopOfStackOrNull(); 771 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 772 } 773 774 Scope *getCurScope() const { 775 const SharingMapTy *Top = getTopOfStackOrNull(); 776 return Top ? Top->CurScope : nullptr; 777 } 778 SourceLocation getConstructLoc() const { 779 const SharingMapTy *Top = getTopOfStackOrNull(); 780 return Top ? Top->ConstructLoc : SourceLocation(); 781 } 782 783 /// Do the check specified in \a Check to all component lists and return true 784 /// if any issue is found. 785 bool checkMappableExprComponentListsForDecl( 786 const ValueDecl *VD, bool CurrentRegionOnly, 787 const llvm::function_ref< 788 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 789 OpenMPClauseKind)> 790 Check) const { 791 if (isStackEmpty()) 792 return false; 793 auto SI = begin(); 794 auto SE = end(); 795 796 if (SI == SE) 797 return false; 798 799 if (CurrentRegionOnly) 800 SE = std::next(SI); 801 else 802 std::advance(SI, 1); 803 804 for (; SI != SE; ++SI) { 805 auto MI = SI->MappedExprComponents.find(VD); 806 if (MI != SI->MappedExprComponents.end()) 807 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 808 MI->second.Components) 809 if (Check(L, MI->second.Kind)) 810 return true; 811 } 812 return false; 813 } 814 815 /// Do the check specified in \a Check to all component lists at a given level 816 /// and return true if any issue is found. 817 bool checkMappableExprComponentListsForDeclAtLevel( 818 const ValueDecl *VD, unsigned Level, 819 const llvm::function_ref< 820 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 821 OpenMPClauseKind)> 822 Check) const { 823 if (getStackSize() <= Level) 824 return false; 825 826 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 827 auto MI = StackElem.MappedExprComponents.find(VD); 828 if (MI != StackElem.MappedExprComponents.end()) 829 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 830 MI->second.Components) 831 if (Check(L, MI->second.Kind)) 832 return true; 833 return false; 834 } 835 836 /// Create a new mappable expression component list associated with a given 837 /// declaration and initialize it with the provided list of components. 838 void addMappableExpressionComponents( 839 const ValueDecl *VD, 840 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 841 OpenMPClauseKind WhereFoundClauseKind) { 842 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 843 // Create new entry and append the new components there. 844 MEC.Components.resize(MEC.Components.size() + 1); 845 MEC.Components.back().append(Components.begin(), Components.end()); 846 MEC.Kind = WhereFoundClauseKind; 847 } 848 849 unsigned getNestingLevel() const { 850 assert(!isStackEmpty()); 851 return getStackSize() - 1; 852 } 853 void addDoacrossDependClause(OMPDependClause *C, 854 const OperatorOffsetTy &OpsOffs) { 855 SharingMapTy *Parent = getSecondOnStackOrNull(); 856 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 857 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 858 } 859 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 860 getDoacrossDependClauses() const { 861 const SharingMapTy &StackElem = getTopOfStack(); 862 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 863 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 864 return llvm::make_range(Ref.begin(), Ref.end()); 865 } 866 return llvm::make_range(StackElem.DoacrossDepends.end(), 867 StackElem.DoacrossDepends.end()); 868 } 869 870 // Store types of classes which have been explicitly mapped 871 void addMappedClassesQualTypes(QualType QT) { 872 SharingMapTy &StackElem = getTopOfStack(); 873 StackElem.MappedClassesQualTypes.insert(QT); 874 } 875 876 // Return set of mapped classes types 877 bool isClassPreviouslyMapped(QualType QT) const { 878 const SharingMapTy &StackElem = getTopOfStack(); 879 return StackElem.MappedClassesQualTypes.count(QT) != 0; 880 } 881 882 /// Adds global declare target to the parent target region. 883 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 884 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 885 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 886 "Expected declare target link global."); 887 for (auto &Elem : *this) { 888 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 889 Elem.DeclareTargetLinkVarDecls.push_back(E); 890 return; 891 } 892 } 893 } 894 895 /// Returns the list of globals with declare target link if current directive 896 /// is target. 897 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 898 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 899 "Expected target executable directive."); 900 return getTopOfStack().DeclareTargetLinkVarDecls; 901 } 902 }; 903 904 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 905 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 906 } 907 908 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 909 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 910 DKind == OMPD_unknown; 911 } 912 913 } // namespace 914 915 static const Expr *getExprAsWritten(const Expr *E) { 916 if (const auto *FE = dyn_cast<FullExpr>(E)) 917 E = FE->getSubExpr(); 918 919 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 920 E = MTE->getSubExpr(); 921 922 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 923 E = Binder->getSubExpr(); 924 925 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 926 E = ICE->getSubExprAsWritten(); 927 return E->IgnoreParens(); 928 } 929 930 static Expr *getExprAsWritten(Expr *E) { 931 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 932 } 933 934 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 935 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 936 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 937 D = ME->getMemberDecl(); 938 const auto *VD = dyn_cast<VarDecl>(D); 939 const auto *FD = dyn_cast<FieldDecl>(D); 940 if (VD != nullptr) { 941 VD = VD->getCanonicalDecl(); 942 D = VD; 943 } else { 944 assert(FD); 945 FD = FD->getCanonicalDecl(); 946 D = FD; 947 } 948 return D; 949 } 950 951 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 952 return const_cast<ValueDecl *>( 953 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 954 } 955 956 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 957 ValueDecl *D) const { 958 D = getCanonicalDecl(D); 959 auto *VD = dyn_cast<VarDecl>(D); 960 const auto *FD = dyn_cast<FieldDecl>(D); 961 DSAVarData DVar; 962 if (Iter == end()) { 963 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 964 // in a region but not in construct] 965 // File-scope or namespace-scope variables referenced in called routines 966 // in the region are shared unless they appear in a threadprivate 967 // directive. 968 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 969 DVar.CKind = OMPC_shared; 970 971 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 972 // in a region but not in construct] 973 // Variables with static storage duration that are declared in called 974 // routines in the region are shared. 975 if (VD && VD->hasGlobalStorage()) 976 DVar.CKind = OMPC_shared; 977 978 // Non-static data members are shared by default. 979 if (FD) 980 DVar.CKind = OMPC_shared; 981 982 return DVar; 983 } 984 985 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 986 // in a Construct, C/C++, predetermined, p.1] 987 // Variables with automatic storage duration that are declared in a scope 988 // inside the construct are private. 989 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 990 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 991 DVar.CKind = OMPC_private; 992 return DVar; 993 } 994 995 DVar.DKind = Iter->Directive; 996 // Explicitly specified attributes and local variables with predetermined 997 // attributes. 998 if (Iter->SharingMap.count(D)) { 999 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1000 DVar.RefExpr = Data.RefExpr.getPointer(); 1001 DVar.PrivateCopy = Data.PrivateCopy; 1002 DVar.CKind = Data.Attributes; 1003 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1004 return DVar; 1005 } 1006 1007 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1008 // in a Construct, C/C++, implicitly determined, p.1] 1009 // In a parallel or task construct, the data-sharing attributes of these 1010 // variables are determined by the default clause, if present. 1011 switch (Iter->DefaultAttr) { 1012 case DSA_shared: 1013 DVar.CKind = OMPC_shared; 1014 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1015 return DVar; 1016 case DSA_none: 1017 return DVar; 1018 case DSA_unspecified: 1019 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1020 // in a Construct, implicitly determined, p.2] 1021 // In a parallel construct, if no default clause is present, these 1022 // variables are shared. 1023 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1024 if ((isOpenMPParallelDirective(DVar.DKind) && 1025 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1026 isOpenMPTeamsDirective(DVar.DKind)) { 1027 DVar.CKind = OMPC_shared; 1028 return DVar; 1029 } 1030 1031 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1032 // in a Construct, implicitly determined, p.4] 1033 // In a task construct, if no default clause is present, a variable that in 1034 // the enclosing context is determined to be shared by all implicit tasks 1035 // bound to the current team is shared. 1036 if (isOpenMPTaskingDirective(DVar.DKind)) { 1037 DSAVarData DVarTemp; 1038 const_iterator I = Iter, E = end(); 1039 do { 1040 ++I; 1041 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1042 // Referenced in a Construct, implicitly determined, p.6] 1043 // In a task construct, if no default clause is present, a variable 1044 // whose data-sharing attribute is not determined by the rules above is 1045 // firstprivate. 1046 DVarTemp = getDSA(I, D); 1047 if (DVarTemp.CKind != OMPC_shared) { 1048 DVar.RefExpr = nullptr; 1049 DVar.CKind = OMPC_firstprivate; 1050 return DVar; 1051 } 1052 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1053 DVar.CKind = 1054 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1055 return DVar; 1056 } 1057 } 1058 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1059 // in a Construct, implicitly determined, p.3] 1060 // For constructs other than task, if no default clause is present, these 1061 // variables inherit their data-sharing attributes from the enclosing 1062 // context. 1063 return getDSA(++Iter, D); 1064 } 1065 1066 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1067 const Expr *NewDE) { 1068 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1069 D = getCanonicalDecl(D); 1070 SharingMapTy &StackElem = getTopOfStack(); 1071 auto It = StackElem.AlignedMap.find(D); 1072 if (It == StackElem.AlignedMap.end()) { 1073 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1074 StackElem.AlignedMap[D] = NewDE; 1075 return nullptr; 1076 } 1077 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1078 return It->second; 1079 } 1080 1081 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1082 const Expr *NewDE) { 1083 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1084 D = getCanonicalDecl(D); 1085 SharingMapTy &StackElem = getTopOfStack(); 1086 auto It = StackElem.NontemporalMap.find(D); 1087 if (It == StackElem.NontemporalMap.end()) { 1088 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1089 StackElem.NontemporalMap[D] = NewDE; 1090 return nullptr; 1091 } 1092 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1093 return It->second; 1094 } 1095 1096 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1097 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1098 D = getCanonicalDecl(D); 1099 SharingMapTy &StackElem = getTopOfStack(); 1100 StackElem.LCVMap.try_emplace( 1101 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1102 } 1103 1104 const DSAStackTy::LCDeclInfo 1105 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1106 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1107 D = getCanonicalDecl(D); 1108 const SharingMapTy &StackElem = getTopOfStack(); 1109 auto It = StackElem.LCVMap.find(D); 1110 if (It != StackElem.LCVMap.end()) 1111 return It->second; 1112 return {0, nullptr}; 1113 } 1114 1115 const DSAStackTy::LCDeclInfo 1116 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1117 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1118 assert(Parent && "Data-sharing attributes stack is empty"); 1119 D = getCanonicalDecl(D); 1120 auto It = Parent->LCVMap.find(D); 1121 if (It != Parent->LCVMap.end()) 1122 return It->second; 1123 return {0, nullptr}; 1124 } 1125 1126 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1127 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1128 assert(Parent && "Data-sharing attributes stack is empty"); 1129 if (Parent->LCVMap.size() < I) 1130 return nullptr; 1131 for (const auto &Pair : Parent->LCVMap) 1132 if (Pair.second.first == I) 1133 return Pair.first; 1134 return nullptr; 1135 } 1136 1137 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1138 DeclRefExpr *PrivateCopy) { 1139 D = getCanonicalDecl(D); 1140 if (A == OMPC_threadprivate) { 1141 DSAInfo &Data = Threadprivates[D]; 1142 Data.Attributes = A; 1143 Data.RefExpr.setPointer(E); 1144 Data.PrivateCopy = nullptr; 1145 } else { 1146 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1147 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1148 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1149 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1150 (isLoopControlVariable(D).first && A == OMPC_private)); 1151 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1152 Data.RefExpr.setInt(/*IntVal=*/true); 1153 return; 1154 } 1155 const bool IsLastprivate = 1156 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1157 Data.Attributes = A; 1158 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1159 Data.PrivateCopy = PrivateCopy; 1160 if (PrivateCopy) { 1161 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1162 Data.Attributes = A; 1163 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1164 Data.PrivateCopy = nullptr; 1165 } 1166 } 1167 } 1168 1169 /// Build a variable declaration for OpenMP loop iteration variable. 1170 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1171 StringRef Name, const AttrVec *Attrs = nullptr, 1172 DeclRefExpr *OrigRef = nullptr) { 1173 DeclContext *DC = SemaRef.CurContext; 1174 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1175 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1176 auto *Decl = 1177 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1178 if (Attrs) { 1179 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1180 I != E; ++I) 1181 Decl->addAttr(*I); 1182 } 1183 Decl->setImplicit(); 1184 if (OrigRef) { 1185 Decl->addAttr( 1186 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1187 } 1188 return Decl; 1189 } 1190 1191 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1192 SourceLocation Loc, 1193 bool RefersToCapture = false) { 1194 D->setReferenced(); 1195 D->markUsed(S.Context); 1196 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1197 SourceLocation(), D, RefersToCapture, Loc, Ty, 1198 VK_LValue); 1199 } 1200 1201 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1202 BinaryOperatorKind BOK) { 1203 D = getCanonicalDecl(D); 1204 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1205 assert( 1206 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1207 "Additional reduction info may be specified only for reduction items."); 1208 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1209 assert(ReductionData.ReductionRange.isInvalid() && 1210 getTopOfStack().Directive == OMPD_taskgroup && 1211 "Additional reduction info may be specified only once for reduction " 1212 "items."); 1213 ReductionData.set(BOK, SR); 1214 Expr *&TaskgroupReductionRef = 1215 getTopOfStack().TaskgroupReductionRef; 1216 if (!TaskgroupReductionRef) { 1217 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1218 SemaRef.Context.VoidPtrTy, ".task_red."); 1219 TaskgroupReductionRef = 1220 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1221 } 1222 } 1223 1224 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1225 const Expr *ReductionRef) { 1226 D = getCanonicalDecl(D); 1227 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1228 assert( 1229 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1230 "Additional reduction info may be specified only for reduction items."); 1231 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1232 assert(ReductionData.ReductionRange.isInvalid() && 1233 getTopOfStack().Directive == OMPD_taskgroup && 1234 "Additional reduction info may be specified only once for reduction " 1235 "items."); 1236 ReductionData.set(ReductionRef, SR); 1237 Expr *&TaskgroupReductionRef = 1238 getTopOfStack().TaskgroupReductionRef; 1239 if (!TaskgroupReductionRef) { 1240 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1241 SemaRef.Context.VoidPtrTy, ".task_red."); 1242 TaskgroupReductionRef = 1243 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1244 } 1245 } 1246 1247 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1248 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1249 Expr *&TaskgroupDescriptor) const { 1250 D = getCanonicalDecl(D); 1251 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1252 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1253 const DSAInfo &Data = I->SharingMap.lookup(D); 1254 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1255 continue; 1256 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1257 if (!ReductionData.ReductionOp || 1258 ReductionData.ReductionOp.is<const Expr *>()) 1259 return DSAVarData(); 1260 SR = ReductionData.ReductionRange; 1261 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1262 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1263 "expression for the descriptor is not " 1264 "set."); 1265 TaskgroupDescriptor = I->TaskgroupReductionRef; 1266 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1267 Data.PrivateCopy, I->DefaultAttrLoc); 1268 } 1269 return DSAVarData(); 1270 } 1271 1272 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1273 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1274 Expr *&TaskgroupDescriptor) const { 1275 D = getCanonicalDecl(D); 1276 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1277 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1278 const DSAInfo &Data = I->SharingMap.lookup(D); 1279 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1280 continue; 1281 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1282 if (!ReductionData.ReductionOp || 1283 !ReductionData.ReductionOp.is<const Expr *>()) 1284 return DSAVarData(); 1285 SR = ReductionData.ReductionRange; 1286 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1287 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1288 "expression for the descriptor is not " 1289 "set."); 1290 TaskgroupDescriptor = I->TaskgroupReductionRef; 1291 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1292 Data.PrivateCopy, I->DefaultAttrLoc); 1293 } 1294 return DSAVarData(); 1295 } 1296 1297 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1298 D = D->getCanonicalDecl(); 1299 for (const_iterator E = end(); I != E; ++I) { 1300 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1301 isOpenMPTargetExecutionDirective(I->Directive)) { 1302 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1303 Scope *CurScope = getCurScope(); 1304 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1305 CurScope = CurScope->getParent(); 1306 return CurScope != TopScope; 1307 } 1308 } 1309 return false; 1310 } 1311 1312 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1313 bool AcceptIfMutable = true, 1314 bool *IsClassType = nullptr) { 1315 ASTContext &Context = SemaRef.getASTContext(); 1316 Type = Type.getNonReferenceType().getCanonicalType(); 1317 bool IsConstant = Type.isConstant(Context); 1318 Type = Context.getBaseElementType(Type); 1319 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1320 ? Type->getAsCXXRecordDecl() 1321 : nullptr; 1322 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1323 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1324 RD = CTD->getTemplatedDecl(); 1325 if (IsClassType) 1326 *IsClassType = RD; 1327 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1328 RD->hasDefinition() && RD->hasMutableFields()); 1329 } 1330 1331 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1332 QualType Type, OpenMPClauseKind CKind, 1333 SourceLocation ELoc, 1334 bool AcceptIfMutable = true, 1335 bool ListItemNotVar = false) { 1336 ASTContext &Context = SemaRef.getASTContext(); 1337 bool IsClassType; 1338 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1339 unsigned Diag = ListItemNotVar 1340 ? diag::err_omp_const_list_item 1341 : IsClassType ? diag::err_omp_const_not_mutable_variable 1342 : diag::err_omp_const_variable; 1343 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1344 if (!ListItemNotVar && D) { 1345 const VarDecl *VD = dyn_cast<VarDecl>(D); 1346 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1347 VarDecl::DeclarationOnly; 1348 SemaRef.Diag(D->getLocation(), 1349 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1350 << D; 1351 } 1352 return true; 1353 } 1354 return false; 1355 } 1356 1357 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1358 bool FromParent) { 1359 D = getCanonicalDecl(D); 1360 DSAVarData DVar; 1361 1362 auto *VD = dyn_cast<VarDecl>(D); 1363 auto TI = Threadprivates.find(D); 1364 if (TI != Threadprivates.end()) { 1365 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1366 DVar.CKind = OMPC_threadprivate; 1367 return DVar; 1368 } 1369 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1370 DVar.RefExpr = buildDeclRefExpr( 1371 SemaRef, VD, D->getType().getNonReferenceType(), 1372 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1373 DVar.CKind = OMPC_threadprivate; 1374 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1375 return DVar; 1376 } 1377 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1378 // in a Construct, C/C++, predetermined, p.1] 1379 // Variables appearing in threadprivate directives are threadprivate. 1380 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1381 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1382 SemaRef.getLangOpts().OpenMPUseTLS && 1383 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1384 (VD && VD->getStorageClass() == SC_Register && 1385 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1386 DVar.RefExpr = buildDeclRefExpr( 1387 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1388 DVar.CKind = OMPC_threadprivate; 1389 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1390 return DVar; 1391 } 1392 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1393 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1394 !isLoopControlVariable(D).first) { 1395 const_iterator IterTarget = 1396 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1397 return isOpenMPTargetExecutionDirective(Data.Directive); 1398 }); 1399 if (IterTarget != end()) { 1400 const_iterator ParentIterTarget = IterTarget + 1; 1401 for (const_iterator Iter = begin(); 1402 Iter != ParentIterTarget; ++Iter) { 1403 if (isOpenMPLocal(VD, Iter)) { 1404 DVar.RefExpr = 1405 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1406 D->getLocation()); 1407 DVar.CKind = OMPC_threadprivate; 1408 return DVar; 1409 } 1410 } 1411 if (!isClauseParsingMode() || IterTarget != begin()) { 1412 auto DSAIter = IterTarget->SharingMap.find(D); 1413 if (DSAIter != IterTarget->SharingMap.end() && 1414 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1415 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1416 DVar.CKind = OMPC_threadprivate; 1417 return DVar; 1418 } 1419 const_iterator End = end(); 1420 if (!SemaRef.isOpenMPCapturedByRef( 1421 D, std::distance(ParentIterTarget, End), 1422 /*OpenMPCaptureLevel=*/0)) { 1423 DVar.RefExpr = 1424 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1425 IterTarget->ConstructLoc); 1426 DVar.CKind = OMPC_threadprivate; 1427 return DVar; 1428 } 1429 } 1430 } 1431 } 1432 1433 if (isStackEmpty()) 1434 // Not in OpenMP execution region and top scope was already checked. 1435 return DVar; 1436 1437 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1438 // in a Construct, C/C++, predetermined, p.4] 1439 // Static data members are shared. 1440 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1441 // in a Construct, C/C++, predetermined, p.7] 1442 // Variables with static storage duration that are declared in a scope 1443 // inside the construct are shared. 1444 if (VD && VD->isStaticDataMember()) { 1445 // Check for explicitly specified attributes. 1446 const_iterator I = begin(); 1447 const_iterator EndI = end(); 1448 if (FromParent && I != EndI) 1449 ++I; 1450 auto It = I->SharingMap.find(D); 1451 if (It != I->SharingMap.end()) { 1452 const DSAInfo &Data = It->getSecond(); 1453 DVar.RefExpr = Data.RefExpr.getPointer(); 1454 DVar.PrivateCopy = Data.PrivateCopy; 1455 DVar.CKind = Data.Attributes; 1456 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1457 DVar.DKind = I->Directive; 1458 return DVar; 1459 } 1460 1461 DVar.CKind = OMPC_shared; 1462 return DVar; 1463 } 1464 1465 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1466 // The predetermined shared attribute for const-qualified types having no 1467 // mutable members was removed after OpenMP 3.1. 1468 if (SemaRef.LangOpts.OpenMP <= 31) { 1469 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1470 // in a Construct, C/C++, predetermined, p.6] 1471 // Variables with const qualified type having no mutable member are 1472 // shared. 1473 if (isConstNotMutableType(SemaRef, D->getType())) { 1474 // Variables with const-qualified type having no mutable member may be 1475 // listed in a firstprivate clause, even if they are static data members. 1476 DSAVarData DVarTemp = hasInnermostDSA( 1477 D, 1478 [](OpenMPClauseKind C) { 1479 return C == OMPC_firstprivate || C == OMPC_shared; 1480 }, 1481 MatchesAlways, FromParent); 1482 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1483 return DVarTemp; 1484 1485 DVar.CKind = OMPC_shared; 1486 return DVar; 1487 } 1488 } 1489 1490 // Explicitly specified attributes and local variables with predetermined 1491 // attributes. 1492 const_iterator I = begin(); 1493 const_iterator EndI = end(); 1494 if (FromParent && I != EndI) 1495 ++I; 1496 auto It = I->SharingMap.find(D); 1497 if (It != I->SharingMap.end()) { 1498 const DSAInfo &Data = It->getSecond(); 1499 DVar.RefExpr = Data.RefExpr.getPointer(); 1500 DVar.PrivateCopy = Data.PrivateCopy; 1501 DVar.CKind = Data.Attributes; 1502 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1503 DVar.DKind = I->Directive; 1504 } 1505 1506 return DVar; 1507 } 1508 1509 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1510 bool FromParent) const { 1511 if (isStackEmpty()) { 1512 const_iterator I; 1513 return getDSA(I, D); 1514 } 1515 D = getCanonicalDecl(D); 1516 const_iterator StartI = begin(); 1517 const_iterator EndI = end(); 1518 if (FromParent && StartI != EndI) 1519 ++StartI; 1520 return getDSA(StartI, D); 1521 } 1522 1523 const DSAStackTy::DSAVarData 1524 DSAStackTy::hasDSA(ValueDecl *D, 1525 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1526 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1527 bool FromParent) const { 1528 if (isStackEmpty()) 1529 return {}; 1530 D = getCanonicalDecl(D); 1531 const_iterator I = begin(); 1532 const_iterator EndI = end(); 1533 if (FromParent && I != EndI) 1534 ++I; 1535 for (; I != EndI; ++I) { 1536 if (!DPred(I->Directive) && 1537 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1538 continue; 1539 const_iterator NewI = I; 1540 DSAVarData DVar = getDSA(NewI, D); 1541 if (I == NewI && CPred(DVar.CKind)) 1542 return DVar; 1543 } 1544 return {}; 1545 } 1546 1547 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1548 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1549 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1550 bool FromParent) const { 1551 if (isStackEmpty()) 1552 return {}; 1553 D = getCanonicalDecl(D); 1554 const_iterator StartI = begin(); 1555 const_iterator EndI = end(); 1556 if (FromParent && StartI != EndI) 1557 ++StartI; 1558 if (StartI == EndI || !DPred(StartI->Directive)) 1559 return {}; 1560 const_iterator NewI = StartI; 1561 DSAVarData DVar = getDSA(NewI, D); 1562 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1563 } 1564 1565 bool DSAStackTy::hasExplicitDSA( 1566 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1567 unsigned Level, bool NotLastprivate) const { 1568 if (getStackSize() <= Level) 1569 return false; 1570 D = getCanonicalDecl(D); 1571 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1572 auto I = StackElem.SharingMap.find(D); 1573 if (I != StackElem.SharingMap.end() && 1574 I->getSecond().RefExpr.getPointer() && 1575 CPred(I->getSecond().Attributes) && 1576 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1577 return true; 1578 // Check predetermined rules for the loop control variables. 1579 auto LI = StackElem.LCVMap.find(D); 1580 if (LI != StackElem.LCVMap.end()) 1581 return CPred(OMPC_private); 1582 return false; 1583 } 1584 1585 bool DSAStackTy::hasExplicitDirective( 1586 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1587 unsigned Level) const { 1588 if (getStackSize() <= Level) 1589 return false; 1590 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1591 return DPred(StackElem.Directive); 1592 } 1593 1594 bool DSAStackTy::hasDirective( 1595 const llvm::function_ref<bool(OpenMPDirectiveKind, 1596 const DeclarationNameInfo &, SourceLocation)> 1597 DPred, 1598 bool FromParent) const { 1599 // We look only in the enclosing region. 1600 size_t Skip = FromParent ? 2 : 1; 1601 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1602 I != E; ++I) { 1603 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1604 return true; 1605 } 1606 return false; 1607 } 1608 1609 void Sema::InitDataSharingAttributesStack() { 1610 VarDataSharingAttributesStack = new DSAStackTy(*this); 1611 } 1612 1613 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1614 1615 void Sema::pushOpenMPFunctionRegion() { 1616 DSAStack->pushFunction(); 1617 } 1618 1619 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1620 DSAStack->popFunction(OldFSI); 1621 } 1622 1623 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1624 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1625 "Expected OpenMP device compilation."); 1626 return !S.isInOpenMPTargetExecutionDirective() && 1627 !S.isInOpenMPDeclareTargetContext(); 1628 } 1629 1630 namespace { 1631 /// Status of the function emission on the host/device. 1632 enum class FunctionEmissionStatus { 1633 Emitted, 1634 Discarded, 1635 Unknown, 1636 }; 1637 } // anonymous namespace 1638 1639 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1640 unsigned DiagID) { 1641 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1642 "Expected OpenMP device compilation."); 1643 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1644 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1645 switch (FES) { 1646 case FunctionEmissionStatus::Emitted: 1647 Kind = DeviceDiagBuilder::K_Immediate; 1648 break; 1649 case FunctionEmissionStatus::Unknown: 1650 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1651 : DeviceDiagBuilder::K_Immediate; 1652 break; 1653 case FunctionEmissionStatus::TemplateDiscarded: 1654 case FunctionEmissionStatus::OMPDiscarded: 1655 Kind = DeviceDiagBuilder::K_Nop; 1656 break; 1657 case FunctionEmissionStatus::CUDADiscarded: 1658 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1659 break; 1660 } 1661 1662 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1663 } 1664 1665 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1666 unsigned DiagID) { 1667 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1668 "Expected OpenMP host compilation."); 1669 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1670 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1671 switch (FES) { 1672 case FunctionEmissionStatus::Emitted: 1673 Kind = DeviceDiagBuilder::K_Immediate; 1674 break; 1675 case FunctionEmissionStatus::Unknown: 1676 Kind = DeviceDiagBuilder::K_Deferred; 1677 break; 1678 case FunctionEmissionStatus::TemplateDiscarded: 1679 case FunctionEmissionStatus::OMPDiscarded: 1680 case FunctionEmissionStatus::CUDADiscarded: 1681 Kind = DeviceDiagBuilder::K_Nop; 1682 break; 1683 } 1684 1685 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1686 } 1687 1688 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1689 bool CheckForDelayedContext) { 1690 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1691 "Expected OpenMP device compilation."); 1692 assert(Callee && "Callee may not be null."); 1693 Callee = Callee->getMostRecentDecl(); 1694 FunctionDecl *Caller = getCurFunctionDecl(); 1695 1696 // host only function are not available on the device. 1697 if (Caller) { 1698 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1699 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1700 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1701 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1702 "CUDADiscarded unexpected in OpenMP device function check"); 1703 if ((CallerS == FunctionEmissionStatus::Emitted || 1704 (!isOpenMPDeviceDelayedContext(*this) && 1705 CallerS == FunctionEmissionStatus::Unknown)) && 1706 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1707 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1708 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1709 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1710 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1711 diag::note_omp_marked_device_type_here) 1712 << HostDevTy; 1713 return; 1714 } 1715 } 1716 // If the caller is known-emitted, mark the callee as known-emitted. 1717 // Otherwise, mark the call in our call graph so we can traverse it later. 1718 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1719 (!Caller && !CheckForDelayedContext) || 1720 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1721 markKnownEmitted(*this, Caller, Callee, Loc, 1722 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1723 return CheckForDelayedContext && 1724 S.getEmissionStatus(FD) == 1725 FunctionEmissionStatus::Emitted; 1726 }); 1727 else if (Caller) 1728 DeviceCallGraph[Caller].insert({Callee, Loc}); 1729 } 1730 1731 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1732 bool CheckCaller) { 1733 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1734 "Expected OpenMP host compilation."); 1735 assert(Callee && "Callee may not be null."); 1736 Callee = Callee->getMostRecentDecl(); 1737 FunctionDecl *Caller = getCurFunctionDecl(); 1738 1739 // device only function are not available on the host. 1740 if (Caller) { 1741 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1742 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1743 assert( 1744 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1745 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1746 "CUDADiscarded unexpected in OpenMP host function check"); 1747 if (CallerS == FunctionEmissionStatus::Emitted && 1748 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1749 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1750 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1751 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1752 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1753 diag::note_omp_marked_device_type_here) 1754 << NoHostDevTy; 1755 return; 1756 } 1757 } 1758 // If the caller is known-emitted, mark the callee as known-emitted. 1759 // Otherwise, mark the call in our call graph so we can traverse it later. 1760 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1761 if ((!CheckCaller && !Caller) || 1762 (Caller && 1763 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1764 markKnownEmitted( 1765 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1766 return CheckCaller && 1767 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1768 }); 1769 else if (Caller) 1770 DeviceCallGraph[Caller].insert({Callee, Loc}); 1771 } 1772 } 1773 1774 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1775 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1776 "OpenMP device compilation mode is expected."); 1777 QualType Ty = E->getType(); 1778 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1779 ((Ty->isFloat128Type() || 1780 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1781 !Context.getTargetInfo().hasFloat128Type()) || 1782 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1783 !Context.getTargetInfo().hasInt128Type())) 1784 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1785 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1786 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1787 } 1788 1789 static OpenMPDefaultmapClauseKind 1790 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1791 if (LO.OpenMP <= 45) { 1792 if (VD->getType().getNonReferenceType()->isScalarType()) 1793 return OMPC_DEFAULTMAP_scalar; 1794 return OMPC_DEFAULTMAP_aggregate; 1795 } 1796 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1797 return OMPC_DEFAULTMAP_pointer; 1798 if (VD->getType().getNonReferenceType()->isScalarType()) 1799 return OMPC_DEFAULTMAP_scalar; 1800 return OMPC_DEFAULTMAP_aggregate; 1801 } 1802 1803 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1804 unsigned OpenMPCaptureLevel) const { 1805 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1806 1807 ASTContext &Ctx = getASTContext(); 1808 bool IsByRef = true; 1809 1810 // Find the directive that is associated with the provided scope. 1811 D = cast<ValueDecl>(D->getCanonicalDecl()); 1812 QualType Ty = D->getType(); 1813 1814 bool IsVariableUsedInMapClause = false; 1815 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1816 // This table summarizes how a given variable should be passed to the device 1817 // given its type and the clauses where it appears. This table is based on 1818 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1819 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1820 // 1821 // ========================================================================= 1822 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1823 // | |(tofrom:scalar)| | pvt | | | | 1824 // ========================================================================= 1825 // | scl | | | | - | | bycopy| 1826 // | scl | | - | x | - | - | bycopy| 1827 // | scl | | x | - | - | - | null | 1828 // | scl | x | | | - | | byref | 1829 // | scl | x | - | x | - | - | bycopy| 1830 // | scl | x | x | - | - | - | null | 1831 // | scl | | - | - | - | x | byref | 1832 // | scl | x | - | - | - | x | byref | 1833 // 1834 // | agg | n.a. | | | - | | byref | 1835 // | agg | n.a. | - | x | - | - | byref | 1836 // | agg | n.a. | x | - | - | - | null | 1837 // | agg | n.a. | - | - | - | x | byref | 1838 // | agg | n.a. | - | - | - | x[] | byref | 1839 // 1840 // | ptr | n.a. | | | - | | bycopy| 1841 // | ptr | n.a. | - | x | - | - | bycopy| 1842 // | ptr | n.a. | x | - | - | - | null | 1843 // | ptr | n.a. | - | - | - | x | byref | 1844 // | ptr | n.a. | - | - | - | x[] | bycopy| 1845 // | ptr | n.a. | - | - | x | | bycopy| 1846 // | ptr | n.a. | - | - | x | x | bycopy| 1847 // | ptr | n.a. | - | - | x | x[] | bycopy| 1848 // ========================================================================= 1849 // Legend: 1850 // scl - scalar 1851 // ptr - pointer 1852 // agg - aggregate 1853 // x - applies 1854 // - - invalid in this combination 1855 // [] - mapped with an array section 1856 // byref - should be mapped by reference 1857 // byval - should be mapped by value 1858 // null - initialize a local variable to null on the device 1859 // 1860 // Observations: 1861 // - All scalar declarations that show up in a map clause have to be passed 1862 // by reference, because they may have been mapped in the enclosing data 1863 // environment. 1864 // - If the scalar value does not fit the size of uintptr, it has to be 1865 // passed by reference, regardless the result in the table above. 1866 // - For pointers mapped by value that have either an implicit map or an 1867 // array section, the runtime library may pass the NULL value to the 1868 // device instead of the value passed to it by the compiler. 1869 1870 if (Ty->isReferenceType()) 1871 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1872 1873 // Locate map clauses and see if the variable being captured is referred to 1874 // in any of those clauses. Here we only care about variables, not fields, 1875 // because fields are part of aggregates. 1876 bool IsVariableAssociatedWithSection = false; 1877 1878 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1879 D, Level, 1880 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1881 OMPClauseMappableExprCommon::MappableExprComponentListRef 1882 MapExprComponents, 1883 OpenMPClauseKind WhereFoundClauseKind) { 1884 // Only the map clause information influences how a variable is 1885 // captured. E.g. is_device_ptr does not require changing the default 1886 // behavior. 1887 if (WhereFoundClauseKind != OMPC_map) 1888 return false; 1889 1890 auto EI = MapExprComponents.rbegin(); 1891 auto EE = MapExprComponents.rend(); 1892 1893 assert(EI != EE && "Invalid map expression!"); 1894 1895 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1896 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1897 1898 ++EI; 1899 if (EI == EE) 1900 return false; 1901 1902 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1903 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1904 isa<MemberExpr>(EI->getAssociatedExpression())) { 1905 IsVariableAssociatedWithSection = true; 1906 // There is nothing more we need to know about this variable. 1907 return true; 1908 } 1909 1910 // Keep looking for more map info. 1911 return false; 1912 }); 1913 1914 if (IsVariableUsedInMapClause) { 1915 // If variable is identified in a map clause it is always captured by 1916 // reference except if it is a pointer that is dereferenced somehow. 1917 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1918 } else { 1919 // By default, all the data that has a scalar type is mapped by copy 1920 // (except for reduction variables). 1921 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1922 IsByRef = 1923 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1924 !Ty->isAnyPointerType()) || 1925 !Ty->isScalarType() || 1926 DSAStack->isDefaultmapCapturedByRef( 1927 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1928 DSAStack->hasExplicitDSA( 1929 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1930 } 1931 } 1932 1933 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1934 IsByRef = 1935 ((IsVariableUsedInMapClause && 1936 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1937 OMPD_target) || 1938 !DSAStack->hasExplicitDSA( 1939 D, 1940 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1941 Level, /*NotLastprivate=*/true)) && 1942 // If the variable is artificial and must be captured by value - try to 1943 // capture by value. 1944 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1945 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1946 } 1947 1948 // When passing data by copy, we need to make sure it fits the uintptr size 1949 // and alignment, because the runtime library only deals with uintptr types. 1950 // If it does not fit the uintptr size, we need to pass the data by reference 1951 // instead. 1952 if (!IsByRef && 1953 (Ctx.getTypeSizeInChars(Ty) > 1954 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1955 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1956 IsByRef = true; 1957 } 1958 1959 return IsByRef; 1960 } 1961 1962 unsigned Sema::getOpenMPNestingLevel() const { 1963 assert(getLangOpts().OpenMP); 1964 return DSAStack->getNestingLevel(); 1965 } 1966 1967 bool Sema::isInOpenMPTargetExecutionDirective() const { 1968 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1969 !DSAStack->isClauseParsingMode()) || 1970 DSAStack->hasDirective( 1971 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1972 SourceLocation) -> bool { 1973 return isOpenMPTargetExecutionDirective(K); 1974 }, 1975 false); 1976 } 1977 1978 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1979 unsigned StopAt) { 1980 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1981 D = getCanonicalDecl(D); 1982 1983 auto *VD = dyn_cast<VarDecl>(D); 1984 // Do not capture constexpr variables. 1985 if (VD && VD->isConstexpr()) 1986 return nullptr; 1987 1988 // If we want to determine whether the variable should be captured from the 1989 // perspective of the current capturing scope, and we've already left all the 1990 // capturing scopes of the top directive on the stack, check from the 1991 // perspective of its parent directive (if any) instead. 1992 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1993 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1994 1995 // If we are attempting to capture a global variable in a directive with 1996 // 'target' we return true so that this global is also mapped to the device. 1997 // 1998 if (VD && !VD->hasLocalStorage() && 1999 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2000 if (isInOpenMPDeclareTargetContext()) { 2001 // Try to mark variable as declare target if it is used in capturing 2002 // regions. 2003 if (LangOpts.OpenMP <= 45 && 2004 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2005 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2006 return nullptr; 2007 } else if (isInOpenMPTargetExecutionDirective()) { 2008 // If the declaration is enclosed in a 'declare target' directive, 2009 // then it should not be captured. 2010 // 2011 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2012 return nullptr; 2013 return VD; 2014 } 2015 } 2016 2017 if (CheckScopeInfo) { 2018 bool OpenMPFound = false; 2019 for (unsigned I = StopAt + 1; I > 0; --I) { 2020 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2021 if(!isa<CapturingScopeInfo>(FSI)) 2022 return nullptr; 2023 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2024 if (RSI->CapRegionKind == CR_OpenMP) { 2025 OpenMPFound = true; 2026 break; 2027 } 2028 } 2029 if (!OpenMPFound) 2030 return nullptr; 2031 } 2032 2033 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2034 (!DSAStack->isClauseParsingMode() || 2035 DSAStack->getParentDirective() != OMPD_unknown)) { 2036 auto &&Info = DSAStack->isLoopControlVariable(D); 2037 if (Info.first || 2038 (VD && VD->hasLocalStorage() && 2039 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2040 (VD && DSAStack->isForceVarCapturing())) 2041 return VD ? VD : Info.second; 2042 DSAStackTy::DSAVarData DVarPrivate = 2043 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2044 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2045 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2046 // Threadprivate variables must not be captured. 2047 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2048 return nullptr; 2049 // The variable is not private or it is the variable in the directive with 2050 // default(none) clause and not used in any clause. 2051 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2052 [](OpenMPDirectiveKind) { return true; }, 2053 DSAStack->isClauseParsingMode()); 2054 if (DVarPrivate.CKind != OMPC_unknown || 2055 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2056 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2057 } 2058 return nullptr; 2059 } 2060 2061 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2062 unsigned Level) const { 2063 SmallVector<OpenMPDirectiveKind, 4> Regions; 2064 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2065 FunctionScopesIndex -= Regions.size(); 2066 } 2067 2068 void Sema::startOpenMPLoop() { 2069 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2070 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2071 DSAStack->loopInit(); 2072 } 2073 2074 void Sema::startOpenMPCXXRangeFor() { 2075 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2076 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2077 DSAStack->resetPossibleLoopCounter(); 2078 DSAStack->loopStart(); 2079 } 2080 } 2081 2082 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2083 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2084 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2085 if (DSAStack->getAssociatedLoops() > 0 && 2086 !DSAStack->isLoopStarted()) { 2087 DSAStack->resetPossibleLoopCounter(D); 2088 DSAStack->loopStart(); 2089 return true; 2090 } 2091 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2092 DSAStack->isLoopControlVariable(D).first) && 2093 !DSAStack->hasExplicitDSA( 2094 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2095 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2096 return true; 2097 } 2098 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2099 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2100 DSAStack->isForceVarCapturing() && 2101 !DSAStack->hasExplicitDSA( 2102 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2103 return true; 2104 } 2105 return DSAStack->hasExplicitDSA( 2106 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2107 (DSAStack->isClauseParsingMode() && 2108 DSAStack->getClauseParsingMode() == OMPC_private) || 2109 // Consider taskgroup reduction descriptor variable a private to avoid 2110 // possible capture in the region. 2111 (DSAStack->hasExplicitDirective( 2112 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2113 Level) && 2114 DSAStack->isTaskgroupReductionRef(D, Level)); 2115 } 2116 2117 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2118 unsigned Level) { 2119 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2120 D = getCanonicalDecl(D); 2121 OpenMPClauseKind OMPC = OMPC_unknown; 2122 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2123 const unsigned NewLevel = I - 1; 2124 if (DSAStack->hasExplicitDSA(D, 2125 [&OMPC](const OpenMPClauseKind K) { 2126 if (isOpenMPPrivate(K)) { 2127 OMPC = K; 2128 return true; 2129 } 2130 return false; 2131 }, 2132 NewLevel)) 2133 break; 2134 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2135 D, NewLevel, 2136 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2137 OpenMPClauseKind) { return true; })) { 2138 OMPC = OMPC_map; 2139 break; 2140 } 2141 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2142 NewLevel)) { 2143 OMPC = OMPC_map; 2144 if (DSAStack->mustBeFirstprivateAtLevel( 2145 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2146 OMPC = OMPC_firstprivate; 2147 break; 2148 } 2149 } 2150 if (OMPC != OMPC_unknown) 2151 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2152 } 2153 2154 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2155 unsigned Level) const { 2156 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2157 // Return true if the current level is no longer enclosed in a target region. 2158 2159 const auto *VD = dyn_cast<VarDecl>(D); 2160 return VD && !VD->hasLocalStorage() && 2161 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2162 Level); 2163 } 2164 2165 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2166 2167 void Sema::finalizeOpenMPDelayedAnalysis() { 2168 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2169 // Diagnose implicit declare target functions and their callees. 2170 for (const auto &CallerCallees : DeviceCallGraph) { 2171 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2172 OMPDeclareTargetDeclAttr::getDeviceType( 2173 CallerCallees.getFirst()->getMostRecentDecl()); 2174 // Ignore host functions during device analyzis. 2175 if (LangOpts.OpenMPIsDevice && DevTy && 2176 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2177 continue; 2178 // Ignore nohost functions during host analyzis. 2179 if (!LangOpts.OpenMPIsDevice && DevTy && 2180 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2181 continue; 2182 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2183 &Callee : CallerCallees.getSecond()) { 2184 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2185 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2186 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2187 if (LangOpts.OpenMPIsDevice && DevTy && 2188 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2189 // Diagnose host function called during device codegen. 2190 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2191 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2192 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2193 << HostDevTy << 0; 2194 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2195 diag::note_omp_marked_device_type_here) 2196 << HostDevTy; 2197 continue; 2198 } 2199 if (!LangOpts.OpenMPIsDevice && DevTy && 2200 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2201 // Diagnose nohost function called during host codegen. 2202 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2203 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2204 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2205 << NoHostDevTy << 1; 2206 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2207 diag::note_omp_marked_device_type_here) 2208 << NoHostDevTy; 2209 continue; 2210 } 2211 } 2212 } 2213 } 2214 2215 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2216 const DeclarationNameInfo &DirName, 2217 Scope *CurScope, SourceLocation Loc) { 2218 DSAStack->push(DKind, DirName, CurScope, Loc); 2219 PushExpressionEvaluationContext( 2220 ExpressionEvaluationContext::PotentiallyEvaluated); 2221 } 2222 2223 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2224 DSAStack->setClauseParsingMode(K); 2225 } 2226 2227 void Sema::EndOpenMPClause() { 2228 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2229 } 2230 2231 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2232 ArrayRef<OMPClause *> Clauses); 2233 static std::pair<ValueDecl *, bool> 2234 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2235 SourceRange &ERange, bool AllowArraySection = false); 2236 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2237 bool WithInit); 2238 2239 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2240 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2241 // A variable of class type (or array thereof) that appears in a lastprivate 2242 // clause requires an accessible, unambiguous default constructor for the 2243 // class type, unless the list item is also specified in a firstprivate 2244 // clause. 2245 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2246 for (OMPClause *C : D->clauses()) { 2247 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2248 SmallVector<Expr *, 8> PrivateCopies; 2249 for (Expr *DE : Clause->varlists()) { 2250 if (DE->isValueDependent() || DE->isTypeDependent()) { 2251 PrivateCopies.push_back(nullptr); 2252 continue; 2253 } 2254 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2255 auto *VD = cast<VarDecl>(DRE->getDecl()); 2256 QualType Type = VD->getType().getNonReferenceType(); 2257 const DSAStackTy::DSAVarData DVar = 2258 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2259 if (DVar.CKind == OMPC_lastprivate) { 2260 // Generate helper private variable and initialize it with the 2261 // default value. The address of the original variable is replaced 2262 // by the address of the new private variable in CodeGen. This new 2263 // variable is not added to IdResolver, so the code in the OpenMP 2264 // region uses original variable for proper diagnostics. 2265 VarDecl *VDPrivate = buildVarDecl( 2266 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2267 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2268 ActOnUninitializedDecl(VDPrivate); 2269 if (VDPrivate->isInvalidDecl()) { 2270 PrivateCopies.push_back(nullptr); 2271 continue; 2272 } 2273 PrivateCopies.push_back(buildDeclRefExpr( 2274 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2275 } else { 2276 // The variable is also a firstprivate, so initialization sequence 2277 // for private copy is generated already. 2278 PrivateCopies.push_back(nullptr); 2279 } 2280 } 2281 Clause->setPrivateCopies(PrivateCopies); 2282 continue; 2283 } 2284 // Finalize nontemporal clause by handling private copies, if any. 2285 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2286 SmallVector<Expr *, 8> PrivateRefs; 2287 for (Expr *RefExpr : Clause->varlists()) { 2288 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2289 SourceLocation ELoc; 2290 SourceRange ERange; 2291 Expr *SimpleRefExpr = RefExpr; 2292 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2293 if (Res.second) 2294 // It will be analyzed later. 2295 PrivateRefs.push_back(RefExpr); 2296 ValueDecl *D = Res.first; 2297 if (!D) 2298 continue; 2299 2300 const DSAStackTy::DSAVarData DVar = 2301 DSAStack->getTopDSA(D, /*FromParent=*/false); 2302 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2303 : SimpleRefExpr); 2304 } 2305 Clause->setPrivateRefs(PrivateRefs); 2306 continue; 2307 } 2308 } 2309 // Check allocate clauses. 2310 if (!CurContext->isDependentContext()) 2311 checkAllocateClauses(*this, DSAStack, D->clauses()); 2312 } 2313 2314 DSAStack->pop(); 2315 DiscardCleanupsInEvaluationContext(); 2316 PopExpressionEvaluationContext(); 2317 } 2318 2319 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2320 Expr *NumIterations, Sema &SemaRef, 2321 Scope *S, DSAStackTy *Stack); 2322 2323 namespace { 2324 2325 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2326 private: 2327 Sema &SemaRef; 2328 2329 public: 2330 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2331 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2332 NamedDecl *ND = Candidate.getCorrectionDecl(); 2333 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2334 return VD->hasGlobalStorage() && 2335 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2336 SemaRef.getCurScope()); 2337 } 2338 return false; 2339 } 2340 2341 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2342 return std::make_unique<VarDeclFilterCCC>(*this); 2343 } 2344 2345 }; 2346 2347 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2348 private: 2349 Sema &SemaRef; 2350 2351 public: 2352 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2353 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2354 NamedDecl *ND = Candidate.getCorrectionDecl(); 2355 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2356 isa<FunctionDecl>(ND))) { 2357 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2358 SemaRef.getCurScope()); 2359 } 2360 return false; 2361 } 2362 2363 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2364 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2365 } 2366 }; 2367 2368 } // namespace 2369 2370 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2371 CXXScopeSpec &ScopeSpec, 2372 const DeclarationNameInfo &Id, 2373 OpenMPDirectiveKind Kind) { 2374 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2375 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2376 2377 if (Lookup.isAmbiguous()) 2378 return ExprError(); 2379 2380 VarDecl *VD; 2381 if (!Lookup.isSingleResult()) { 2382 VarDeclFilterCCC CCC(*this); 2383 if (TypoCorrection Corrected = 2384 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2385 CTK_ErrorRecovery)) { 2386 diagnoseTypo(Corrected, 2387 PDiag(Lookup.empty() 2388 ? diag::err_undeclared_var_use_suggest 2389 : diag::err_omp_expected_var_arg_suggest) 2390 << Id.getName()); 2391 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2392 } else { 2393 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2394 : diag::err_omp_expected_var_arg) 2395 << Id.getName(); 2396 return ExprError(); 2397 } 2398 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2399 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2400 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2401 return ExprError(); 2402 } 2403 Lookup.suppressDiagnostics(); 2404 2405 // OpenMP [2.9.2, Syntax, C/C++] 2406 // Variables must be file-scope, namespace-scope, or static block-scope. 2407 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2408 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2409 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2410 bool IsDecl = 2411 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2412 Diag(VD->getLocation(), 2413 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2414 << VD; 2415 return ExprError(); 2416 } 2417 2418 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2419 NamedDecl *ND = CanonicalVD; 2420 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2421 // A threadprivate directive for file-scope variables must appear outside 2422 // any definition or declaration. 2423 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2424 !getCurLexicalContext()->isTranslationUnit()) { 2425 Diag(Id.getLoc(), diag::err_omp_var_scope) 2426 << getOpenMPDirectiveName(Kind) << VD; 2427 bool IsDecl = 2428 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2429 Diag(VD->getLocation(), 2430 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2431 << VD; 2432 return ExprError(); 2433 } 2434 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2435 // A threadprivate directive for static class member variables must appear 2436 // in the class definition, in the same scope in which the member 2437 // variables are declared. 2438 if (CanonicalVD->isStaticDataMember() && 2439 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2440 Diag(Id.getLoc(), diag::err_omp_var_scope) 2441 << getOpenMPDirectiveName(Kind) << VD; 2442 bool IsDecl = 2443 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2444 Diag(VD->getLocation(), 2445 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2446 << VD; 2447 return ExprError(); 2448 } 2449 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2450 // A threadprivate directive for namespace-scope variables must appear 2451 // outside any definition or declaration other than the namespace 2452 // definition itself. 2453 if (CanonicalVD->getDeclContext()->isNamespace() && 2454 (!getCurLexicalContext()->isFileContext() || 2455 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2456 Diag(Id.getLoc(), diag::err_omp_var_scope) 2457 << getOpenMPDirectiveName(Kind) << VD; 2458 bool IsDecl = 2459 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2460 Diag(VD->getLocation(), 2461 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2462 << VD; 2463 return ExprError(); 2464 } 2465 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2466 // A threadprivate directive for static block-scope variables must appear 2467 // in the scope of the variable and not in a nested scope. 2468 if (CanonicalVD->isLocalVarDecl() && CurScope && 2469 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2470 Diag(Id.getLoc(), diag::err_omp_var_scope) 2471 << getOpenMPDirectiveName(Kind) << VD; 2472 bool IsDecl = 2473 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2474 Diag(VD->getLocation(), 2475 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2476 << VD; 2477 return ExprError(); 2478 } 2479 2480 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2481 // A threadprivate directive must lexically precede all references to any 2482 // of the variables in its list. 2483 if (Kind == OMPD_threadprivate && VD->isUsed() && 2484 !DSAStack->isThreadPrivate(VD)) { 2485 Diag(Id.getLoc(), diag::err_omp_var_used) 2486 << getOpenMPDirectiveName(Kind) << VD; 2487 return ExprError(); 2488 } 2489 2490 QualType ExprType = VD->getType().getNonReferenceType(); 2491 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2492 SourceLocation(), VD, 2493 /*RefersToEnclosingVariableOrCapture=*/false, 2494 Id.getLoc(), ExprType, VK_LValue); 2495 } 2496 2497 Sema::DeclGroupPtrTy 2498 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2499 ArrayRef<Expr *> VarList) { 2500 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2501 CurContext->addDecl(D); 2502 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2503 } 2504 return nullptr; 2505 } 2506 2507 namespace { 2508 class LocalVarRefChecker final 2509 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2510 Sema &SemaRef; 2511 2512 public: 2513 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2514 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2515 if (VD->hasLocalStorage()) { 2516 SemaRef.Diag(E->getBeginLoc(), 2517 diag::err_omp_local_var_in_threadprivate_init) 2518 << E->getSourceRange(); 2519 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2520 << VD << VD->getSourceRange(); 2521 return true; 2522 } 2523 } 2524 return false; 2525 } 2526 bool VisitStmt(const Stmt *S) { 2527 for (const Stmt *Child : S->children()) { 2528 if (Child && Visit(Child)) 2529 return true; 2530 } 2531 return false; 2532 } 2533 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2534 }; 2535 } // namespace 2536 2537 OMPThreadPrivateDecl * 2538 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2539 SmallVector<Expr *, 8> Vars; 2540 for (Expr *RefExpr : VarList) { 2541 auto *DE = cast<DeclRefExpr>(RefExpr); 2542 auto *VD = cast<VarDecl>(DE->getDecl()); 2543 SourceLocation ILoc = DE->getExprLoc(); 2544 2545 // Mark variable as used. 2546 VD->setReferenced(); 2547 VD->markUsed(Context); 2548 2549 QualType QType = VD->getType(); 2550 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2551 // It will be analyzed later. 2552 Vars.push_back(DE); 2553 continue; 2554 } 2555 2556 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2557 // A threadprivate variable must not have an incomplete type. 2558 if (RequireCompleteType(ILoc, VD->getType(), 2559 diag::err_omp_threadprivate_incomplete_type)) { 2560 continue; 2561 } 2562 2563 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2564 // A threadprivate variable must not have a reference type. 2565 if (VD->getType()->isReferenceType()) { 2566 Diag(ILoc, diag::err_omp_ref_type_arg) 2567 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2568 bool IsDecl = 2569 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2570 Diag(VD->getLocation(), 2571 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2572 << VD; 2573 continue; 2574 } 2575 2576 // Check if this is a TLS variable. If TLS is not being supported, produce 2577 // the corresponding diagnostic. 2578 if ((VD->getTLSKind() != VarDecl::TLS_None && 2579 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2580 getLangOpts().OpenMPUseTLS && 2581 getASTContext().getTargetInfo().isTLSSupported())) || 2582 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2583 !VD->isLocalVarDecl())) { 2584 Diag(ILoc, diag::err_omp_var_thread_local) 2585 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2586 bool IsDecl = 2587 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2588 Diag(VD->getLocation(), 2589 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2590 << VD; 2591 continue; 2592 } 2593 2594 // Check if initial value of threadprivate variable reference variable with 2595 // local storage (it is not supported by runtime). 2596 if (const Expr *Init = VD->getAnyInitializer()) { 2597 LocalVarRefChecker Checker(*this); 2598 if (Checker.Visit(Init)) 2599 continue; 2600 } 2601 2602 Vars.push_back(RefExpr); 2603 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2604 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2605 Context, SourceRange(Loc, Loc))); 2606 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2607 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2608 } 2609 OMPThreadPrivateDecl *D = nullptr; 2610 if (!Vars.empty()) { 2611 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2612 Vars); 2613 D->setAccess(AS_public); 2614 } 2615 return D; 2616 } 2617 2618 static OMPAllocateDeclAttr::AllocatorTypeTy 2619 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2620 if (!Allocator) 2621 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2622 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2623 Allocator->isInstantiationDependent() || 2624 Allocator->containsUnexpandedParameterPack()) 2625 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2626 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2627 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2628 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2629 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2630 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2631 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2632 llvm::FoldingSetNodeID AEId, DAEId; 2633 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2634 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2635 if (AEId == DAEId) { 2636 AllocatorKindRes = AllocatorKind; 2637 break; 2638 } 2639 } 2640 return AllocatorKindRes; 2641 } 2642 2643 static bool checkPreviousOMPAllocateAttribute( 2644 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2645 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2646 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2647 return false; 2648 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2649 Expr *PrevAllocator = A->getAllocator(); 2650 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2651 getAllocatorKind(S, Stack, PrevAllocator); 2652 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2653 if (AllocatorsMatch && 2654 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2655 Allocator && PrevAllocator) { 2656 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2657 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2658 llvm::FoldingSetNodeID AEId, PAEId; 2659 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2660 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2661 AllocatorsMatch = AEId == PAEId; 2662 } 2663 if (!AllocatorsMatch) { 2664 SmallString<256> AllocatorBuffer; 2665 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2666 if (Allocator) 2667 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2668 SmallString<256> PrevAllocatorBuffer; 2669 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2670 if (PrevAllocator) 2671 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2672 S.getPrintingPolicy()); 2673 2674 SourceLocation AllocatorLoc = 2675 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2676 SourceRange AllocatorRange = 2677 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2678 SourceLocation PrevAllocatorLoc = 2679 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2680 SourceRange PrevAllocatorRange = 2681 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2682 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2683 << (Allocator ? 1 : 0) << AllocatorStream.str() 2684 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2685 << AllocatorRange; 2686 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2687 << PrevAllocatorRange; 2688 return true; 2689 } 2690 return false; 2691 } 2692 2693 static void 2694 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2695 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2696 Expr *Allocator, SourceRange SR) { 2697 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2698 return; 2699 if (Allocator && 2700 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2701 Allocator->isInstantiationDependent() || 2702 Allocator->containsUnexpandedParameterPack())) 2703 return; 2704 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2705 Allocator, SR); 2706 VD->addAttr(A); 2707 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2708 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2709 } 2710 2711 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2712 SourceLocation Loc, ArrayRef<Expr *> VarList, 2713 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2714 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2715 Expr *Allocator = nullptr; 2716 if (Clauses.empty()) { 2717 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2718 // allocate directives that appear in a target region must specify an 2719 // allocator clause unless a requires directive with the dynamic_allocators 2720 // clause is present in the same compilation unit. 2721 if (LangOpts.OpenMPIsDevice && 2722 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2723 targetDiag(Loc, diag::err_expected_allocator_clause); 2724 } else { 2725 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2726 } 2727 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2728 getAllocatorKind(*this, DSAStack, Allocator); 2729 SmallVector<Expr *, 8> Vars; 2730 for (Expr *RefExpr : VarList) { 2731 auto *DE = cast<DeclRefExpr>(RefExpr); 2732 auto *VD = cast<VarDecl>(DE->getDecl()); 2733 2734 // Check if this is a TLS variable or global register. 2735 if (VD->getTLSKind() != VarDecl::TLS_None || 2736 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2737 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2738 !VD->isLocalVarDecl())) 2739 continue; 2740 2741 // If the used several times in the allocate directive, the same allocator 2742 // must be used. 2743 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2744 AllocatorKind, Allocator)) 2745 continue; 2746 2747 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2748 // If a list item has a static storage type, the allocator expression in the 2749 // allocator clause must be a constant expression that evaluates to one of 2750 // the predefined memory allocator values. 2751 if (Allocator && VD->hasGlobalStorage()) { 2752 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2753 Diag(Allocator->getExprLoc(), 2754 diag::err_omp_expected_predefined_allocator) 2755 << Allocator->getSourceRange(); 2756 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2757 VarDecl::DeclarationOnly; 2758 Diag(VD->getLocation(), 2759 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2760 << VD; 2761 continue; 2762 } 2763 } 2764 2765 Vars.push_back(RefExpr); 2766 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2767 DE->getSourceRange()); 2768 } 2769 if (Vars.empty()) 2770 return nullptr; 2771 if (!Owner) 2772 Owner = getCurLexicalContext(); 2773 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2774 D->setAccess(AS_public); 2775 Owner->addDecl(D); 2776 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2777 } 2778 2779 Sema::DeclGroupPtrTy 2780 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2781 ArrayRef<OMPClause *> ClauseList) { 2782 OMPRequiresDecl *D = nullptr; 2783 if (!CurContext->isFileContext()) { 2784 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2785 } else { 2786 D = CheckOMPRequiresDecl(Loc, ClauseList); 2787 if (D) { 2788 CurContext->addDecl(D); 2789 DSAStack->addRequiresDecl(D); 2790 } 2791 } 2792 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2793 } 2794 2795 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2796 ArrayRef<OMPClause *> ClauseList) { 2797 /// For target specific clauses, the requires directive cannot be 2798 /// specified after the handling of any of the target regions in the 2799 /// current compilation unit. 2800 ArrayRef<SourceLocation> TargetLocations = 2801 DSAStack->getEncounteredTargetLocs(); 2802 if (!TargetLocations.empty()) { 2803 for (const OMPClause *CNew : ClauseList) { 2804 // Check if any of the requires clauses affect target regions. 2805 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2806 isa<OMPUnifiedAddressClause>(CNew) || 2807 isa<OMPReverseOffloadClause>(CNew) || 2808 isa<OMPDynamicAllocatorsClause>(CNew)) { 2809 Diag(Loc, diag::err_omp_target_before_requires) 2810 << getOpenMPClauseName(CNew->getClauseKind()); 2811 for (SourceLocation TargetLoc : TargetLocations) { 2812 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2813 } 2814 } 2815 } 2816 } 2817 2818 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2819 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2820 ClauseList); 2821 return nullptr; 2822 } 2823 2824 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2825 const ValueDecl *D, 2826 const DSAStackTy::DSAVarData &DVar, 2827 bool IsLoopIterVar = false) { 2828 if (DVar.RefExpr) { 2829 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2830 << getOpenMPClauseName(DVar.CKind); 2831 return; 2832 } 2833 enum { 2834 PDSA_StaticMemberShared, 2835 PDSA_StaticLocalVarShared, 2836 PDSA_LoopIterVarPrivate, 2837 PDSA_LoopIterVarLinear, 2838 PDSA_LoopIterVarLastprivate, 2839 PDSA_ConstVarShared, 2840 PDSA_GlobalVarShared, 2841 PDSA_TaskVarFirstprivate, 2842 PDSA_LocalVarPrivate, 2843 PDSA_Implicit 2844 } Reason = PDSA_Implicit; 2845 bool ReportHint = false; 2846 auto ReportLoc = D->getLocation(); 2847 auto *VD = dyn_cast<VarDecl>(D); 2848 if (IsLoopIterVar) { 2849 if (DVar.CKind == OMPC_private) 2850 Reason = PDSA_LoopIterVarPrivate; 2851 else if (DVar.CKind == OMPC_lastprivate) 2852 Reason = PDSA_LoopIterVarLastprivate; 2853 else 2854 Reason = PDSA_LoopIterVarLinear; 2855 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2856 DVar.CKind == OMPC_firstprivate) { 2857 Reason = PDSA_TaskVarFirstprivate; 2858 ReportLoc = DVar.ImplicitDSALoc; 2859 } else if (VD && VD->isStaticLocal()) 2860 Reason = PDSA_StaticLocalVarShared; 2861 else if (VD && VD->isStaticDataMember()) 2862 Reason = PDSA_StaticMemberShared; 2863 else if (VD && VD->isFileVarDecl()) 2864 Reason = PDSA_GlobalVarShared; 2865 else if (D->getType().isConstant(SemaRef.getASTContext())) 2866 Reason = PDSA_ConstVarShared; 2867 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2868 ReportHint = true; 2869 Reason = PDSA_LocalVarPrivate; 2870 } 2871 if (Reason != PDSA_Implicit) { 2872 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2873 << Reason << ReportHint 2874 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2875 } else if (DVar.ImplicitDSALoc.isValid()) { 2876 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2877 << getOpenMPClauseName(DVar.CKind); 2878 } 2879 } 2880 2881 static OpenMPMapClauseKind 2882 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2883 bool IsAggregateOrDeclareTarget) { 2884 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2885 switch (M) { 2886 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2887 Kind = OMPC_MAP_alloc; 2888 break; 2889 case OMPC_DEFAULTMAP_MODIFIER_to: 2890 Kind = OMPC_MAP_to; 2891 break; 2892 case OMPC_DEFAULTMAP_MODIFIER_from: 2893 Kind = OMPC_MAP_from; 2894 break; 2895 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2896 Kind = OMPC_MAP_tofrom; 2897 break; 2898 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2899 case OMPC_DEFAULTMAP_MODIFIER_last: 2900 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2901 case OMPC_DEFAULTMAP_MODIFIER_none: 2902 case OMPC_DEFAULTMAP_MODIFIER_default: 2903 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2904 // IsAggregateOrDeclareTarget could be true if: 2905 // 1. the implicit behavior for aggregate is tofrom 2906 // 2. it's a declare target link 2907 if (IsAggregateOrDeclareTarget) { 2908 Kind = OMPC_MAP_tofrom; 2909 break; 2910 } 2911 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2912 } 2913 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2914 return Kind; 2915 } 2916 2917 namespace { 2918 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2919 DSAStackTy *Stack; 2920 Sema &SemaRef; 2921 bool ErrorFound = false; 2922 bool TryCaptureCXXThisMembers = false; 2923 CapturedStmt *CS = nullptr; 2924 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2925 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2926 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2927 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2928 2929 void VisitSubCaptures(OMPExecutableDirective *S) { 2930 // Check implicitly captured variables. 2931 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2932 return; 2933 visitSubCaptures(S->getInnermostCapturedStmt()); 2934 // Try to capture inner this->member references to generate correct mappings 2935 // and diagnostics. 2936 if (TryCaptureCXXThisMembers || 2937 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2938 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2939 [](const CapturedStmt::Capture &C) { 2940 return C.capturesThis(); 2941 }))) { 2942 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2943 TryCaptureCXXThisMembers = true; 2944 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2945 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2946 } 2947 } 2948 2949 public: 2950 void VisitDeclRefExpr(DeclRefExpr *E) { 2951 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2952 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2953 E->isInstantiationDependent()) 2954 return; 2955 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2956 // Check the datasharing rules for the expressions in the clauses. 2957 if (!CS) { 2958 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2959 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2960 Visit(CED->getInit()); 2961 return; 2962 } 2963 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2964 // Do not analyze internal variables and do not enclose them into 2965 // implicit clauses. 2966 return; 2967 VD = VD->getCanonicalDecl(); 2968 // Skip internally declared variables. 2969 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2970 return; 2971 2972 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2973 // Check if the variable has explicit DSA set and stop analysis if it so. 2974 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2975 return; 2976 2977 // Skip internally declared static variables. 2978 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2979 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2980 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2981 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2982 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2983 return; 2984 2985 SourceLocation ELoc = E->getExprLoc(); 2986 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2987 // The default(none) clause requires that each variable that is referenced 2988 // in the construct, and does not have a predetermined data-sharing 2989 // attribute, must have its data-sharing attribute explicitly determined 2990 // by being listed in a data-sharing attribute clause. 2991 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2992 isImplicitOrExplicitTaskingRegion(DKind) && 2993 VarsWithInheritedDSA.count(VD) == 0) { 2994 VarsWithInheritedDSA[VD] = E; 2995 return; 2996 } 2997 2998 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 2999 // If implicit-behavior is none, each variable referenced in the 3000 // construct that does not have a predetermined data-sharing attribute 3001 // and does not appear in a to or link clause on a declare target 3002 // directive must be listed in a data-mapping attribute clause, a 3003 // data-haring attribute clause (including a data-sharing attribute 3004 // clause on a combined construct where target. is one of the 3005 // constituent constructs), or an is_device_ptr clause. 3006 OpenMPDefaultmapClauseKind ClauseKind = 3007 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3008 if (SemaRef.getLangOpts().OpenMP >= 50) { 3009 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3010 OMPC_DEFAULTMAP_MODIFIER_none; 3011 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3012 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3013 // Only check for data-mapping attribute and is_device_ptr here 3014 // since we have already make sure that the declaration does not 3015 // have a data-sharing attribute above 3016 if (!Stack->checkMappableExprComponentListsForDecl( 3017 VD, /*CurrentRegionOnly=*/true, 3018 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3019 MapExprComponents, 3020 OpenMPClauseKind) { 3021 auto MI = MapExprComponents.rbegin(); 3022 auto ME = MapExprComponents.rend(); 3023 return MI != ME && MI->getAssociatedDeclaration() == VD; 3024 })) { 3025 VarsWithInheritedDSA[VD] = E; 3026 return; 3027 } 3028 } 3029 } 3030 3031 if (isOpenMPTargetExecutionDirective(DKind) && 3032 !Stack->isLoopControlVariable(VD).first) { 3033 if (!Stack->checkMappableExprComponentListsForDecl( 3034 VD, /*CurrentRegionOnly=*/true, 3035 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3036 StackComponents, 3037 OpenMPClauseKind) { 3038 // Variable is used if it has been marked as an array, array 3039 // section or the variable iself. 3040 return StackComponents.size() == 1 || 3041 std::all_of( 3042 std::next(StackComponents.rbegin()), 3043 StackComponents.rend(), 3044 [](const OMPClauseMappableExprCommon:: 3045 MappableComponent &MC) { 3046 return MC.getAssociatedDeclaration() == 3047 nullptr && 3048 (isa<OMPArraySectionExpr>( 3049 MC.getAssociatedExpression()) || 3050 isa<ArraySubscriptExpr>( 3051 MC.getAssociatedExpression())); 3052 }); 3053 })) { 3054 bool IsFirstprivate = false; 3055 // By default lambdas are captured as firstprivates. 3056 if (const auto *RD = 3057 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3058 IsFirstprivate = RD->isLambda(); 3059 IsFirstprivate = 3060 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3061 if (IsFirstprivate) { 3062 ImplicitFirstprivate.emplace_back(E); 3063 } else { 3064 OpenMPDefaultmapClauseModifier M = 3065 Stack->getDefaultmapModifier(ClauseKind); 3066 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3067 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3068 ImplicitMap[Kind].emplace_back(E); 3069 } 3070 return; 3071 } 3072 } 3073 3074 // OpenMP [2.9.3.6, Restrictions, p.2] 3075 // A list item that appears in a reduction clause of the innermost 3076 // enclosing worksharing or parallel construct may not be accessed in an 3077 // explicit task. 3078 DVar = Stack->hasInnermostDSA( 3079 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3080 [](OpenMPDirectiveKind K) { 3081 return isOpenMPParallelDirective(K) || 3082 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3083 }, 3084 /*FromParent=*/true); 3085 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3086 ErrorFound = true; 3087 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3088 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3089 return; 3090 } 3091 3092 // Define implicit data-sharing attributes for task. 3093 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3094 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3095 !Stack->isLoopControlVariable(VD).first) { 3096 ImplicitFirstprivate.push_back(E); 3097 return; 3098 } 3099 3100 // Store implicitly used globals with declare target link for parent 3101 // target. 3102 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3103 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3104 Stack->addToParentTargetRegionLinkGlobals(E); 3105 return; 3106 } 3107 } 3108 } 3109 void VisitMemberExpr(MemberExpr *E) { 3110 if (E->isTypeDependent() || E->isValueDependent() || 3111 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3112 return; 3113 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3114 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3115 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3116 if (!FD) 3117 return; 3118 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3119 // Check if the variable has explicit DSA set and stop analysis if it 3120 // so. 3121 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3122 return; 3123 3124 if (isOpenMPTargetExecutionDirective(DKind) && 3125 !Stack->isLoopControlVariable(FD).first && 3126 !Stack->checkMappableExprComponentListsForDecl( 3127 FD, /*CurrentRegionOnly=*/true, 3128 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3129 StackComponents, 3130 OpenMPClauseKind) { 3131 return isa<CXXThisExpr>( 3132 cast<MemberExpr>( 3133 StackComponents.back().getAssociatedExpression()) 3134 ->getBase() 3135 ->IgnoreParens()); 3136 })) { 3137 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3138 // A bit-field cannot appear in a map clause. 3139 // 3140 if (FD->isBitField()) 3141 return; 3142 3143 // Check to see if the member expression is referencing a class that 3144 // has already been explicitly mapped 3145 if (Stack->isClassPreviouslyMapped(TE->getType())) 3146 return; 3147 3148 OpenMPDefaultmapClauseModifier Modifier = 3149 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3150 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3151 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3152 ImplicitMap[Kind].emplace_back(E); 3153 return; 3154 } 3155 3156 SourceLocation ELoc = E->getExprLoc(); 3157 // OpenMP [2.9.3.6, Restrictions, p.2] 3158 // A list item that appears in a reduction clause of the innermost 3159 // enclosing worksharing or parallel construct may not be accessed in 3160 // an explicit task. 3161 DVar = Stack->hasInnermostDSA( 3162 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3163 [](OpenMPDirectiveKind K) { 3164 return isOpenMPParallelDirective(K) || 3165 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3166 }, 3167 /*FromParent=*/true); 3168 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3169 ErrorFound = true; 3170 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3171 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3172 return; 3173 } 3174 3175 // Define implicit data-sharing attributes for task. 3176 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3177 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3178 !Stack->isLoopControlVariable(FD).first) { 3179 // Check if there is a captured expression for the current field in the 3180 // region. Do not mark it as firstprivate unless there is no captured 3181 // expression. 3182 // TODO: try to make it firstprivate. 3183 if (DVar.CKind != OMPC_unknown) 3184 ImplicitFirstprivate.push_back(E); 3185 } 3186 return; 3187 } 3188 if (isOpenMPTargetExecutionDirective(DKind)) { 3189 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3190 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3191 /*NoDiagnose=*/true)) 3192 return; 3193 const auto *VD = cast<ValueDecl>( 3194 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3195 if (!Stack->checkMappableExprComponentListsForDecl( 3196 VD, /*CurrentRegionOnly=*/true, 3197 [&CurComponents]( 3198 OMPClauseMappableExprCommon::MappableExprComponentListRef 3199 StackComponents, 3200 OpenMPClauseKind) { 3201 auto CCI = CurComponents.rbegin(); 3202 auto CCE = CurComponents.rend(); 3203 for (const auto &SC : llvm::reverse(StackComponents)) { 3204 // Do both expressions have the same kind? 3205 if (CCI->getAssociatedExpression()->getStmtClass() != 3206 SC.getAssociatedExpression()->getStmtClass()) 3207 if (!(isa<OMPArraySectionExpr>( 3208 SC.getAssociatedExpression()) && 3209 isa<ArraySubscriptExpr>( 3210 CCI->getAssociatedExpression()))) 3211 return false; 3212 3213 const Decl *CCD = CCI->getAssociatedDeclaration(); 3214 const Decl *SCD = SC.getAssociatedDeclaration(); 3215 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3216 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3217 if (SCD != CCD) 3218 return false; 3219 std::advance(CCI, 1); 3220 if (CCI == CCE) 3221 break; 3222 } 3223 return true; 3224 })) { 3225 Visit(E->getBase()); 3226 } 3227 } else if (!TryCaptureCXXThisMembers) { 3228 Visit(E->getBase()); 3229 } 3230 } 3231 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3232 for (OMPClause *C : S->clauses()) { 3233 // Skip analysis of arguments of implicitly defined firstprivate clause 3234 // for task|target directives. 3235 // Skip analysis of arguments of implicitly defined map clause for target 3236 // directives. 3237 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3238 C->isImplicit())) { 3239 for (Stmt *CC : C->children()) { 3240 if (CC) 3241 Visit(CC); 3242 } 3243 } 3244 } 3245 // Check implicitly captured variables. 3246 VisitSubCaptures(S); 3247 } 3248 void VisitStmt(Stmt *S) { 3249 for (Stmt *C : S->children()) { 3250 if (C) { 3251 // Check implicitly captured variables in the task-based directives to 3252 // check if they must be firstprivatized. 3253 Visit(C); 3254 } 3255 } 3256 } 3257 3258 void visitSubCaptures(CapturedStmt *S) { 3259 for (const CapturedStmt::Capture &Cap : S->captures()) { 3260 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3261 continue; 3262 VarDecl *VD = Cap.getCapturedVar(); 3263 // Do not try to map the variable if it or its sub-component was mapped 3264 // already. 3265 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3266 Stack->checkMappableExprComponentListsForDecl( 3267 VD, /*CurrentRegionOnly=*/true, 3268 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3269 OpenMPClauseKind) { return true; })) 3270 continue; 3271 DeclRefExpr *DRE = buildDeclRefExpr( 3272 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3273 Cap.getLocation(), /*RefersToCapture=*/true); 3274 Visit(DRE); 3275 } 3276 } 3277 bool isErrorFound() const { return ErrorFound; } 3278 ArrayRef<Expr *> getImplicitFirstprivate() const { 3279 return ImplicitFirstprivate; 3280 } 3281 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3282 return ImplicitMap[Kind]; 3283 } 3284 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3285 return VarsWithInheritedDSA; 3286 } 3287 3288 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3289 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3290 // Process declare target link variables for the target directives. 3291 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3292 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3293 Visit(E); 3294 } 3295 } 3296 }; 3297 } // namespace 3298 3299 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3300 switch (DKind) { 3301 case OMPD_parallel: 3302 case OMPD_parallel_for: 3303 case OMPD_parallel_for_simd: 3304 case OMPD_parallel_sections: 3305 case OMPD_parallel_master: 3306 case OMPD_teams: 3307 case OMPD_teams_distribute: 3308 case OMPD_teams_distribute_simd: { 3309 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3310 QualType KmpInt32PtrTy = 3311 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3312 Sema::CapturedParamNameType Params[] = { 3313 std::make_pair(".global_tid.", KmpInt32PtrTy), 3314 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3315 std::make_pair(StringRef(), QualType()) // __context with shared vars 3316 }; 3317 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3318 Params); 3319 break; 3320 } 3321 case OMPD_target_teams: 3322 case OMPD_target_parallel: 3323 case OMPD_target_parallel_for: 3324 case OMPD_target_parallel_for_simd: 3325 case OMPD_target_teams_distribute: 3326 case OMPD_target_teams_distribute_simd: { 3327 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3328 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3329 QualType KmpInt32PtrTy = 3330 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3331 QualType Args[] = {VoidPtrTy}; 3332 FunctionProtoType::ExtProtoInfo EPI; 3333 EPI.Variadic = true; 3334 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3335 Sema::CapturedParamNameType Params[] = { 3336 std::make_pair(".global_tid.", KmpInt32Ty), 3337 std::make_pair(".part_id.", KmpInt32PtrTy), 3338 std::make_pair(".privates.", VoidPtrTy), 3339 std::make_pair( 3340 ".copy_fn.", 3341 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3342 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3343 std::make_pair(StringRef(), QualType()) // __context with shared vars 3344 }; 3345 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3346 Params, /*OpenMPCaptureLevel=*/0); 3347 // Mark this captured region as inlined, because we don't use outlined 3348 // function directly. 3349 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3350 AlwaysInlineAttr::CreateImplicit( 3351 Context, {}, AttributeCommonInfo::AS_Keyword, 3352 AlwaysInlineAttr::Keyword_forceinline)); 3353 Sema::CapturedParamNameType ParamsTarget[] = { 3354 std::make_pair(StringRef(), QualType()) // __context with shared vars 3355 }; 3356 // Start a captured region for 'target' with no implicit parameters. 3357 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3358 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3359 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3360 std::make_pair(".global_tid.", KmpInt32PtrTy), 3361 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3362 std::make_pair(StringRef(), QualType()) // __context with shared vars 3363 }; 3364 // Start a captured region for 'teams' or 'parallel'. Both regions have 3365 // the same implicit parameters. 3366 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3367 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3368 break; 3369 } 3370 case OMPD_target: 3371 case OMPD_target_simd: { 3372 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3373 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3374 QualType KmpInt32PtrTy = 3375 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3376 QualType Args[] = {VoidPtrTy}; 3377 FunctionProtoType::ExtProtoInfo EPI; 3378 EPI.Variadic = true; 3379 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3380 Sema::CapturedParamNameType Params[] = { 3381 std::make_pair(".global_tid.", KmpInt32Ty), 3382 std::make_pair(".part_id.", KmpInt32PtrTy), 3383 std::make_pair(".privates.", VoidPtrTy), 3384 std::make_pair( 3385 ".copy_fn.", 3386 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3387 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3388 std::make_pair(StringRef(), QualType()) // __context with shared vars 3389 }; 3390 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3391 Params, /*OpenMPCaptureLevel=*/0); 3392 // Mark this captured region as inlined, because we don't use outlined 3393 // function directly. 3394 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3395 AlwaysInlineAttr::CreateImplicit( 3396 Context, {}, AttributeCommonInfo::AS_Keyword, 3397 AlwaysInlineAttr::Keyword_forceinline)); 3398 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3399 std::make_pair(StringRef(), QualType()), 3400 /*OpenMPCaptureLevel=*/1); 3401 break; 3402 } 3403 case OMPD_simd: 3404 case OMPD_for: 3405 case OMPD_for_simd: 3406 case OMPD_sections: 3407 case OMPD_section: 3408 case OMPD_single: 3409 case OMPD_master: 3410 case OMPD_critical: 3411 case OMPD_taskgroup: 3412 case OMPD_distribute: 3413 case OMPD_distribute_simd: 3414 case OMPD_ordered: 3415 case OMPD_atomic: 3416 case OMPD_target_data: { 3417 Sema::CapturedParamNameType Params[] = { 3418 std::make_pair(StringRef(), QualType()) // __context with shared vars 3419 }; 3420 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3421 Params); 3422 break; 3423 } 3424 case OMPD_task: { 3425 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3426 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3427 QualType KmpInt32PtrTy = 3428 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3429 QualType Args[] = {VoidPtrTy}; 3430 FunctionProtoType::ExtProtoInfo EPI; 3431 EPI.Variadic = true; 3432 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3433 Sema::CapturedParamNameType Params[] = { 3434 std::make_pair(".global_tid.", KmpInt32Ty), 3435 std::make_pair(".part_id.", KmpInt32PtrTy), 3436 std::make_pair(".privates.", VoidPtrTy), 3437 std::make_pair( 3438 ".copy_fn.", 3439 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3440 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3441 std::make_pair(StringRef(), QualType()) // __context with shared vars 3442 }; 3443 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3444 Params); 3445 // Mark this captured region as inlined, because we don't use outlined 3446 // function directly. 3447 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3448 AlwaysInlineAttr::CreateImplicit( 3449 Context, {}, AttributeCommonInfo::AS_Keyword, 3450 AlwaysInlineAttr::Keyword_forceinline)); 3451 break; 3452 } 3453 case OMPD_taskloop: 3454 case OMPD_taskloop_simd: 3455 case OMPD_master_taskloop: 3456 case OMPD_master_taskloop_simd: { 3457 QualType KmpInt32Ty = 3458 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3459 .withConst(); 3460 QualType KmpUInt64Ty = 3461 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3462 .withConst(); 3463 QualType KmpInt64Ty = 3464 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3465 .withConst(); 3466 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3467 QualType KmpInt32PtrTy = 3468 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3469 QualType Args[] = {VoidPtrTy}; 3470 FunctionProtoType::ExtProtoInfo EPI; 3471 EPI.Variadic = true; 3472 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3473 Sema::CapturedParamNameType Params[] = { 3474 std::make_pair(".global_tid.", KmpInt32Ty), 3475 std::make_pair(".part_id.", KmpInt32PtrTy), 3476 std::make_pair(".privates.", VoidPtrTy), 3477 std::make_pair( 3478 ".copy_fn.", 3479 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3480 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3481 std::make_pair(".lb.", KmpUInt64Ty), 3482 std::make_pair(".ub.", KmpUInt64Ty), 3483 std::make_pair(".st.", KmpInt64Ty), 3484 std::make_pair(".liter.", KmpInt32Ty), 3485 std::make_pair(".reductions.", VoidPtrTy), 3486 std::make_pair(StringRef(), QualType()) // __context with shared vars 3487 }; 3488 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3489 Params); 3490 // Mark this captured region as inlined, because we don't use outlined 3491 // function directly. 3492 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3493 AlwaysInlineAttr::CreateImplicit( 3494 Context, {}, AttributeCommonInfo::AS_Keyword, 3495 AlwaysInlineAttr::Keyword_forceinline)); 3496 break; 3497 } 3498 case OMPD_parallel_master_taskloop: 3499 case OMPD_parallel_master_taskloop_simd: { 3500 QualType KmpInt32Ty = 3501 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3502 .withConst(); 3503 QualType KmpUInt64Ty = 3504 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3505 .withConst(); 3506 QualType KmpInt64Ty = 3507 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3508 .withConst(); 3509 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3510 QualType KmpInt32PtrTy = 3511 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3512 Sema::CapturedParamNameType ParamsParallel[] = { 3513 std::make_pair(".global_tid.", KmpInt32PtrTy), 3514 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3515 std::make_pair(StringRef(), QualType()) // __context with shared vars 3516 }; 3517 // Start a captured region for 'parallel'. 3518 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3519 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3520 QualType Args[] = {VoidPtrTy}; 3521 FunctionProtoType::ExtProtoInfo EPI; 3522 EPI.Variadic = true; 3523 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3524 Sema::CapturedParamNameType Params[] = { 3525 std::make_pair(".global_tid.", KmpInt32Ty), 3526 std::make_pair(".part_id.", KmpInt32PtrTy), 3527 std::make_pair(".privates.", VoidPtrTy), 3528 std::make_pair( 3529 ".copy_fn.", 3530 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3531 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3532 std::make_pair(".lb.", KmpUInt64Ty), 3533 std::make_pair(".ub.", KmpUInt64Ty), 3534 std::make_pair(".st.", KmpInt64Ty), 3535 std::make_pair(".liter.", KmpInt32Ty), 3536 std::make_pair(".reductions.", VoidPtrTy), 3537 std::make_pair(StringRef(), QualType()) // __context with shared vars 3538 }; 3539 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3540 Params, /*OpenMPCaptureLevel=*/2); 3541 // Mark this captured region as inlined, because we don't use outlined 3542 // function directly. 3543 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3544 AlwaysInlineAttr::CreateImplicit( 3545 Context, {}, AttributeCommonInfo::AS_Keyword, 3546 AlwaysInlineAttr::Keyword_forceinline)); 3547 break; 3548 } 3549 case OMPD_distribute_parallel_for_simd: 3550 case OMPD_distribute_parallel_for: { 3551 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3552 QualType KmpInt32PtrTy = 3553 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3554 Sema::CapturedParamNameType Params[] = { 3555 std::make_pair(".global_tid.", KmpInt32PtrTy), 3556 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3557 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3558 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3559 std::make_pair(StringRef(), QualType()) // __context with shared vars 3560 }; 3561 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3562 Params); 3563 break; 3564 } 3565 case OMPD_target_teams_distribute_parallel_for: 3566 case OMPD_target_teams_distribute_parallel_for_simd: { 3567 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3568 QualType KmpInt32PtrTy = 3569 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3570 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3571 3572 QualType Args[] = {VoidPtrTy}; 3573 FunctionProtoType::ExtProtoInfo EPI; 3574 EPI.Variadic = true; 3575 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3576 Sema::CapturedParamNameType Params[] = { 3577 std::make_pair(".global_tid.", KmpInt32Ty), 3578 std::make_pair(".part_id.", KmpInt32PtrTy), 3579 std::make_pair(".privates.", VoidPtrTy), 3580 std::make_pair( 3581 ".copy_fn.", 3582 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3583 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3584 std::make_pair(StringRef(), QualType()) // __context with shared vars 3585 }; 3586 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3587 Params, /*OpenMPCaptureLevel=*/0); 3588 // Mark this captured region as inlined, because we don't use outlined 3589 // function directly. 3590 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3591 AlwaysInlineAttr::CreateImplicit( 3592 Context, {}, AttributeCommonInfo::AS_Keyword, 3593 AlwaysInlineAttr::Keyword_forceinline)); 3594 Sema::CapturedParamNameType ParamsTarget[] = { 3595 std::make_pair(StringRef(), QualType()) // __context with shared vars 3596 }; 3597 // Start a captured region for 'target' with no implicit parameters. 3598 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3599 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3600 3601 Sema::CapturedParamNameType ParamsTeams[] = { 3602 std::make_pair(".global_tid.", KmpInt32PtrTy), 3603 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3604 std::make_pair(StringRef(), QualType()) // __context with shared vars 3605 }; 3606 // Start a captured region for 'target' with no implicit parameters. 3607 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3608 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3609 3610 Sema::CapturedParamNameType ParamsParallel[] = { 3611 std::make_pair(".global_tid.", KmpInt32PtrTy), 3612 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3613 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3614 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3615 std::make_pair(StringRef(), QualType()) // __context with shared vars 3616 }; 3617 // Start a captured region for 'teams' or 'parallel'. Both regions have 3618 // the same implicit parameters. 3619 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3620 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3621 break; 3622 } 3623 3624 case OMPD_teams_distribute_parallel_for: 3625 case OMPD_teams_distribute_parallel_for_simd: { 3626 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3627 QualType KmpInt32PtrTy = 3628 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3629 3630 Sema::CapturedParamNameType ParamsTeams[] = { 3631 std::make_pair(".global_tid.", KmpInt32PtrTy), 3632 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3633 std::make_pair(StringRef(), QualType()) // __context with shared vars 3634 }; 3635 // Start a captured region for 'target' with no implicit parameters. 3636 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3637 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3638 3639 Sema::CapturedParamNameType ParamsParallel[] = { 3640 std::make_pair(".global_tid.", KmpInt32PtrTy), 3641 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3642 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3643 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3644 std::make_pair(StringRef(), QualType()) // __context with shared vars 3645 }; 3646 // Start a captured region for 'teams' or 'parallel'. Both regions have 3647 // the same implicit parameters. 3648 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3649 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3650 break; 3651 } 3652 case OMPD_target_update: 3653 case OMPD_target_enter_data: 3654 case OMPD_target_exit_data: { 3655 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3656 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3657 QualType KmpInt32PtrTy = 3658 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3659 QualType Args[] = {VoidPtrTy}; 3660 FunctionProtoType::ExtProtoInfo EPI; 3661 EPI.Variadic = true; 3662 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3663 Sema::CapturedParamNameType Params[] = { 3664 std::make_pair(".global_tid.", KmpInt32Ty), 3665 std::make_pair(".part_id.", KmpInt32PtrTy), 3666 std::make_pair(".privates.", VoidPtrTy), 3667 std::make_pair( 3668 ".copy_fn.", 3669 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3670 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3671 std::make_pair(StringRef(), QualType()) // __context with shared vars 3672 }; 3673 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3674 Params); 3675 // Mark this captured region as inlined, because we don't use outlined 3676 // function directly. 3677 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3678 AlwaysInlineAttr::CreateImplicit( 3679 Context, {}, AttributeCommonInfo::AS_Keyword, 3680 AlwaysInlineAttr::Keyword_forceinline)); 3681 break; 3682 } 3683 case OMPD_threadprivate: 3684 case OMPD_allocate: 3685 case OMPD_taskyield: 3686 case OMPD_barrier: 3687 case OMPD_taskwait: 3688 case OMPD_cancellation_point: 3689 case OMPD_cancel: 3690 case OMPD_flush: 3691 case OMPD_declare_reduction: 3692 case OMPD_declare_mapper: 3693 case OMPD_declare_simd: 3694 case OMPD_declare_target: 3695 case OMPD_end_declare_target: 3696 case OMPD_requires: 3697 case OMPD_declare_variant: 3698 llvm_unreachable("OpenMP Directive is not allowed"); 3699 case OMPD_unknown: 3700 llvm_unreachable("Unknown OpenMP directive"); 3701 } 3702 } 3703 3704 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3705 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3706 } 3707 3708 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3709 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3710 getOpenMPCaptureRegions(CaptureRegions, DKind); 3711 return CaptureRegions.size(); 3712 } 3713 3714 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3715 Expr *CaptureExpr, bool WithInit, 3716 bool AsExpression) { 3717 assert(CaptureExpr); 3718 ASTContext &C = S.getASTContext(); 3719 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3720 QualType Ty = Init->getType(); 3721 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3722 if (S.getLangOpts().CPlusPlus) { 3723 Ty = C.getLValueReferenceType(Ty); 3724 } else { 3725 Ty = C.getPointerType(Ty); 3726 ExprResult Res = 3727 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3728 if (!Res.isUsable()) 3729 return nullptr; 3730 Init = Res.get(); 3731 } 3732 WithInit = true; 3733 } 3734 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3735 CaptureExpr->getBeginLoc()); 3736 if (!WithInit) 3737 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3738 S.CurContext->addHiddenDecl(CED); 3739 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3740 return CED; 3741 } 3742 3743 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3744 bool WithInit) { 3745 OMPCapturedExprDecl *CD; 3746 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3747 CD = cast<OMPCapturedExprDecl>(VD); 3748 else 3749 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3750 /*AsExpression=*/false); 3751 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3752 CaptureExpr->getExprLoc()); 3753 } 3754 3755 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3756 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3757 if (!Ref) { 3758 OMPCapturedExprDecl *CD = buildCaptureDecl( 3759 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3760 /*WithInit=*/true, /*AsExpression=*/true); 3761 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3762 CaptureExpr->getExprLoc()); 3763 } 3764 ExprResult Res = Ref; 3765 if (!S.getLangOpts().CPlusPlus && 3766 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3767 Ref->getType()->isPointerType()) { 3768 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3769 if (!Res.isUsable()) 3770 return ExprError(); 3771 } 3772 return S.DefaultLvalueConversion(Res.get()); 3773 } 3774 3775 namespace { 3776 // OpenMP directives parsed in this section are represented as a 3777 // CapturedStatement with an associated statement. If a syntax error 3778 // is detected during the parsing of the associated statement, the 3779 // compiler must abort processing and close the CapturedStatement. 3780 // 3781 // Combined directives such as 'target parallel' have more than one 3782 // nested CapturedStatements. This RAII ensures that we unwind out 3783 // of all the nested CapturedStatements when an error is found. 3784 class CaptureRegionUnwinderRAII { 3785 private: 3786 Sema &S; 3787 bool &ErrorFound; 3788 OpenMPDirectiveKind DKind = OMPD_unknown; 3789 3790 public: 3791 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3792 OpenMPDirectiveKind DKind) 3793 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3794 ~CaptureRegionUnwinderRAII() { 3795 if (ErrorFound) { 3796 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3797 while (--ThisCaptureLevel >= 0) 3798 S.ActOnCapturedRegionError(); 3799 } 3800 } 3801 }; 3802 } // namespace 3803 3804 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3805 // Capture variables captured by reference in lambdas for target-based 3806 // directives. 3807 if (!CurContext->isDependentContext() && 3808 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3809 isOpenMPTargetDataManagementDirective( 3810 DSAStack->getCurrentDirective()))) { 3811 QualType Type = V->getType(); 3812 if (const auto *RD = Type.getCanonicalType() 3813 .getNonReferenceType() 3814 ->getAsCXXRecordDecl()) { 3815 bool SavedForceCaptureByReferenceInTargetExecutable = 3816 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3817 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3818 /*V=*/true); 3819 if (RD->isLambda()) { 3820 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3821 FieldDecl *ThisCapture; 3822 RD->getCaptureFields(Captures, ThisCapture); 3823 for (const LambdaCapture &LC : RD->captures()) { 3824 if (LC.getCaptureKind() == LCK_ByRef) { 3825 VarDecl *VD = LC.getCapturedVar(); 3826 DeclContext *VDC = VD->getDeclContext(); 3827 if (!VDC->Encloses(CurContext)) 3828 continue; 3829 MarkVariableReferenced(LC.getLocation(), VD); 3830 } else if (LC.getCaptureKind() == LCK_This) { 3831 QualType ThisTy = getCurrentThisType(); 3832 if (!ThisTy.isNull() && 3833 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3834 CheckCXXThisCapture(LC.getLocation()); 3835 } 3836 } 3837 } 3838 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3839 SavedForceCaptureByReferenceInTargetExecutable); 3840 } 3841 } 3842 } 3843 3844 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3845 ArrayRef<OMPClause *> Clauses) { 3846 bool ErrorFound = false; 3847 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3848 *this, ErrorFound, DSAStack->getCurrentDirective()); 3849 if (!S.isUsable()) { 3850 ErrorFound = true; 3851 return StmtError(); 3852 } 3853 3854 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3855 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3856 OMPOrderedClause *OC = nullptr; 3857 OMPScheduleClause *SC = nullptr; 3858 SmallVector<const OMPLinearClause *, 4> LCs; 3859 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3860 // This is required for proper codegen. 3861 for (OMPClause *Clause : Clauses) { 3862 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3863 Clause->getClauseKind() == OMPC_in_reduction) { 3864 // Capture taskgroup task_reduction descriptors inside the tasking regions 3865 // with the corresponding in_reduction items. 3866 auto *IRC = cast<OMPInReductionClause>(Clause); 3867 for (Expr *E : IRC->taskgroup_descriptors()) 3868 if (E) 3869 MarkDeclarationsReferencedInExpr(E); 3870 } 3871 if (isOpenMPPrivate(Clause->getClauseKind()) || 3872 Clause->getClauseKind() == OMPC_copyprivate || 3873 (getLangOpts().OpenMPUseTLS && 3874 getASTContext().getTargetInfo().isTLSSupported() && 3875 Clause->getClauseKind() == OMPC_copyin)) { 3876 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3877 // Mark all variables in private list clauses as used in inner region. 3878 for (Stmt *VarRef : Clause->children()) { 3879 if (auto *E = cast_or_null<Expr>(VarRef)) { 3880 MarkDeclarationsReferencedInExpr(E); 3881 } 3882 } 3883 DSAStack->setForceVarCapturing(/*V=*/false); 3884 } else if (CaptureRegions.size() > 1 || 3885 CaptureRegions.back() != OMPD_unknown) { 3886 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3887 PICs.push_back(C); 3888 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3889 if (Expr *E = C->getPostUpdateExpr()) 3890 MarkDeclarationsReferencedInExpr(E); 3891 } 3892 } 3893 if (Clause->getClauseKind() == OMPC_schedule) 3894 SC = cast<OMPScheduleClause>(Clause); 3895 else if (Clause->getClauseKind() == OMPC_ordered) 3896 OC = cast<OMPOrderedClause>(Clause); 3897 else if (Clause->getClauseKind() == OMPC_linear) 3898 LCs.push_back(cast<OMPLinearClause>(Clause)); 3899 } 3900 // OpenMP, 2.7.1 Loop Construct, Restrictions 3901 // The nonmonotonic modifier cannot be specified if an ordered clause is 3902 // specified. 3903 if (SC && 3904 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3905 SC->getSecondScheduleModifier() == 3906 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3907 OC) { 3908 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3909 ? SC->getFirstScheduleModifierLoc() 3910 : SC->getSecondScheduleModifierLoc(), 3911 diag::err_omp_schedule_nonmonotonic_ordered) 3912 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3913 ErrorFound = true; 3914 } 3915 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3916 for (const OMPLinearClause *C : LCs) { 3917 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3918 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3919 } 3920 ErrorFound = true; 3921 } 3922 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3923 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3924 OC->getNumForLoops()) { 3925 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3926 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3927 ErrorFound = true; 3928 } 3929 if (ErrorFound) { 3930 return StmtError(); 3931 } 3932 StmtResult SR = S; 3933 unsigned CompletedRegions = 0; 3934 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3935 // Mark all variables in private list clauses as used in inner region. 3936 // Required for proper codegen of combined directives. 3937 // TODO: add processing for other clauses. 3938 if (ThisCaptureRegion != OMPD_unknown) { 3939 for (const clang::OMPClauseWithPreInit *C : PICs) { 3940 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3941 // Find the particular capture region for the clause if the 3942 // directive is a combined one with multiple capture regions. 3943 // If the directive is not a combined one, the capture region 3944 // associated with the clause is OMPD_unknown and is generated 3945 // only once. 3946 if (CaptureRegion == ThisCaptureRegion || 3947 CaptureRegion == OMPD_unknown) { 3948 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3949 for (Decl *D : DS->decls()) 3950 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3951 } 3952 } 3953 } 3954 } 3955 if (++CompletedRegions == CaptureRegions.size()) 3956 DSAStack->setBodyComplete(); 3957 SR = ActOnCapturedRegionEnd(SR.get()); 3958 } 3959 return SR; 3960 } 3961 3962 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3963 OpenMPDirectiveKind CancelRegion, 3964 SourceLocation StartLoc) { 3965 // CancelRegion is only needed for cancel and cancellation_point. 3966 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3967 return false; 3968 3969 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3970 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3971 return false; 3972 3973 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3974 << getOpenMPDirectiveName(CancelRegion); 3975 return true; 3976 } 3977 3978 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3979 OpenMPDirectiveKind CurrentRegion, 3980 const DeclarationNameInfo &CurrentName, 3981 OpenMPDirectiveKind CancelRegion, 3982 SourceLocation StartLoc) { 3983 if (Stack->getCurScope()) { 3984 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3985 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3986 bool NestingProhibited = false; 3987 bool CloseNesting = true; 3988 bool OrphanSeen = false; 3989 enum { 3990 NoRecommend, 3991 ShouldBeInParallelRegion, 3992 ShouldBeInOrderedRegion, 3993 ShouldBeInTargetRegion, 3994 ShouldBeInTeamsRegion 3995 } Recommend = NoRecommend; 3996 if (isOpenMPSimdDirective(ParentRegion) && 3997 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 3998 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 3999 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 4000 // OpenMP [2.16, Nesting of Regions] 4001 // OpenMP constructs may not be nested inside a simd region. 4002 // OpenMP [2.8.1,simd Construct, Restrictions] 4003 // An ordered construct with the simd clause is the only OpenMP 4004 // construct that can appear in the simd region. 4005 // Allowing a SIMD construct nested in another SIMD construct is an 4006 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4007 // message. 4008 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4009 // The only OpenMP constructs that can be encountered during execution of 4010 // a simd region are the atomic construct, the loop construct, the simd 4011 // construct and the ordered construct with the simd clause. 4012 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4013 ? diag::err_omp_prohibited_region_simd 4014 : diag::warn_omp_nesting_simd) 4015 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4016 return CurrentRegion != OMPD_simd; 4017 } 4018 if (ParentRegion == OMPD_atomic) { 4019 // OpenMP [2.16, Nesting of Regions] 4020 // OpenMP constructs may not be nested inside an atomic region. 4021 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4022 return true; 4023 } 4024 if (CurrentRegion == OMPD_section) { 4025 // OpenMP [2.7.2, sections Construct, Restrictions] 4026 // Orphaned section directives are prohibited. That is, the section 4027 // directives must appear within the sections construct and must not be 4028 // encountered elsewhere in the sections region. 4029 if (ParentRegion != OMPD_sections && 4030 ParentRegion != OMPD_parallel_sections) { 4031 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4032 << (ParentRegion != OMPD_unknown) 4033 << getOpenMPDirectiveName(ParentRegion); 4034 return true; 4035 } 4036 return false; 4037 } 4038 // Allow some constructs (except teams and cancellation constructs) to be 4039 // orphaned (they could be used in functions, called from OpenMP regions 4040 // with the required preconditions). 4041 if (ParentRegion == OMPD_unknown && 4042 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4043 CurrentRegion != OMPD_cancellation_point && 4044 CurrentRegion != OMPD_cancel) 4045 return false; 4046 if (CurrentRegion == OMPD_cancellation_point || 4047 CurrentRegion == OMPD_cancel) { 4048 // OpenMP [2.16, Nesting of Regions] 4049 // A cancellation point construct for which construct-type-clause is 4050 // taskgroup must be nested inside a task construct. A cancellation 4051 // point construct for which construct-type-clause is not taskgroup must 4052 // be closely nested inside an OpenMP construct that matches the type 4053 // specified in construct-type-clause. 4054 // A cancel construct for which construct-type-clause is taskgroup must be 4055 // nested inside a task construct. A cancel construct for which 4056 // construct-type-clause is not taskgroup must be closely nested inside an 4057 // OpenMP construct that matches the type specified in 4058 // construct-type-clause. 4059 NestingProhibited = 4060 !((CancelRegion == OMPD_parallel && 4061 (ParentRegion == OMPD_parallel || 4062 ParentRegion == OMPD_target_parallel)) || 4063 (CancelRegion == OMPD_for && 4064 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4065 ParentRegion == OMPD_target_parallel_for || 4066 ParentRegion == OMPD_distribute_parallel_for || 4067 ParentRegion == OMPD_teams_distribute_parallel_for || 4068 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4069 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 4070 (CancelRegion == OMPD_sections && 4071 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4072 ParentRegion == OMPD_parallel_sections))); 4073 OrphanSeen = ParentRegion == OMPD_unknown; 4074 } else if (CurrentRegion == OMPD_master) { 4075 // OpenMP [2.16, Nesting of Regions] 4076 // A master region may not be closely nested inside a worksharing, 4077 // atomic, or explicit task region. 4078 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4079 isOpenMPTaskingDirective(ParentRegion); 4080 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4081 // OpenMP [2.16, Nesting of Regions] 4082 // A critical region may not be nested (closely or otherwise) inside a 4083 // critical region with the same name. Note that this restriction is not 4084 // sufficient to prevent deadlock. 4085 SourceLocation PreviousCriticalLoc; 4086 bool DeadLock = Stack->hasDirective( 4087 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4088 const DeclarationNameInfo &DNI, 4089 SourceLocation Loc) { 4090 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4091 PreviousCriticalLoc = Loc; 4092 return true; 4093 } 4094 return false; 4095 }, 4096 false /* skip top directive */); 4097 if (DeadLock) { 4098 SemaRef.Diag(StartLoc, 4099 diag::err_omp_prohibited_region_critical_same_name) 4100 << CurrentName.getName(); 4101 if (PreviousCriticalLoc.isValid()) 4102 SemaRef.Diag(PreviousCriticalLoc, 4103 diag::note_omp_previous_critical_region); 4104 return true; 4105 } 4106 } else if (CurrentRegion == OMPD_barrier) { 4107 // OpenMP [2.16, Nesting of Regions] 4108 // A barrier region may not be closely nested inside a worksharing, 4109 // explicit task, critical, ordered, atomic, or master region. 4110 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4111 isOpenMPTaskingDirective(ParentRegion) || 4112 ParentRegion == OMPD_master || 4113 ParentRegion == OMPD_parallel_master || 4114 ParentRegion == OMPD_critical || 4115 ParentRegion == OMPD_ordered; 4116 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4117 !isOpenMPParallelDirective(CurrentRegion) && 4118 !isOpenMPTeamsDirective(CurrentRegion)) { 4119 // OpenMP [2.16, Nesting of Regions] 4120 // A worksharing region may not be closely nested inside a worksharing, 4121 // explicit task, critical, ordered, atomic, or master region. 4122 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4123 isOpenMPTaskingDirective(ParentRegion) || 4124 ParentRegion == OMPD_master || 4125 ParentRegion == OMPD_parallel_master || 4126 ParentRegion == OMPD_critical || 4127 ParentRegion == OMPD_ordered; 4128 Recommend = ShouldBeInParallelRegion; 4129 } else if (CurrentRegion == OMPD_ordered) { 4130 // OpenMP [2.16, Nesting of Regions] 4131 // An ordered region may not be closely nested inside a critical, 4132 // atomic, or explicit task region. 4133 // An ordered region must be closely nested inside a loop region (or 4134 // parallel loop region) with an ordered clause. 4135 // OpenMP [2.8.1,simd Construct, Restrictions] 4136 // An ordered construct with the simd clause is the only OpenMP construct 4137 // that can appear in the simd region. 4138 NestingProhibited = ParentRegion == OMPD_critical || 4139 isOpenMPTaskingDirective(ParentRegion) || 4140 !(isOpenMPSimdDirective(ParentRegion) || 4141 Stack->isParentOrderedRegion()); 4142 Recommend = ShouldBeInOrderedRegion; 4143 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4144 // OpenMP [2.16, Nesting of Regions] 4145 // If specified, a teams construct must be contained within a target 4146 // construct. 4147 NestingProhibited = 4148 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4149 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4150 ParentRegion != OMPD_target); 4151 OrphanSeen = ParentRegion == OMPD_unknown; 4152 Recommend = ShouldBeInTargetRegion; 4153 } 4154 if (!NestingProhibited && 4155 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4156 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4157 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4158 // OpenMP [2.16, Nesting of Regions] 4159 // distribute, parallel, parallel sections, parallel workshare, and the 4160 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4161 // constructs that can be closely nested in the teams region. 4162 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4163 !isOpenMPDistributeDirective(CurrentRegion); 4164 Recommend = ShouldBeInParallelRegion; 4165 } 4166 if (!NestingProhibited && 4167 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4168 // OpenMP 4.5 [2.17 Nesting of Regions] 4169 // The region associated with the distribute construct must be strictly 4170 // nested inside a teams region 4171 NestingProhibited = 4172 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4173 Recommend = ShouldBeInTeamsRegion; 4174 } 4175 if (!NestingProhibited && 4176 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4177 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4178 // OpenMP 4.5 [2.17 Nesting of Regions] 4179 // If a target, target update, target data, target enter data, or 4180 // target exit data construct is encountered during execution of a 4181 // target region, the behavior is unspecified. 4182 NestingProhibited = Stack->hasDirective( 4183 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4184 SourceLocation) { 4185 if (isOpenMPTargetExecutionDirective(K)) { 4186 OffendingRegion = K; 4187 return true; 4188 } 4189 return false; 4190 }, 4191 false /* don't skip top directive */); 4192 CloseNesting = false; 4193 } 4194 if (NestingProhibited) { 4195 if (OrphanSeen) { 4196 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4197 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4198 } else { 4199 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4200 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4201 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4202 } 4203 return true; 4204 } 4205 } 4206 return false; 4207 } 4208 4209 struct Kind2Unsigned { 4210 using argument_type = OpenMPDirectiveKind; 4211 unsigned operator()(argument_type DK) { return unsigned(DK); } 4212 }; 4213 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4214 ArrayRef<OMPClause *> Clauses, 4215 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4216 bool ErrorFound = false; 4217 unsigned NamedModifiersNumber = 0; 4218 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4219 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4220 SmallVector<SourceLocation, 4> NameModifierLoc; 4221 for (const OMPClause *C : Clauses) { 4222 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4223 // At most one if clause without a directive-name-modifier can appear on 4224 // the directive. 4225 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4226 if (FoundNameModifiers[CurNM]) { 4227 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4228 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4229 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4230 ErrorFound = true; 4231 } else if (CurNM != OMPD_unknown) { 4232 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4233 ++NamedModifiersNumber; 4234 } 4235 FoundNameModifiers[CurNM] = IC; 4236 if (CurNM == OMPD_unknown) 4237 continue; 4238 // Check if the specified name modifier is allowed for the current 4239 // directive. 4240 // At most one if clause with the particular directive-name-modifier can 4241 // appear on the directive. 4242 bool MatchFound = false; 4243 for (auto NM : AllowedNameModifiers) { 4244 if (CurNM == NM) { 4245 MatchFound = true; 4246 break; 4247 } 4248 } 4249 if (!MatchFound) { 4250 S.Diag(IC->getNameModifierLoc(), 4251 diag::err_omp_wrong_if_directive_name_modifier) 4252 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4253 ErrorFound = true; 4254 } 4255 } 4256 } 4257 // If any if clause on the directive includes a directive-name-modifier then 4258 // all if clauses on the directive must include a directive-name-modifier. 4259 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4260 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4261 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4262 diag::err_omp_no_more_if_clause); 4263 } else { 4264 std::string Values; 4265 std::string Sep(", "); 4266 unsigned AllowedCnt = 0; 4267 unsigned TotalAllowedNum = 4268 AllowedNameModifiers.size() - NamedModifiersNumber; 4269 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4270 ++Cnt) { 4271 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4272 if (!FoundNameModifiers[NM]) { 4273 Values += "'"; 4274 Values += getOpenMPDirectiveName(NM); 4275 Values += "'"; 4276 if (AllowedCnt + 2 == TotalAllowedNum) 4277 Values += " or "; 4278 else if (AllowedCnt + 1 != TotalAllowedNum) 4279 Values += Sep; 4280 ++AllowedCnt; 4281 } 4282 } 4283 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4284 diag::err_omp_unnamed_if_clause) 4285 << (TotalAllowedNum > 1) << Values; 4286 } 4287 for (SourceLocation Loc : NameModifierLoc) { 4288 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4289 } 4290 ErrorFound = true; 4291 } 4292 return ErrorFound; 4293 } 4294 4295 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4296 SourceLocation &ELoc, 4297 SourceRange &ERange, 4298 bool AllowArraySection) { 4299 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4300 RefExpr->containsUnexpandedParameterPack()) 4301 return std::make_pair(nullptr, true); 4302 4303 // OpenMP [3.1, C/C++] 4304 // A list item is a variable name. 4305 // OpenMP [2.9.3.3, Restrictions, p.1] 4306 // A variable that is part of another variable (as an array or 4307 // structure element) cannot appear in a private clause. 4308 RefExpr = RefExpr->IgnoreParens(); 4309 enum { 4310 NoArrayExpr = -1, 4311 ArraySubscript = 0, 4312 OMPArraySection = 1 4313 } IsArrayExpr = NoArrayExpr; 4314 if (AllowArraySection) { 4315 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4316 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4317 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4318 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4319 RefExpr = Base; 4320 IsArrayExpr = ArraySubscript; 4321 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4322 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4323 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4324 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4325 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4326 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4327 RefExpr = Base; 4328 IsArrayExpr = OMPArraySection; 4329 } 4330 } 4331 ELoc = RefExpr->getExprLoc(); 4332 ERange = RefExpr->getSourceRange(); 4333 RefExpr = RefExpr->IgnoreParenImpCasts(); 4334 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4335 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4336 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4337 (S.getCurrentThisType().isNull() || !ME || 4338 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4339 !isa<FieldDecl>(ME->getMemberDecl()))) { 4340 if (IsArrayExpr != NoArrayExpr) { 4341 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4342 << ERange; 4343 } else { 4344 S.Diag(ELoc, 4345 AllowArraySection 4346 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4347 : diag::err_omp_expected_var_name_member_expr) 4348 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4349 } 4350 return std::make_pair(nullptr, false); 4351 } 4352 return std::make_pair( 4353 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4354 } 4355 4356 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4357 ArrayRef<OMPClause *> Clauses) { 4358 assert(!S.CurContext->isDependentContext() && 4359 "Expected non-dependent context."); 4360 auto AllocateRange = 4361 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4362 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4363 DeclToCopy; 4364 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4365 return isOpenMPPrivate(C->getClauseKind()); 4366 }); 4367 for (OMPClause *Cl : PrivateRange) { 4368 MutableArrayRef<Expr *>::iterator I, It, Et; 4369 if (Cl->getClauseKind() == OMPC_private) { 4370 auto *PC = cast<OMPPrivateClause>(Cl); 4371 I = PC->private_copies().begin(); 4372 It = PC->varlist_begin(); 4373 Et = PC->varlist_end(); 4374 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4375 auto *PC = cast<OMPFirstprivateClause>(Cl); 4376 I = PC->private_copies().begin(); 4377 It = PC->varlist_begin(); 4378 Et = PC->varlist_end(); 4379 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4380 auto *PC = cast<OMPLastprivateClause>(Cl); 4381 I = PC->private_copies().begin(); 4382 It = PC->varlist_begin(); 4383 Et = PC->varlist_end(); 4384 } else if (Cl->getClauseKind() == OMPC_linear) { 4385 auto *PC = cast<OMPLinearClause>(Cl); 4386 I = PC->privates().begin(); 4387 It = PC->varlist_begin(); 4388 Et = PC->varlist_end(); 4389 } else if (Cl->getClauseKind() == OMPC_reduction) { 4390 auto *PC = cast<OMPReductionClause>(Cl); 4391 I = PC->privates().begin(); 4392 It = PC->varlist_begin(); 4393 Et = PC->varlist_end(); 4394 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4395 auto *PC = cast<OMPTaskReductionClause>(Cl); 4396 I = PC->privates().begin(); 4397 It = PC->varlist_begin(); 4398 Et = PC->varlist_end(); 4399 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4400 auto *PC = cast<OMPInReductionClause>(Cl); 4401 I = PC->privates().begin(); 4402 It = PC->varlist_begin(); 4403 Et = PC->varlist_end(); 4404 } else { 4405 llvm_unreachable("Expected private clause."); 4406 } 4407 for (Expr *E : llvm::make_range(It, Et)) { 4408 if (!*I) { 4409 ++I; 4410 continue; 4411 } 4412 SourceLocation ELoc; 4413 SourceRange ERange; 4414 Expr *SimpleRefExpr = E; 4415 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4416 /*AllowArraySection=*/true); 4417 DeclToCopy.try_emplace(Res.first, 4418 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4419 ++I; 4420 } 4421 } 4422 for (OMPClause *C : AllocateRange) { 4423 auto *AC = cast<OMPAllocateClause>(C); 4424 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4425 getAllocatorKind(S, Stack, AC->getAllocator()); 4426 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4427 // For task, taskloop or target directives, allocation requests to memory 4428 // allocators with the trait access set to thread result in unspecified 4429 // behavior. 4430 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4431 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4432 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4433 S.Diag(AC->getAllocator()->getExprLoc(), 4434 diag::warn_omp_allocate_thread_on_task_target_directive) 4435 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4436 } 4437 for (Expr *E : AC->varlists()) { 4438 SourceLocation ELoc; 4439 SourceRange ERange; 4440 Expr *SimpleRefExpr = E; 4441 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4442 ValueDecl *VD = Res.first; 4443 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4444 if (!isOpenMPPrivate(Data.CKind)) { 4445 S.Diag(E->getExprLoc(), 4446 diag::err_omp_expected_private_copy_for_allocate); 4447 continue; 4448 } 4449 VarDecl *PrivateVD = DeclToCopy[VD]; 4450 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4451 AllocatorKind, AC->getAllocator())) 4452 continue; 4453 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4454 E->getSourceRange()); 4455 } 4456 } 4457 } 4458 4459 StmtResult Sema::ActOnOpenMPExecutableDirective( 4460 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4461 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4462 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4463 StmtResult Res = StmtError(); 4464 // First check CancelRegion which is then used in checkNestingOfRegions. 4465 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4466 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4467 StartLoc)) 4468 return StmtError(); 4469 4470 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4471 VarsWithInheritedDSAType VarsWithInheritedDSA; 4472 bool ErrorFound = false; 4473 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4474 if (AStmt && !CurContext->isDependentContext()) { 4475 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4476 4477 // Check default data sharing attributes for referenced variables. 4478 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4479 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4480 Stmt *S = AStmt; 4481 while (--ThisCaptureLevel >= 0) 4482 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4483 DSAChecker.Visit(S); 4484 if (!isOpenMPTargetDataManagementDirective(Kind) && 4485 !isOpenMPTaskingDirective(Kind)) { 4486 // Visit subcaptures to generate implicit clauses for captured vars. 4487 auto *CS = cast<CapturedStmt>(AStmt); 4488 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4489 getOpenMPCaptureRegions(CaptureRegions, Kind); 4490 // Ignore outer tasking regions for target directives. 4491 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4492 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4493 DSAChecker.visitSubCaptures(CS); 4494 } 4495 if (DSAChecker.isErrorFound()) 4496 return StmtError(); 4497 // Generate list of implicitly defined firstprivate variables. 4498 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4499 4500 SmallVector<Expr *, 4> ImplicitFirstprivates( 4501 DSAChecker.getImplicitFirstprivate().begin(), 4502 DSAChecker.getImplicitFirstprivate().end()); 4503 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4504 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4505 ArrayRef<Expr *> ImplicitMap = 4506 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4507 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4508 } 4509 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4510 for (OMPClause *C : Clauses) { 4511 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4512 for (Expr *E : IRC->taskgroup_descriptors()) 4513 if (E) 4514 ImplicitFirstprivates.emplace_back(E); 4515 } 4516 } 4517 if (!ImplicitFirstprivates.empty()) { 4518 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4519 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4520 SourceLocation())) { 4521 ClausesWithImplicit.push_back(Implicit); 4522 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4523 ImplicitFirstprivates.size(); 4524 } else { 4525 ErrorFound = true; 4526 } 4527 } 4528 int ClauseKindCnt = -1; 4529 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4530 ++ClauseKindCnt; 4531 if (ImplicitMap.empty()) 4532 continue; 4533 CXXScopeSpec MapperIdScopeSpec; 4534 DeclarationNameInfo MapperId; 4535 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4536 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4537 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4538 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4539 ImplicitMap, OMPVarListLocTy())) { 4540 ClausesWithImplicit.emplace_back(Implicit); 4541 ErrorFound |= 4542 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4543 } else { 4544 ErrorFound = true; 4545 } 4546 } 4547 } 4548 4549 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4550 switch (Kind) { 4551 case OMPD_parallel: 4552 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4553 EndLoc); 4554 AllowedNameModifiers.push_back(OMPD_parallel); 4555 break; 4556 case OMPD_simd: 4557 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4558 VarsWithInheritedDSA); 4559 if (LangOpts.OpenMP >= 50) 4560 AllowedNameModifiers.push_back(OMPD_simd); 4561 break; 4562 case OMPD_for: 4563 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4564 VarsWithInheritedDSA); 4565 break; 4566 case OMPD_for_simd: 4567 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4568 EndLoc, VarsWithInheritedDSA); 4569 if (LangOpts.OpenMP >= 50) 4570 AllowedNameModifiers.push_back(OMPD_simd); 4571 break; 4572 case OMPD_sections: 4573 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4574 EndLoc); 4575 break; 4576 case OMPD_section: 4577 assert(ClausesWithImplicit.empty() && 4578 "No clauses are allowed for 'omp section' directive"); 4579 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4580 break; 4581 case OMPD_single: 4582 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4583 EndLoc); 4584 break; 4585 case OMPD_master: 4586 assert(ClausesWithImplicit.empty() && 4587 "No clauses are allowed for 'omp master' directive"); 4588 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4589 break; 4590 case OMPD_critical: 4591 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4592 StartLoc, EndLoc); 4593 break; 4594 case OMPD_parallel_for: 4595 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4596 EndLoc, VarsWithInheritedDSA); 4597 AllowedNameModifiers.push_back(OMPD_parallel); 4598 break; 4599 case OMPD_parallel_for_simd: 4600 Res = ActOnOpenMPParallelForSimdDirective( 4601 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4602 AllowedNameModifiers.push_back(OMPD_parallel); 4603 if (LangOpts.OpenMP >= 50) 4604 AllowedNameModifiers.push_back(OMPD_simd); 4605 break; 4606 case OMPD_parallel_master: 4607 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4608 StartLoc, EndLoc); 4609 AllowedNameModifiers.push_back(OMPD_parallel); 4610 break; 4611 case OMPD_parallel_sections: 4612 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4613 StartLoc, EndLoc); 4614 AllowedNameModifiers.push_back(OMPD_parallel); 4615 break; 4616 case OMPD_task: 4617 Res = 4618 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4619 AllowedNameModifiers.push_back(OMPD_task); 4620 break; 4621 case OMPD_taskyield: 4622 assert(ClausesWithImplicit.empty() && 4623 "No clauses are allowed for 'omp taskyield' directive"); 4624 assert(AStmt == nullptr && 4625 "No associated statement allowed for 'omp taskyield' directive"); 4626 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4627 break; 4628 case OMPD_barrier: 4629 assert(ClausesWithImplicit.empty() && 4630 "No clauses are allowed for 'omp barrier' directive"); 4631 assert(AStmt == nullptr && 4632 "No associated statement allowed for 'omp barrier' directive"); 4633 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4634 break; 4635 case OMPD_taskwait: 4636 assert(ClausesWithImplicit.empty() && 4637 "No clauses are allowed for 'omp taskwait' directive"); 4638 assert(AStmt == nullptr && 4639 "No associated statement allowed for 'omp taskwait' directive"); 4640 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4641 break; 4642 case OMPD_taskgroup: 4643 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4644 EndLoc); 4645 break; 4646 case OMPD_flush: 4647 assert(AStmt == nullptr && 4648 "No associated statement allowed for 'omp flush' directive"); 4649 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4650 break; 4651 case OMPD_ordered: 4652 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4653 EndLoc); 4654 break; 4655 case OMPD_atomic: 4656 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4657 EndLoc); 4658 break; 4659 case OMPD_teams: 4660 Res = 4661 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4662 break; 4663 case OMPD_target: 4664 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4665 EndLoc); 4666 AllowedNameModifiers.push_back(OMPD_target); 4667 break; 4668 case OMPD_target_parallel: 4669 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4670 StartLoc, EndLoc); 4671 AllowedNameModifiers.push_back(OMPD_target); 4672 AllowedNameModifiers.push_back(OMPD_parallel); 4673 break; 4674 case OMPD_target_parallel_for: 4675 Res = ActOnOpenMPTargetParallelForDirective( 4676 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4677 AllowedNameModifiers.push_back(OMPD_target); 4678 AllowedNameModifiers.push_back(OMPD_parallel); 4679 break; 4680 case OMPD_cancellation_point: 4681 assert(ClausesWithImplicit.empty() && 4682 "No clauses are allowed for 'omp cancellation point' directive"); 4683 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4684 "cancellation point' directive"); 4685 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4686 break; 4687 case OMPD_cancel: 4688 assert(AStmt == nullptr && 4689 "No associated statement allowed for 'omp cancel' directive"); 4690 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4691 CancelRegion); 4692 AllowedNameModifiers.push_back(OMPD_cancel); 4693 break; 4694 case OMPD_target_data: 4695 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4696 EndLoc); 4697 AllowedNameModifiers.push_back(OMPD_target_data); 4698 break; 4699 case OMPD_target_enter_data: 4700 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4701 EndLoc, AStmt); 4702 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4703 break; 4704 case OMPD_target_exit_data: 4705 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4706 EndLoc, AStmt); 4707 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4708 break; 4709 case OMPD_taskloop: 4710 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4711 EndLoc, VarsWithInheritedDSA); 4712 AllowedNameModifiers.push_back(OMPD_taskloop); 4713 break; 4714 case OMPD_taskloop_simd: 4715 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4716 EndLoc, VarsWithInheritedDSA); 4717 AllowedNameModifiers.push_back(OMPD_taskloop); 4718 if (LangOpts.OpenMP >= 50) 4719 AllowedNameModifiers.push_back(OMPD_simd); 4720 break; 4721 case OMPD_master_taskloop: 4722 Res = ActOnOpenMPMasterTaskLoopDirective( 4723 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4724 AllowedNameModifiers.push_back(OMPD_taskloop); 4725 break; 4726 case OMPD_master_taskloop_simd: 4727 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4728 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4729 AllowedNameModifiers.push_back(OMPD_taskloop); 4730 if (LangOpts.OpenMP >= 50) 4731 AllowedNameModifiers.push_back(OMPD_simd); 4732 break; 4733 case OMPD_parallel_master_taskloop: 4734 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4735 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4736 AllowedNameModifiers.push_back(OMPD_taskloop); 4737 AllowedNameModifiers.push_back(OMPD_parallel); 4738 break; 4739 case OMPD_parallel_master_taskloop_simd: 4740 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4741 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4742 AllowedNameModifiers.push_back(OMPD_taskloop); 4743 AllowedNameModifiers.push_back(OMPD_parallel); 4744 if (LangOpts.OpenMP >= 50) 4745 AllowedNameModifiers.push_back(OMPD_simd); 4746 break; 4747 case OMPD_distribute: 4748 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4749 EndLoc, VarsWithInheritedDSA); 4750 break; 4751 case OMPD_target_update: 4752 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4753 EndLoc, AStmt); 4754 AllowedNameModifiers.push_back(OMPD_target_update); 4755 break; 4756 case OMPD_distribute_parallel_for: 4757 Res = ActOnOpenMPDistributeParallelForDirective( 4758 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4759 AllowedNameModifiers.push_back(OMPD_parallel); 4760 break; 4761 case OMPD_distribute_parallel_for_simd: 4762 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4763 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4764 AllowedNameModifiers.push_back(OMPD_parallel); 4765 if (LangOpts.OpenMP >= 50) 4766 AllowedNameModifiers.push_back(OMPD_simd); 4767 break; 4768 case OMPD_distribute_simd: 4769 Res = ActOnOpenMPDistributeSimdDirective( 4770 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4771 if (LangOpts.OpenMP >= 50) 4772 AllowedNameModifiers.push_back(OMPD_simd); 4773 break; 4774 case OMPD_target_parallel_for_simd: 4775 Res = ActOnOpenMPTargetParallelForSimdDirective( 4776 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4777 AllowedNameModifiers.push_back(OMPD_target); 4778 AllowedNameModifiers.push_back(OMPD_parallel); 4779 if (LangOpts.OpenMP >= 50) 4780 AllowedNameModifiers.push_back(OMPD_simd); 4781 break; 4782 case OMPD_target_simd: 4783 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4784 EndLoc, VarsWithInheritedDSA); 4785 AllowedNameModifiers.push_back(OMPD_target); 4786 if (LangOpts.OpenMP >= 50) 4787 AllowedNameModifiers.push_back(OMPD_simd); 4788 break; 4789 case OMPD_teams_distribute: 4790 Res = ActOnOpenMPTeamsDistributeDirective( 4791 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4792 break; 4793 case OMPD_teams_distribute_simd: 4794 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4795 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4796 if (LangOpts.OpenMP >= 50) 4797 AllowedNameModifiers.push_back(OMPD_simd); 4798 break; 4799 case OMPD_teams_distribute_parallel_for_simd: 4800 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4801 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4802 AllowedNameModifiers.push_back(OMPD_parallel); 4803 if (LangOpts.OpenMP >= 50) 4804 AllowedNameModifiers.push_back(OMPD_simd); 4805 break; 4806 case OMPD_teams_distribute_parallel_for: 4807 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4808 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4809 AllowedNameModifiers.push_back(OMPD_parallel); 4810 break; 4811 case OMPD_target_teams: 4812 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4813 EndLoc); 4814 AllowedNameModifiers.push_back(OMPD_target); 4815 break; 4816 case OMPD_target_teams_distribute: 4817 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4818 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4819 AllowedNameModifiers.push_back(OMPD_target); 4820 break; 4821 case OMPD_target_teams_distribute_parallel_for: 4822 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4823 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4824 AllowedNameModifiers.push_back(OMPD_target); 4825 AllowedNameModifiers.push_back(OMPD_parallel); 4826 break; 4827 case OMPD_target_teams_distribute_parallel_for_simd: 4828 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4829 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4830 AllowedNameModifiers.push_back(OMPD_target); 4831 AllowedNameModifiers.push_back(OMPD_parallel); 4832 if (LangOpts.OpenMP >= 50) 4833 AllowedNameModifiers.push_back(OMPD_simd); 4834 break; 4835 case OMPD_target_teams_distribute_simd: 4836 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4837 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4838 AllowedNameModifiers.push_back(OMPD_target); 4839 if (LangOpts.OpenMP >= 50) 4840 AllowedNameModifiers.push_back(OMPD_simd); 4841 break; 4842 case OMPD_declare_target: 4843 case OMPD_end_declare_target: 4844 case OMPD_threadprivate: 4845 case OMPD_allocate: 4846 case OMPD_declare_reduction: 4847 case OMPD_declare_mapper: 4848 case OMPD_declare_simd: 4849 case OMPD_requires: 4850 case OMPD_declare_variant: 4851 llvm_unreachable("OpenMP Directive is not allowed"); 4852 case OMPD_unknown: 4853 llvm_unreachable("Unknown OpenMP directive"); 4854 } 4855 4856 ErrorFound = Res.isInvalid() || ErrorFound; 4857 4858 // Check variables in the clauses if default(none) was specified. 4859 if (DSAStack->getDefaultDSA() == DSA_none) { 4860 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4861 for (OMPClause *C : Clauses) { 4862 switch (C->getClauseKind()) { 4863 case OMPC_num_threads: 4864 case OMPC_dist_schedule: 4865 // Do not analyse if no parent teams directive. 4866 if (isOpenMPTeamsDirective(Kind)) 4867 break; 4868 continue; 4869 case OMPC_if: 4870 if (isOpenMPTeamsDirective(Kind) && 4871 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4872 break; 4873 if (isOpenMPParallelDirective(Kind) && 4874 isOpenMPTaskLoopDirective(Kind) && 4875 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4876 break; 4877 continue; 4878 case OMPC_schedule: 4879 break; 4880 case OMPC_grainsize: 4881 case OMPC_num_tasks: 4882 case OMPC_final: 4883 case OMPC_priority: 4884 // Do not analyze if no parent parallel directive. 4885 if (isOpenMPParallelDirective(Kind)) 4886 break; 4887 continue; 4888 case OMPC_ordered: 4889 case OMPC_device: 4890 case OMPC_num_teams: 4891 case OMPC_thread_limit: 4892 case OMPC_hint: 4893 case OMPC_collapse: 4894 case OMPC_safelen: 4895 case OMPC_simdlen: 4896 case OMPC_default: 4897 case OMPC_proc_bind: 4898 case OMPC_private: 4899 case OMPC_firstprivate: 4900 case OMPC_lastprivate: 4901 case OMPC_shared: 4902 case OMPC_reduction: 4903 case OMPC_task_reduction: 4904 case OMPC_in_reduction: 4905 case OMPC_linear: 4906 case OMPC_aligned: 4907 case OMPC_copyin: 4908 case OMPC_copyprivate: 4909 case OMPC_nowait: 4910 case OMPC_untied: 4911 case OMPC_mergeable: 4912 case OMPC_allocate: 4913 case OMPC_read: 4914 case OMPC_write: 4915 case OMPC_update: 4916 case OMPC_capture: 4917 case OMPC_seq_cst: 4918 case OMPC_depend: 4919 case OMPC_threads: 4920 case OMPC_simd: 4921 case OMPC_map: 4922 case OMPC_nogroup: 4923 case OMPC_defaultmap: 4924 case OMPC_to: 4925 case OMPC_from: 4926 case OMPC_use_device_ptr: 4927 case OMPC_is_device_ptr: 4928 case OMPC_nontemporal: 4929 continue; 4930 case OMPC_allocator: 4931 case OMPC_flush: 4932 case OMPC_threadprivate: 4933 case OMPC_uniform: 4934 case OMPC_unknown: 4935 case OMPC_unified_address: 4936 case OMPC_unified_shared_memory: 4937 case OMPC_reverse_offload: 4938 case OMPC_dynamic_allocators: 4939 case OMPC_atomic_default_mem_order: 4940 case OMPC_device_type: 4941 case OMPC_match: 4942 llvm_unreachable("Unexpected clause"); 4943 } 4944 for (Stmt *CC : C->children()) { 4945 if (CC) 4946 DSAChecker.Visit(CC); 4947 } 4948 } 4949 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4950 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4951 } 4952 for (const auto &P : VarsWithInheritedDSA) { 4953 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4954 continue; 4955 ErrorFound = true; 4956 if (DSAStack->getDefaultDSA() == DSA_none) { 4957 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4958 << P.first << P.second->getSourceRange(); 4959 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4960 } else if (getLangOpts().OpenMP >= 50) { 4961 Diag(P.second->getExprLoc(), 4962 diag::err_omp_defaultmap_no_attr_for_variable) 4963 << P.first << P.second->getSourceRange(); 4964 Diag(DSAStack->getDefaultDSALocation(), 4965 diag::note_omp_defaultmap_attr_none); 4966 } 4967 } 4968 4969 if (!AllowedNameModifiers.empty()) 4970 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4971 ErrorFound; 4972 4973 if (ErrorFound) 4974 return StmtError(); 4975 4976 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4977 Res.getAs<OMPExecutableDirective>() 4978 ->getStructuredBlock() 4979 ->setIsOMPStructuredBlock(true); 4980 } 4981 4982 if (!CurContext->isDependentContext() && 4983 isOpenMPTargetExecutionDirective(Kind) && 4984 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4985 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4986 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4987 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4988 // Register target to DSA Stack. 4989 DSAStack->addTargetDirLocation(StartLoc); 4990 } 4991 4992 return Res; 4993 } 4994 4995 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4996 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4997 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4998 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4999 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5000 assert(Aligneds.size() == Alignments.size()); 5001 assert(Linears.size() == LinModifiers.size()); 5002 assert(Linears.size() == Steps.size()); 5003 if (!DG || DG.get().isNull()) 5004 return DeclGroupPtrTy(); 5005 5006 const int SimdId = 0; 5007 if (!DG.get().isSingleDecl()) { 5008 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5009 << SimdId; 5010 return DG; 5011 } 5012 Decl *ADecl = DG.get().getSingleDecl(); 5013 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5014 ADecl = FTD->getTemplatedDecl(); 5015 5016 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5017 if (!FD) { 5018 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5019 return DeclGroupPtrTy(); 5020 } 5021 5022 // OpenMP [2.8.2, declare simd construct, Description] 5023 // The parameter of the simdlen clause must be a constant positive integer 5024 // expression. 5025 ExprResult SL; 5026 if (Simdlen) 5027 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5028 // OpenMP [2.8.2, declare simd construct, Description] 5029 // The special this pointer can be used as if was one of the arguments to the 5030 // function in any of the linear, aligned, or uniform clauses. 5031 // The uniform clause declares one or more arguments to have an invariant 5032 // value for all concurrent invocations of the function in the execution of a 5033 // single SIMD loop. 5034 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5035 const Expr *UniformedLinearThis = nullptr; 5036 for (const Expr *E : Uniforms) { 5037 E = E->IgnoreParenImpCasts(); 5038 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5039 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5040 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5041 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5042 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5043 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5044 continue; 5045 } 5046 if (isa<CXXThisExpr>(E)) { 5047 UniformedLinearThis = E; 5048 continue; 5049 } 5050 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5051 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5052 } 5053 // OpenMP [2.8.2, declare simd construct, Description] 5054 // The aligned clause declares that the object to which each list item points 5055 // is aligned to the number of bytes expressed in the optional parameter of 5056 // the aligned clause. 5057 // The special this pointer can be used as if was one of the arguments to the 5058 // function in any of the linear, aligned, or uniform clauses. 5059 // The type of list items appearing in the aligned clause must be array, 5060 // pointer, reference to array, or reference to pointer. 5061 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5062 const Expr *AlignedThis = nullptr; 5063 for (const Expr *E : Aligneds) { 5064 E = E->IgnoreParenImpCasts(); 5065 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5066 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5067 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5068 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5069 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5070 ->getCanonicalDecl() == CanonPVD) { 5071 // OpenMP [2.8.1, simd construct, Restrictions] 5072 // A list-item cannot appear in more than one aligned clause. 5073 if (AlignedArgs.count(CanonPVD) > 0) { 5074 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5075 << 1 << getOpenMPClauseName(OMPC_aligned) 5076 << E->getSourceRange(); 5077 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5078 diag::note_omp_explicit_dsa) 5079 << getOpenMPClauseName(OMPC_aligned); 5080 continue; 5081 } 5082 AlignedArgs[CanonPVD] = E; 5083 QualType QTy = PVD->getType() 5084 .getNonReferenceType() 5085 .getUnqualifiedType() 5086 .getCanonicalType(); 5087 const Type *Ty = QTy.getTypePtrOrNull(); 5088 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5089 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5090 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5091 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5092 } 5093 continue; 5094 } 5095 } 5096 if (isa<CXXThisExpr>(E)) { 5097 if (AlignedThis) { 5098 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5099 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5100 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5101 << getOpenMPClauseName(OMPC_aligned); 5102 } 5103 AlignedThis = E; 5104 continue; 5105 } 5106 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5107 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5108 } 5109 // The optional parameter of the aligned clause, alignment, must be a constant 5110 // positive integer expression. If no optional parameter is specified, 5111 // implementation-defined default alignments for SIMD instructions on the 5112 // target platforms are assumed. 5113 SmallVector<const Expr *, 4> NewAligns; 5114 for (Expr *E : Alignments) { 5115 ExprResult Align; 5116 if (E) 5117 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5118 NewAligns.push_back(Align.get()); 5119 } 5120 // OpenMP [2.8.2, declare simd construct, Description] 5121 // The linear clause declares one or more list items to be private to a SIMD 5122 // lane and to have a linear relationship with respect to the iteration space 5123 // of a loop. 5124 // The special this pointer can be used as if was one of the arguments to the 5125 // function in any of the linear, aligned, or uniform clauses. 5126 // When a linear-step expression is specified in a linear clause it must be 5127 // either a constant integer expression or an integer-typed parameter that is 5128 // specified in a uniform clause on the directive. 5129 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5130 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5131 auto MI = LinModifiers.begin(); 5132 for (const Expr *E : Linears) { 5133 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5134 ++MI; 5135 E = E->IgnoreParenImpCasts(); 5136 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5137 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5138 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5139 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5140 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5141 ->getCanonicalDecl() == CanonPVD) { 5142 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5143 // A list-item cannot appear in more than one linear clause. 5144 if (LinearArgs.count(CanonPVD) > 0) { 5145 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5146 << getOpenMPClauseName(OMPC_linear) 5147 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5148 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5149 diag::note_omp_explicit_dsa) 5150 << getOpenMPClauseName(OMPC_linear); 5151 continue; 5152 } 5153 // Each argument can appear in at most one uniform or linear clause. 5154 if (UniformedArgs.count(CanonPVD) > 0) { 5155 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5156 << getOpenMPClauseName(OMPC_linear) 5157 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5158 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5159 diag::note_omp_explicit_dsa) 5160 << getOpenMPClauseName(OMPC_uniform); 5161 continue; 5162 } 5163 LinearArgs[CanonPVD] = E; 5164 if (E->isValueDependent() || E->isTypeDependent() || 5165 E->isInstantiationDependent() || 5166 E->containsUnexpandedParameterPack()) 5167 continue; 5168 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5169 PVD->getOriginalType()); 5170 continue; 5171 } 5172 } 5173 if (isa<CXXThisExpr>(E)) { 5174 if (UniformedLinearThis) { 5175 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5176 << getOpenMPClauseName(OMPC_linear) 5177 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5178 << E->getSourceRange(); 5179 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5180 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5181 : OMPC_linear); 5182 continue; 5183 } 5184 UniformedLinearThis = E; 5185 if (E->isValueDependent() || E->isTypeDependent() || 5186 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5187 continue; 5188 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5189 E->getType()); 5190 continue; 5191 } 5192 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5193 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5194 } 5195 Expr *Step = nullptr; 5196 Expr *NewStep = nullptr; 5197 SmallVector<Expr *, 4> NewSteps; 5198 for (Expr *E : Steps) { 5199 // Skip the same step expression, it was checked already. 5200 if (Step == E || !E) { 5201 NewSteps.push_back(E ? NewStep : nullptr); 5202 continue; 5203 } 5204 Step = E; 5205 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5206 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5207 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5208 if (UniformedArgs.count(CanonPVD) == 0) { 5209 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5210 << Step->getSourceRange(); 5211 } else if (E->isValueDependent() || E->isTypeDependent() || 5212 E->isInstantiationDependent() || 5213 E->containsUnexpandedParameterPack() || 5214 CanonPVD->getType()->hasIntegerRepresentation()) { 5215 NewSteps.push_back(Step); 5216 } else { 5217 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5218 << Step->getSourceRange(); 5219 } 5220 continue; 5221 } 5222 NewStep = Step; 5223 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5224 !Step->isInstantiationDependent() && 5225 !Step->containsUnexpandedParameterPack()) { 5226 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5227 .get(); 5228 if (NewStep) 5229 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5230 } 5231 NewSteps.push_back(NewStep); 5232 } 5233 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5234 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5235 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5236 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5237 const_cast<Expr **>(Linears.data()), Linears.size(), 5238 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5239 NewSteps.data(), NewSteps.size(), SR); 5240 ADecl->addAttr(NewAttr); 5241 return DG; 5242 } 5243 5244 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5245 QualType NewType) { 5246 assert(NewType->isFunctionProtoType() && 5247 "Expected function type with prototype."); 5248 assert(FD->getType()->isFunctionNoProtoType() && 5249 "Expected function with type with no prototype."); 5250 assert(FDWithProto->getType()->isFunctionProtoType() && 5251 "Expected function with prototype."); 5252 // Synthesize parameters with the same types. 5253 FD->setType(NewType); 5254 SmallVector<ParmVarDecl *, 16> Params; 5255 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5256 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5257 SourceLocation(), nullptr, P->getType(), 5258 /*TInfo=*/nullptr, SC_None, nullptr); 5259 Param->setScopeInfo(0, Params.size()); 5260 Param->setImplicit(); 5261 Params.push_back(Param); 5262 } 5263 5264 FD->setParams(Params); 5265 } 5266 5267 Optional<std::pair<FunctionDecl *, Expr *>> 5268 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5269 Expr *VariantRef, SourceRange SR) { 5270 if (!DG || DG.get().isNull()) 5271 return None; 5272 5273 const int VariantId = 1; 5274 // Must be applied only to single decl. 5275 if (!DG.get().isSingleDecl()) { 5276 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5277 << VariantId << SR; 5278 return None; 5279 } 5280 Decl *ADecl = DG.get().getSingleDecl(); 5281 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5282 ADecl = FTD->getTemplatedDecl(); 5283 5284 // Decl must be a function. 5285 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5286 if (!FD) { 5287 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5288 << VariantId << SR; 5289 return None; 5290 } 5291 5292 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5293 return FD->hasAttrs() && 5294 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5295 FD->hasAttr<TargetAttr>()); 5296 }; 5297 // OpenMP is not compatible with CPU-specific attributes. 5298 if (HasMultiVersionAttributes(FD)) { 5299 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5300 << SR; 5301 return None; 5302 } 5303 5304 // Allow #pragma omp declare variant only if the function is not used. 5305 if (FD->isUsed(false)) 5306 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5307 << FD->getLocation(); 5308 5309 // Check if the function was emitted already. 5310 const FunctionDecl *Definition; 5311 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5312 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5313 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5314 << FD->getLocation(); 5315 5316 // The VariantRef must point to function. 5317 if (!VariantRef) { 5318 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5319 return None; 5320 } 5321 5322 // Do not check templates, wait until instantiation. 5323 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5324 VariantRef->containsUnexpandedParameterPack() || 5325 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5326 return std::make_pair(FD, VariantRef); 5327 5328 // Convert VariantRef expression to the type of the original function to 5329 // resolve possible conflicts. 5330 ExprResult VariantRefCast; 5331 if (LangOpts.CPlusPlus) { 5332 QualType FnPtrType; 5333 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5334 if (Method && !Method->isStatic()) { 5335 const Type *ClassType = 5336 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5337 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5338 ExprResult ER; 5339 { 5340 // Build adrr_of unary op to correctly handle type checks for member 5341 // functions. 5342 Sema::TentativeAnalysisScope Trap(*this); 5343 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5344 VariantRef); 5345 } 5346 if (!ER.isUsable()) { 5347 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5348 << VariantId << VariantRef->getSourceRange(); 5349 return None; 5350 } 5351 VariantRef = ER.get(); 5352 } else { 5353 FnPtrType = Context.getPointerType(FD->getType()); 5354 } 5355 ImplicitConversionSequence ICS = 5356 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5357 /*SuppressUserConversions=*/false, 5358 /*AllowExplicit=*/false, 5359 /*InOverloadResolution=*/false, 5360 /*CStyle=*/false, 5361 /*AllowObjCWritebackConversion=*/false); 5362 if (ICS.isFailure()) { 5363 Diag(VariantRef->getExprLoc(), 5364 diag::err_omp_declare_variant_incompat_types) 5365 << VariantRef->getType() 5366 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5367 << VariantRef->getSourceRange(); 5368 return None; 5369 } 5370 VariantRefCast = PerformImplicitConversion( 5371 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5372 if (!VariantRefCast.isUsable()) 5373 return None; 5374 // Drop previously built artificial addr_of unary op for member functions. 5375 if (Method && !Method->isStatic()) { 5376 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5377 if (auto *UO = dyn_cast<UnaryOperator>( 5378 PossibleAddrOfVariantRef->IgnoreImplicit())) 5379 VariantRefCast = UO->getSubExpr(); 5380 } 5381 } else { 5382 VariantRefCast = VariantRef; 5383 } 5384 5385 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5386 if (!ER.isUsable() || 5387 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5388 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5389 << VariantId << VariantRef->getSourceRange(); 5390 return None; 5391 } 5392 5393 // The VariantRef must point to function. 5394 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5395 if (!DRE) { 5396 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5397 << VariantId << VariantRef->getSourceRange(); 5398 return None; 5399 } 5400 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5401 if (!NewFD) { 5402 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5403 << VariantId << VariantRef->getSourceRange(); 5404 return None; 5405 } 5406 5407 // Check if function types are compatible in C. 5408 if (!LangOpts.CPlusPlus) { 5409 QualType NewType = 5410 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5411 if (NewType.isNull()) { 5412 Diag(VariantRef->getExprLoc(), 5413 diag::err_omp_declare_variant_incompat_types) 5414 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5415 return None; 5416 } 5417 if (NewType->isFunctionProtoType()) { 5418 if (FD->getType()->isFunctionNoProtoType()) 5419 setPrototype(*this, FD, NewFD, NewType); 5420 else if (NewFD->getType()->isFunctionNoProtoType()) 5421 setPrototype(*this, NewFD, FD, NewType); 5422 } 5423 } 5424 5425 // Check if variant function is not marked with declare variant directive. 5426 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5427 Diag(VariantRef->getExprLoc(), 5428 diag::warn_omp_declare_variant_marked_as_declare_variant) 5429 << VariantRef->getSourceRange(); 5430 SourceRange SR = 5431 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5432 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5433 return None; 5434 } 5435 5436 enum DoesntSupport { 5437 VirtFuncs = 1, 5438 Constructors = 3, 5439 Destructors = 4, 5440 DeletedFuncs = 5, 5441 DefaultedFuncs = 6, 5442 ConstexprFuncs = 7, 5443 ConstevalFuncs = 8, 5444 }; 5445 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5446 if (CXXFD->isVirtual()) { 5447 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5448 << VirtFuncs; 5449 return None; 5450 } 5451 5452 if (isa<CXXConstructorDecl>(FD)) { 5453 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5454 << Constructors; 5455 return None; 5456 } 5457 5458 if (isa<CXXDestructorDecl>(FD)) { 5459 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5460 << Destructors; 5461 return None; 5462 } 5463 } 5464 5465 if (FD->isDeleted()) { 5466 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5467 << DeletedFuncs; 5468 return None; 5469 } 5470 5471 if (FD->isDefaulted()) { 5472 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5473 << DefaultedFuncs; 5474 return None; 5475 } 5476 5477 if (FD->isConstexpr()) { 5478 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5479 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5480 return None; 5481 } 5482 5483 // Check general compatibility. 5484 if (areMultiversionVariantFunctionsCompatible( 5485 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5486 PartialDiagnosticAt(SourceLocation(), 5487 PartialDiagnostic::NullDiagnostic()), 5488 PartialDiagnosticAt( 5489 VariantRef->getExprLoc(), 5490 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5491 PartialDiagnosticAt(VariantRef->getExprLoc(), 5492 PDiag(diag::err_omp_declare_variant_diff) 5493 << FD->getLocation()), 5494 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5495 /*CLinkageMayDiffer=*/true)) 5496 return None; 5497 return std::make_pair(FD, cast<Expr>(DRE)); 5498 } 5499 5500 void Sema::ActOnOpenMPDeclareVariantDirective( 5501 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5502 ArrayRef<OMPCtxSelectorData> Data) { 5503 if (Data.empty()) 5504 return; 5505 SmallVector<Expr *, 4> CtxScores; 5506 SmallVector<unsigned, 4> CtxSets; 5507 SmallVector<unsigned, 4> Ctxs; 5508 SmallVector<StringRef, 4> ImplVendors, DeviceKinds; 5509 bool IsError = false; 5510 for (const OMPCtxSelectorData &D : Data) { 5511 OpenMPContextSelectorSetKind CtxSet = D.CtxSet; 5512 OpenMPContextSelectorKind Ctx = D.Ctx; 5513 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) 5514 return; 5515 Expr *Score = nullptr; 5516 if (D.Score.isUsable()) { 5517 Score = D.Score.get(); 5518 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5519 !Score->isInstantiationDependent() && 5520 !Score->containsUnexpandedParameterPack()) { 5521 Score = 5522 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) 5523 .get(); 5524 if (Score) 5525 Score = VerifyIntegerConstantExpression(Score).get(); 5526 } 5527 } else { 5528 // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors. 5529 // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and 5530 // 2^(l+2), respectively, where l is the number of traits in the construct 5531 // set. 5532 // TODO: implement correct logic for isa and arch traits. 5533 // TODO: take the construct context set into account when it is 5534 // implemented. 5535 int L = 0; // Currently set the number of traits in construct set to 0, 5536 // since the construct trait set in not supported yet. 5537 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind) 5538 Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get(); 5539 else 5540 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5541 } 5542 switch (Ctx) { 5543 case OMP_CTX_vendor: 5544 assert(CtxSet == OMP_CTX_SET_implementation && 5545 "Expected implementation context selector set."); 5546 ImplVendors.append(D.Names.begin(), D.Names.end()); 5547 break; 5548 case OMP_CTX_kind: 5549 assert(CtxSet == OMP_CTX_SET_device && 5550 "Expected device context selector set."); 5551 DeviceKinds.append(D.Names.begin(), D.Names.end()); 5552 break; 5553 case OMP_CTX_unknown: 5554 llvm_unreachable("Unknown context selector kind."); 5555 } 5556 IsError = IsError || !Score; 5557 CtxSets.push_back(CtxSet); 5558 Ctxs.push_back(Ctx); 5559 CtxScores.push_back(Score); 5560 } 5561 if (!IsError) { 5562 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5563 Context, VariantRef, CtxScores.begin(), CtxScores.size(), 5564 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), 5565 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(), 5566 DeviceKinds.size(), SR); 5567 FD->addAttr(NewAttr); 5568 } 5569 } 5570 5571 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5572 FunctionDecl *Func, 5573 bool MightBeOdrUse) { 5574 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5575 5576 if (!Func->isDependentContext() && Func->hasAttrs()) { 5577 for (OMPDeclareVariantAttr *A : 5578 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5579 // TODO: add checks for active OpenMP context where possible. 5580 Expr *VariantRef = A->getVariantFuncRef(); 5581 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5582 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5583 if (!F->isDefined() && F->isTemplateInstantiation()) 5584 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5585 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5586 } 5587 } 5588 } 5589 5590 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5591 Stmt *AStmt, 5592 SourceLocation StartLoc, 5593 SourceLocation EndLoc) { 5594 if (!AStmt) 5595 return StmtError(); 5596 5597 auto *CS = cast<CapturedStmt>(AStmt); 5598 // 1.2.2 OpenMP Language Terminology 5599 // Structured block - An executable statement with a single entry at the 5600 // top and a single exit at the bottom. 5601 // The point of exit cannot be a branch out of the structured block. 5602 // longjmp() and throw() must not violate the entry/exit criteria. 5603 CS->getCapturedDecl()->setNothrow(); 5604 5605 setFunctionHasBranchProtectedScope(); 5606 5607 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5608 DSAStack->isCancelRegion()); 5609 } 5610 5611 namespace { 5612 /// Iteration space of a single for loop. 5613 struct LoopIterationSpace final { 5614 /// True if the condition operator is the strict compare operator (<, > or 5615 /// !=). 5616 bool IsStrictCompare = false; 5617 /// Condition of the loop. 5618 Expr *PreCond = nullptr; 5619 /// This expression calculates the number of iterations in the loop. 5620 /// It is always possible to calculate it before starting the loop. 5621 Expr *NumIterations = nullptr; 5622 /// The loop counter variable. 5623 Expr *CounterVar = nullptr; 5624 /// Private loop counter variable. 5625 Expr *PrivateCounterVar = nullptr; 5626 /// This is initializer for the initial value of #CounterVar. 5627 Expr *CounterInit = nullptr; 5628 /// This is step for the #CounterVar used to generate its update: 5629 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5630 Expr *CounterStep = nullptr; 5631 /// Should step be subtracted? 5632 bool Subtract = false; 5633 /// Source range of the loop init. 5634 SourceRange InitSrcRange; 5635 /// Source range of the loop condition. 5636 SourceRange CondSrcRange; 5637 /// Source range of the loop increment. 5638 SourceRange IncSrcRange; 5639 /// Minimum value that can have the loop control variable. Used to support 5640 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5641 /// since only such variables can be used in non-loop invariant expressions. 5642 Expr *MinValue = nullptr; 5643 /// Maximum value that can have the loop control variable. Used to support 5644 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5645 /// since only such variables can be used in non-loop invariant expressions. 5646 Expr *MaxValue = nullptr; 5647 /// true, if the lower bound depends on the outer loop control var. 5648 bool IsNonRectangularLB = false; 5649 /// true, if the upper bound depends on the outer loop control var. 5650 bool IsNonRectangularUB = false; 5651 /// Index of the loop this loop depends on and forms non-rectangular loop 5652 /// nest. 5653 unsigned LoopDependentIdx = 0; 5654 /// Final condition for the non-rectangular loop nest support. It is used to 5655 /// check that the number of iterations for this particular counter must be 5656 /// finished. 5657 Expr *FinalCondition = nullptr; 5658 }; 5659 5660 /// Helper class for checking canonical form of the OpenMP loops and 5661 /// extracting iteration space of each loop in the loop nest, that will be used 5662 /// for IR generation. 5663 class OpenMPIterationSpaceChecker { 5664 /// Reference to Sema. 5665 Sema &SemaRef; 5666 /// Data-sharing stack. 5667 DSAStackTy &Stack; 5668 /// A location for diagnostics (when there is no some better location). 5669 SourceLocation DefaultLoc; 5670 /// A location for diagnostics (when increment is not compatible). 5671 SourceLocation ConditionLoc; 5672 /// A source location for referring to loop init later. 5673 SourceRange InitSrcRange; 5674 /// A source location for referring to condition later. 5675 SourceRange ConditionSrcRange; 5676 /// A source location for referring to increment later. 5677 SourceRange IncrementSrcRange; 5678 /// Loop variable. 5679 ValueDecl *LCDecl = nullptr; 5680 /// Reference to loop variable. 5681 Expr *LCRef = nullptr; 5682 /// Lower bound (initializer for the var). 5683 Expr *LB = nullptr; 5684 /// Upper bound. 5685 Expr *UB = nullptr; 5686 /// Loop step (increment). 5687 Expr *Step = nullptr; 5688 /// This flag is true when condition is one of: 5689 /// Var < UB 5690 /// Var <= UB 5691 /// UB > Var 5692 /// UB >= Var 5693 /// This will have no value when the condition is != 5694 llvm::Optional<bool> TestIsLessOp; 5695 /// This flag is true when condition is strict ( < or > ). 5696 bool TestIsStrictOp = false; 5697 /// This flag is true when step is subtracted on each iteration. 5698 bool SubtractStep = false; 5699 /// The outer loop counter this loop depends on (if any). 5700 const ValueDecl *DepDecl = nullptr; 5701 /// Contains number of loop (starts from 1) on which loop counter init 5702 /// expression of this loop depends on. 5703 Optional<unsigned> InitDependOnLC; 5704 /// Contains number of loop (starts from 1) on which loop counter condition 5705 /// expression of this loop depends on. 5706 Optional<unsigned> CondDependOnLC; 5707 /// Checks if the provide statement depends on the loop counter. 5708 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5709 /// Original condition required for checking of the exit condition for 5710 /// non-rectangular loop. 5711 Expr *Condition = nullptr; 5712 5713 public: 5714 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5715 SourceLocation DefaultLoc) 5716 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5717 ConditionLoc(DefaultLoc) {} 5718 /// Check init-expr for canonical loop form and save loop counter 5719 /// variable - #Var and its initialization value - #LB. 5720 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5721 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5722 /// for less/greater and for strict/non-strict comparison. 5723 bool checkAndSetCond(Expr *S); 5724 /// Check incr-expr for canonical loop form and return true if it 5725 /// does not conform, otherwise save loop step (#Step). 5726 bool checkAndSetInc(Expr *S); 5727 /// Return the loop counter variable. 5728 ValueDecl *getLoopDecl() const { return LCDecl; } 5729 /// Return the reference expression to loop counter variable. 5730 Expr *getLoopDeclRefExpr() const { return LCRef; } 5731 /// Source range of the loop init. 5732 SourceRange getInitSrcRange() const { return InitSrcRange; } 5733 /// Source range of the loop condition. 5734 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5735 /// Source range of the loop increment. 5736 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5737 /// True if the step should be subtracted. 5738 bool shouldSubtractStep() const { return SubtractStep; } 5739 /// True, if the compare operator is strict (<, > or !=). 5740 bool isStrictTestOp() const { return TestIsStrictOp; } 5741 /// Build the expression to calculate the number of iterations. 5742 Expr *buildNumIterations( 5743 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5744 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5745 /// Build the precondition expression for the loops. 5746 Expr * 5747 buildPreCond(Scope *S, Expr *Cond, 5748 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5749 /// Build reference expression to the counter be used for codegen. 5750 DeclRefExpr * 5751 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5752 DSAStackTy &DSA) const; 5753 /// Build reference expression to the private counter be used for 5754 /// codegen. 5755 Expr *buildPrivateCounterVar() const; 5756 /// Build initialization of the counter be used for codegen. 5757 Expr *buildCounterInit() const; 5758 /// Build step of the counter be used for codegen. 5759 Expr *buildCounterStep() const; 5760 /// Build loop data with counter value for depend clauses in ordered 5761 /// directives. 5762 Expr * 5763 buildOrderedLoopData(Scope *S, Expr *Counter, 5764 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5765 SourceLocation Loc, Expr *Inc = nullptr, 5766 OverloadedOperatorKind OOK = OO_Amp); 5767 /// Builds the minimum value for the loop counter. 5768 std::pair<Expr *, Expr *> buildMinMaxValues( 5769 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5770 /// Builds final condition for the non-rectangular loops. 5771 Expr *buildFinalCondition(Scope *S) const; 5772 /// Return true if any expression is dependent. 5773 bool dependent() const; 5774 /// Returns true if the initializer forms non-rectangular loop. 5775 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5776 /// Returns true if the condition forms non-rectangular loop. 5777 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5778 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5779 unsigned getLoopDependentIdx() const { 5780 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5781 } 5782 5783 private: 5784 /// Check the right-hand side of an assignment in the increment 5785 /// expression. 5786 bool checkAndSetIncRHS(Expr *RHS); 5787 /// Helper to set loop counter variable and its initializer. 5788 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5789 bool EmitDiags); 5790 /// Helper to set upper bound. 5791 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5792 SourceRange SR, SourceLocation SL); 5793 /// Helper to set loop increment. 5794 bool setStep(Expr *NewStep, bool Subtract); 5795 }; 5796 5797 bool OpenMPIterationSpaceChecker::dependent() const { 5798 if (!LCDecl) { 5799 assert(!LB && !UB && !Step); 5800 return false; 5801 } 5802 return LCDecl->getType()->isDependentType() || 5803 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5804 (Step && Step->isValueDependent()); 5805 } 5806 5807 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5808 Expr *NewLCRefExpr, 5809 Expr *NewLB, bool EmitDiags) { 5810 // State consistency checking to ensure correct usage. 5811 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5812 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5813 if (!NewLCDecl || !NewLB) 5814 return true; 5815 LCDecl = getCanonicalDecl(NewLCDecl); 5816 LCRef = NewLCRefExpr; 5817 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5818 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5819 if ((Ctor->isCopyOrMoveConstructor() || 5820 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5821 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5822 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5823 LB = NewLB; 5824 if (EmitDiags) 5825 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5826 return false; 5827 } 5828 5829 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5830 llvm::Optional<bool> LessOp, 5831 bool StrictOp, SourceRange SR, 5832 SourceLocation SL) { 5833 // State consistency checking to ensure correct usage. 5834 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5835 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5836 if (!NewUB) 5837 return true; 5838 UB = NewUB; 5839 if (LessOp) 5840 TestIsLessOp = LessOp; 5841 TestIsStrictOp = StrictOp; 5842 ConditionSrcRange = SR; 5843 ConditionLoc = SL; 5844 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5845 return false; 5846 } 5847 5848 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5849 // State consistency checking to ensure correct usage. 5850 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5851 if (!NewStep) 5852 return true; 5853 if (!NewStep->isValueDependent()) { 5854 // Check that the step is integer expression. 5855 SourceLocation StepLoc = NewStep->getBeginLoc(); 5856 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5857 StepLoc, getExprAsWritten(NewStep)); 5858 if (Val.isInvalid()) 5859 return true; 5860 NewStep = Val.get(); 5861 5862 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5863 // If test-expr is of form var relational-op b and relational-op is < or 5864 // <= then incr-expr must cause var to increase on each iteration of the 5865 // loop. If test-expr is of form var relational-op b and relational-op is 5866 // > or >= then incr-expr must cause var to decrease on each iteration of 5867 // the loop. 5868 // If test-expr is of form b relational-op var and relational-op is < or 5869 // <= then incr-expr must cause var to decrease on each iteration of the 5870 // loop. If test-expr is of form b relational-op var and relational-op is 5871 // > or >= then incr-expr must cause var to increase on each iteration of 5872 // the loop. 5873 llvm::APSInt Result; 5874 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5875 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5876 bool IsConstNeg = 5877 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5878 bool IsConstPos = 5879 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5880 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5881 5882 // != with increment is treated as <; != with decrement is treated as > 5883 if (!TestIsLessOp.hasValue()) 5884 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5885 if (UB && (IsConstZero || 5886 (TestIsLessOp.getValue() ? 5887 (IsConstNeg || (IsUnsigned && Subtract)) : 5888 (IsConstPos || (IsUnsigned && !Subtract))))) { 5889 SemaRef.Diag(NewStep->getExprLoc(), 5890 diag::err_omp_loop_incr_not_compatible) 5891 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5892 SemaRef.Diag(ConditionLoc, 5893 diag::note_omp_loop_cond_requres_compatible_incr) 5894 << TestIsLessOp.getValue() << ConditionSrcRange; 5895 return true; 5896 } 5897 if (TestIsLessOp.getValue() == Subtract) { 5898 NewStep = 5899 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5900 .get(); 5901 Subtract = !Subtract; 5902 } 5903 } 5904 5905 Step = NewStep; 5906 SubtractStep = Subtract; 5907 return false; 5908 } 5909 5910 namespace { 5911 /// Checker for the non-rectangular loops. Checks if the initializer or 5912 /// condition expression references loop counter variable. 5913 class LoopCounterRefChecker final 5914 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5915 Sema &SemaRef; 5916 DSAStackTy &Stack; 5917 const ValueDecl *CurLCDecl = nullptr; 5918 const ValueDecl *DepDecl = nullptr; 5919 const ValueDecl *PrevDepDecl = nullptr; 5920 bool IsInitializer = true; 5921 unsigned BaseLoopId = 0; 5922 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5923 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5924 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5925 << (IsInitializer ? 0 : 1); 5926 return false; 5927 } 5928 const auto &&Data = Stack.isLoopControlVariable(VD); 5929 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5930 // The type of the loop iterator on which we depend may not have a random 5931 // access iterator type. 5932 if (Data.first && VD->getType()->isRecordType()) { 5933 SmallString<128> Name; 5934 llvm::raw_svector_ostream OS(Name); 5935 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5936 /*Qualified=*/true); 5937 SemaRef.Diag(E->getExprLoc(), 5938 diag::err_omp_wrong_dependency_iterator_type) 5939 << OS.str(); 5940 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5941 return false; 5942 } 5943 if (Data.first && 5944 (DepDecl || (PrevDepDecl && 5945 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5946 if (!DepDecl && PrevDepDecl) 5947 DepDecl = PrevDepDecl; 5948 SmallString<128> Name; 5949 llvm::raw_svector_ostream OS(Name); 5950 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5951 /*Qualified=*/true); 5952 SemaRef.Diag(E->getExprLoc(), 5953 diag::err_omp_invariant_or_linear_dependency) 5954 << OS.str(); 5955 return false; 5956 } 5957 if (Data.first) { 5958 DepDecl = VD; 5959 BaseLoopId = Data.first; 5960 } 5961 return Data.first; 5962 } 5963 5964 public: 5965 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5966 const ValueDecl *VD = E->getDecl(); 5967 if (isa<VarDecl>(VD)) 5968 return checkDecl(E, VD); 5969 return false; 5970 } 5971 bool VisitMemberExpr(const MemberExpr *E) { 5972 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5973 const ValueDecl *VD = E->getMemberDecl(); 5974 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5975 return checkDecl(E, VD); 5976 } 5977 return false; 5978 } 5979 bool VisitStmt(const Stmt *S) { 5980 bool Res = false; 5981 for (const Stmt *Child : S->children()) 5982 Res = (Child && Visit(Child)) || Res; 5983 return Res; 5984 } 5985 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5986 const ValueDecl *CurLCDecl, bool IsInitializer, 5987 const ValueDecl *PrevDepDecl = nullptr) 5988 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5989 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5990 unsigned getBaseLoopId() const { 5991 assert(CurLCDecl && "Expected loop dependency."); 5992 return BaseLoopId; 5993 } 5994 const ValueDecl *getDepDecl() const { 5995 assert(CurLCDecl && "Expected loop dependency."); 5996 return DepDecl; 5997 } 5998 }; 5999 } // namespace 6000 6001 Optional<unsigned> 6002 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6003 bool IsInitializer) { 6004 // Check for the non-rectangular loops. 6005 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6006 DepDecl); 6007 if (LoopStmtChecker.Visit(S)) { 6008 DepDecl = LoopStmtChecker.getDepDecl(); 6009 return LoopStmtChecker.getBaseLoopId(); 6010 } 6011 return llvm::None; 6012 } 6013 6014 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6015 // Check init-expr for canonical loop form and save loop counter 6016 // variable - #Var and its initialization value - #LB. 6017 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6018 // var = lb 6019 // integer-type var = lb 6020 // random-access-iterator-type var = lb 6021 // pointer-type var = lb 6022 // 6023 if (!S) { 6024 if (EmitDiags) { 6025 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6026 } 6027 return true; 6028 } 6029 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6030 if (!ExprTemp->cleanupsHaveSideEffects()) 6031 S = ExprTemp->getSubExpr(); 6032 6033 InitSrcRange = S->getSourceRange(); 6034 if (Expr *E = dyn_cast<Expr>(S)) 6035 S = E->IgnoreParens(); 6036 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6037 if (BO->getOpcode() == BO_Assign) { 6038 Expr *LHS = BO->getLHS()->IgnoreParens(); 6039 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6040 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6041 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6042 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6043 EmitDiags); 6044 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6045 } 6046 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6047 if (ME->isArrow() && 6048 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6049 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6050 EmitDiags); 6051 } 6052 } 6053 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6054 if (DS->isSingleDecl()) { 6055 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6056 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6057 // Accept non-canonical init form here but emit ext. warning. 6058 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6059 SemaRef.Diag(S->getBeginLoc(), 6060 diag::ext_omp_loop_not_canonical_init) 6061 << S->getSourceRange(); 6062 return setLCDeclAndLB( 6063 Var, 6064 buildDeclRefExpr(SemaRef, Var, 6065 Var->getType().getNonReferenceType(), 6066 DS->getBeginLoc()), 6067 Var->getInit(), EmitDiags); 6068 } 6069 } 6070 } 6071 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6072 if (CE->getOperator() == OO_Equal) { 6073 Expr *LHS = CE->getArg(0); 6074 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6075 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6076 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6077 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6078 EmitDiags); 6079 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6080 } 6081 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6082 if (ME->isArrow() && 6083 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6084 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6085 EmitDiags); 6086 } 6087 } 6088 } 6089 6090 if (dependent() || SemaRef.CurContext->isDependentContext()) 6091 return false; 6092 if (EmitDiags) { 6093 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6094 << S->getSourceRange(); 6095 } 6096 return true; 6097 } 6098 6099 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6100 /// variable (which may be the loop variable) if possible. 6101 static const ValueDecl *getInitLCDecl(const Expr *E) { 6102 if (!E) 6103 return nullptr; 6104 E = getExprAsWritten(E); 6105 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6106 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6107 if ((Ctor->isCopyOrMoveConstructor() || 6108 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6109 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6110 E = CE->getArg(0)->IgnoreParenImpCasts(); 6111 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6112 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6113 return getCanonicalDecl(VD); 6114 } 6115 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6116 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6117 return getCanonicalDecl(ME->getMemberDecl()); 6118 return nullptr; 6119 } 6120 6121 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6122 // Check test-expr for canonical form, save upper-bound UB, flags for 6123 // less/greater and for strict/non-strict comparison. 6124 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6125 // var relational-op b 6126 // b relational-op var 6127 // 6128 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6129 if (!S) { 6130 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6131 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6132 return true; 6133 } 6134 Condition = S; 6135 S = getExprAsWritten(S); 6136 SourceLocation CondLoc = S->getBeginLoc(); 6137 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6138 if (BO->isRelationalOp()) { 6139 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6140 return setUB(BO->getRHS(), 6141 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6142 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6143 BO->getSourceRange(), BO->getOperatorLoc()); 6144 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6145 return setUB(BO->getLHS(), 6146 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6147 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6148 BO->getSourceRange(), BO->getOperatorLoc()); 6149 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6150 return setUB( 6151 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6152 /*LessOp=*/llvm::None, 6153 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6154 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6155 if (CE->getNumArgs() == 2) { 6156 auto Op = CE->getOperator(); 6157 switch (Op) { 6158 case OO_Greater: 6159 case OO_GreaterEqual: 6160 case OO_Less: 6161 case OO_LessEqual: 6162 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6163 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6164 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6165 CE->getOperatorLoc()); 6166 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6167 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6168 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6169 CE->getOperatorLoc()); 6170 break; 6171 case OO_ExclaimEqual: 6172 if (IneqCondIsCanonical) 6173 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6174 : CE->getArg(0), 6175 /*LessOp=*/llvm::None, 6176 /*StrictOp=*/true, CE->getSourceRange(), 6177 CE->getOperatorLoc()); 6178 break; 6179 default: 6180 break; 6181 } 6182 } 6183 } 6184 if (dependent() || SemaRef.CurContext->isDependentContext()) 6185 return false; 6186 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6187 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6188 return true; 6189 } 6190 6191 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6192 // RHS of canonical loop form increment can be: 6193 // var + incr 6194 // incr + var 6195 // var - incr 6196 // 6197 RHS = RHS->IgnoreParenImpCasts(); 6198 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6199 if (BO->isAdditiveOp()) { 6200 bool IsAdd = BO->getOpcode() == BO_Add; 6201 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6202 return setStep(BO->getRHS(), !IsAdd); 6203 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6204 return setStep(BO->getLHS(), /*Subtract=*/false); 6205 } 6206 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6207 bool IsAdd = CE->getOperator() == OO_Plus; 6208 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6209 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6210 return setStep(CE->getArg(1), !IsAdd); 6211 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6212 return setStep(CE->getArg(0), /*Subtract=*/false); 6213 } 6214 } 6215 if (dependent() || SemaRef.CurContext->isDependentContext()) 6216 return false; 6217 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6218 << RHS->getSourceRange() << LCDecl; 6219 return true; 6220 } 6221 6222 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6223 // Check incr-expr for canonical loop form and return true if it 6224 // does not conform. 6225 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6226 // ++var 6227 // var++ 6228 // --var 6229 // var-- 6230 // var += incr 6231 // var -= incr 6232 // var = var + incr 6233 // var = incr + var 6234 // var = var - incr 6235 // 6236 if (!S) { 6237 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6238 return true; 6239 } 6240 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6241 if (!ExprTemp->cleanupsHaveSideEffects()) 6242 S = ExprTemp->getSubExpr(); 6243 6244 IncrementSrcRange = S->getSourceRange(); 6245 S = S->IgnoreParens(); 6246 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6247 if (UO->isIncrementDecrementOp() && 6248 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6249 return setStep(SemaRef 6250 .ActOnIntegerConstant(UO->getBeginLoc(), 6251 (UO->isDecrementOp() ? -1 : 1)) 6252 .get(), 6253 /*Subtract=*/false); 6254 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6255 switch (BO->getOpcode()) { 6256 case BO_AddAssign: 6257 case BO_SubAssign: 6258 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6259 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6260 break; 6261 case BO_Assign: 6262 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6263 return checkAndSetIncRHS(BO->getRHS()); 6264 break; 6265 default: 6266 break; 6267 } 6268 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6269 switch (CE->getOperator()) { 6270 case OO_PlusPlus: 6271 case OO_MinusMinus: 6272 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6273 return setStep(SemaRef 6274 .ActOnIntegerConstant( 6275 CE->getBeginLoc(), 6276 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6277 .get(), 6278 /*Subtract=*/false); 6279 break; 6280 case OO_PlusEqual: 6281 case OO_MinusEqual: 6282 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6283 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6284 break; 6285 case OO_Equal: 6286 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6287 return checkAndSetIncRHS(CE->getArg(1)); 6288 break; 6289 default: 6290 break; 6291 } 6292 } 6293 if (dependent() || SemaRef.CurContext->isDependentContext()) 6294 return false; 6295 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6296 << S->getSourceRange() << LCDecl; 6297 return true; 6298 } 6299 6300 static ExprResult 6301 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6302 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6303 if (SemaRef.CurContext->isDependentContext()) 6304 return ExprResult(Capture); 6305 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6306 return SemaRef.PerformImplicitConversion( 6307 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6308 /*AllowExplicit=*/true); 6309 auto I = Captures.find(Capture); 6310 if (I != Captures.end()) 6311 return buildCapture(SemaRef, Capture, I->second); 6312 DeclRefExpr *Ref = nullptr; 6313 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6314 Captures[Capture] = Ref; 6315 return Res; 6316 } 6317 6318 /// Build the expression to calculate the number of iterations. 6319 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6320 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6321 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6322 ExprResult Diff; 6323 QualType VarType = LCDecl->getType().getNonReferenceType(); 6324 if (VarType->isIntegerType() || VarType->isPointerType() || 6325 SemaRef.getLangOpts().CPlusPlus) { 6326 Expr *LBVal = LB; 6327 Expr *UBVal = UB; 6328 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6329 // max(LB(MinVal), LB(MaxVal)) 6330 if (InitDependOnLC) { 6331 const LoopIterationSpace &IS = 6332 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6333 InitDependOnLC.getValueOr( 6334 CondDependOnLC.getValueOr(0))]; 6335 if (!IS.MinValue || !IS.MaxValue) 6336 return nullptr; 6337 // OuterVar = Min 6338 ExprResult MinValue = 6339 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6340 if (!MinValue.isUsable()) 6341 return nullptr; 6342 6343 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6344 IS.CounterVar, MinValue.get()); 6345 if (!LBMinVal.isUsable()) 6346 return nullptr; 6347 // OuterVar = Min, LBVal 6348 LBMinVal = 6349 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6350 if (!LBMinVal.isUsable()) 6351 return nullptr; 6352 // (OuterVar = Min, LBVal) 6353 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6354 if (!LBMinVal.isUsable()) 6355 return nullptr; 6356 6357 // OuterVar = Max 6358 ExprResult MaxValue = 6359 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6360 if (!MaxValue.isUsable()) 6361 return nullptr; 6362 6363 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6364 IS.CounterVar, MaxValue.get()); 6365 if (!LBMaxVal.isUsable()) 6366 return nullptr; 6367 // OuterVar = Max, LBVal 6368 LBMaxVal = 6369 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6370 if (!LBMaxVal.isUsable()) 6371 return nullptr; 6372 // (OuterVar = Max, LBVal) 6373 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6374 if (!LBMaxVal.isUsable()) 6375 return nullptr; 6376 6377 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6378 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6379 if (!LBMin || !LBMax) 6380 return nullptr; 6381 // LB(MinVal) < LB(MaxVal) 6382 ExprResult MinLessMaxRes = 6383 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6384 if (!MinLessMaxRes.isUsable()) 6385 return nullptr; 6386 Expr *MinLessMax = 6387 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6388 if (!MinLessMax) 6389 return nullptr; 6390 if (TestIsLessOp.getValue()) { 6391 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6392 // LB(MaxVal)) 6393 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6394 MinLessMax, LBMin, LBMax); 6395 if (!MinLB.isUsable()) 6396 return nullptr; 6397 LBVal = MinLB.get(); 6398 } else { 6399 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6400 // LB(MaxVal)) 6401 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6402 MinLessMax, LBMax, LBMin); 6403 if (!MaxLB.isUsable()) 6404 return nullptr; 6405 LBVal = MaxLB.get(); 6406 } 6407 } 6408 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6409 // min(UB(MinVal), UB(MaxVal)) 6410 if (CondDependOnLC) { 6411 const LoopIterationSpace &IS = 6412 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6413 InitDependOnLC.getValueOr( 6414 CondDependOnLC.getValueOr(0))]; 6415 if (!IS.MinValue || !IS.MaxValue) 6416 return nullptr; 6417 // OuterVar = Min 6418 ExprResult MinValue = 6419 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6420 if (!MinValue.isUsable()) 6421 return nullptr; 6422 6423 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6424 IS.CounterVar, MinValue.get()); 6425 if (!UBMinVal.isUsable()) 6426 return nullptr; 6427 // OuterVar = Min, UBVal 6428 UBMinVal = 6429 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6430 if (!UBMinVal.isUsable()) 6431 return nullptr; 6432 // (OuterVar = Min, UBVal) 6433 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6434 if (!UBMinVal.isUsable()) 6435 return nullptr; 6436 6437 // OuterVar = Max 6438 ExprResult MaxValue = 6439 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6440 if (!MaxValue.isUsable()) 6441 return nullptr; 6442 6443 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6444 IS.CounterVar, MaxValue.get()); 6445 if (!UBMaxVal.isUsable()) 6446 return nullptr; 6447 // OuterVar = Max, UBVal 6448 UBMaxVal = 6449 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6450 if (!UBMaxVal.isUsable()) 6451 return nullptr; 6452 // (OuterVar = Max, UBVal) 6453 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6454 if (!UBMaxVal.isUsable()) 6455 return nullptr; 6456 6457 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6458 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6459 if (!UBMin || !UBMax) 6460 return nullptr; 6461 // UB(MinVal) > UB(MaxVal) 6462 ExprResult MinGreaterMaxRes = 6463 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6464 if (!MinGreaterMaxRes.isUsable()) 6465 return nullptr; 6466 Expr *MinGreaterMax = 6467 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6468 if (!MinGreaterMax) 6469 return nullptr; 6470 if (TestIsLessOp.getValue()) { 6471 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6472 // UB(MaxVal)) 6473 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6474 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6475 if (!MaxUB.isUsable()) 6476 return nullptr; 6477 UBVal = MaxUB.get(); 6478 } else { 6479 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6480 // UB(MaxVal)) 6481 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6482 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6483 if (!MinUB.isUsable()) 6484 return nullptr; 6485 UBVal = MinUB.get(); 6486 } 6487 } 6488 // Upper - Lower 6489 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6490 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6491 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6492 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6493 if (!Upper || !Lower) 6494 return nullptr; 6495 6496 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6497 6498 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6499 // BuildBinOp already emitted error, this one is to point user to upper 6500 // and lower bound, and to tell what is passed to 'operator-'. 6501 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6502 << Upper->getSourceRange() << Lower->getSourceRange(); 6503 return nullptr; 6504 } 6505 } 6506 6507 if (!Diff.isUsable()) 6508 return nullptr; 6509 6510 // Upper - Lower [- 1] 6511 if (TestIsStrictOp) 6512 Diff = SemaRef.BuildBinOp( 6513 S, DefaultLoc, BO_Sub, Diff.get(), 6514 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6515 if (!Diff.isUsable()) 6516 return nullptr; 6517 6518 // Upper - Lower [- 1] + Step 6519 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6520 if (!NewStep.isUsable()) 6521 return nullptr; 6522 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6523 if (!Diff.isUsable()) 6524 return nullptr; 6525 6526 // Parentheses (for dumping/debugging purposes only). 6527 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6528 if (!Diff.isUsable()) 6529 return nullptr; 6530 6531 // (Upper - Lower [- 1] + Step) / Step 6532 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6533 if (!Diff.isUsable()) 6534 return nullptr; 6535 6536 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6537 QualType Type = Diff.get()->getType(); 6538 ASTContext &C = SemaRef.Context; 6539 bool UseVarType = VarType->hasIntegerRepresentation() && 6540 C.getTypeSize(Type) > C.getTypeSize(VarType); 6541 if (!Type->isIntegerType() || UseVarType) { 6542 unsigned NewSize = 6543 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6544 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6545 : Type->hasSignedIntegerRepresentation(); 6546 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6547 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6548 Diff = SemaRef.PerformImplicitConversion( 6549 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6550 if (!Diff.isUsable()) 6551 return nullptr; 6552 } 6553 } 6554 if (LimitedType) { 6555 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6556 if (NewSize != C.getTypeSize(Type)) { 6557 if (NewSize < C.getTypeSize(Type)) { 6558 assert(NewSize == 64 && "incorrect loop var size"); 6559 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6560 << InitSrcRange << ConditionSrcRange; 6561 } 6562 QualType NewType = C.getIntTypeForBitwidth( 6563 NewSize, Type->hasSignedIntegerRepresentation() || 6564 C.getTypeSize(Type) < NewSize); 6565 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6566 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6567 Sema::AA_Converting, true); 6568 if (!Diff.isUsable()) 6569 return nullptr; 6570 } 6571 } 6572 } 6573 6574 return Diff.get(); 6575 } 6576 6577 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6578 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6579 // Do not build for iterators, they cannot be used in non-rectangular loop 6580 // nests. 6581 if (LCDecl->getType()->isRecordType()) 6582 return std::make_pair(nullptr, nullptr); 6583 // If we subtract, the min is in the condition, otherwise the min is in the 6584 // init value. 6585 Expr *MinExpr = nullptr; 6586 Expr *MaxExpr = nullptr; 6587 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6588 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6589 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6590 : CondDependOnLC.hasValue(); 6591 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6592 : InitDependOnLC.hasValue(); 6593 Expr *Lower = 6594 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6595 Expr *Upper = 6596 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6597 if (!Upper || !Lower) 6598 return std::make_pair(nullptr, nullptr); 6599 6600 if (TestIsLessOp.getValue()) 6601 MinExpr = Lower; 6602 else 6603 MaxExpr = Upper; 6604 6605 // Build minimum/maximum value based on number of iterations. 6606 ExprResult Diff; 6607 QualType VarType = LCDecl->getType().getNonReferenceType(); 6608 6609 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6610 if (!Diff.isUsable()) 6611 return std::make_pair(nullptr, nullptr); 6612 6613 // Upper - Lower [- 1] 6614 if (TestIsStrictOp) 6615 Diff = SemaRef.BuildBinOp( 6616 S, DefaultLoc, BO_Sub, Diff.get(), 6617 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6618 if (!Diff.isUsable()) 6619 return std::make_pair(nullptr, nullptr); 6620 6621 // Upper - Lower [- 1] + Step 6622 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6623 if (!NewStep.isUsable()) 6624 return std::make_pair(nullptr, nullptr); 6625 6626 // Parentheses (for dumping/debugging purposes only). 6627 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6628 if (!Diff.isUsable()) 6629 return std::make_pair(nullptr, nullptr); 6630 6631 // (Upper - Lower [- 1]) / Step 6632 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6633 if (!Diff.isUsable()) 6634 return std::make_pair(nullptr, nullptr); 6635 6636 // ((Upper - Lower [- 1]) / Step) * Step 6637 // Parentheses (for dumping/debugging purposes only). 6638 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6639 if (!Diff.isUsable()) 6640 return std::make_pair(nullptr, nullptr); 6641 6642 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6643 if (!Diff.isUsable()) 6644 return std::make_pair(nullptr, nullptr); 6645 6646 // Convert to the original type or ptrdiff_t, if original type is pointer. 6647 if (!VarType->isAnyPointerType() && 6648 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6649 Diff = SemaRef.PerformImplicitConversion( 6650 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6651 } else if (VarType->isAnyPointerType() && 6652 !SemaRef.Context.hasSameType( 6653 Diff.get()->getType(), 6654 SemaRef.Context.getUnsignedPointerDiffType())) { 6655 Diff = SemaRef.PerformImplicitConversion( 6656 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6657 Sema::AA_Converting, /*AllowExplicit=*/true); 6658 } 6659 if (!Diff.isUsable()) 6660 return std::make_pair(nullptr, nullptr); 6661 6662 // Parentheses (for dumping/debugging purposes only). 6663 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6664 if (!Diff.isUsable()) 6665 return std::make_pair(nullptr, nullptr); 6666 6667 if (TestIsLessOp.getValue()) { 6668 // MinExpr = Lower; 6669 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6670 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6671 if (!Diff.isUsable()) 6672 return std::make_pair(nullptr, nullptr); 6673 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6674 if (!Diff.isUsable()) 6675 return std::make_pair(nullptr, nullptr); 6676 MaxExpr = Diff.get(); 6677 } else { 6678 // MaxExpr = Upper; 6679 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6680 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6681 if (!Diff.isUsable()) 6682 return std::make_pair(nullptr, nullptr); 6683 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6684 if (!Diff.isUsable()) 6685 return std::make_pair(nullptr, nullptr); 6686 MinExpr = Diff.get(); 6687 } 6688 6689 return std::make_pair(MinExpr, MaxExpr); 6690 } 6691 6692 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6693 if (InitDependOnLC || CondDependOnLC) 6694 return Condition; 6695 return nullptr; 6696 } 6697 6698 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6699 Scope *S, Expr *Cond, 6700 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6701 // Do not build a precondition when the condition/initialization is dependent 6702 // to prevent pessimistic early loop exit. 6703 // TODO: this can be improved by calculating min/max values but not sure that 6704 // it will be very effective. 6705 if (CondDependOnLC || InitDependOnLC) 6706 return SemaRef.PerformImplicitConversion( 6707 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6708 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6709 /*AllowExplicit=*/true).get(); 6710 6711 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6712 Sema::TentativeAnalysisScope Trap(SemaRef); 6713 6714 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6715 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6716 if (!NewLB.isUsable() || !NewUB.isUsable()) 6717 return nullptr; 6718 6719 ExprResult CondExpr = 6720 SemaRef.BuildBinOp(S, DefaultLoc, 6721 TestIsLessOp.getValue() ? 6722 (TestIsStrictOp ? BO_LT : BO_LE) : 6723 (TestIsStrictOp ? BO_GT : BO_GE), 6724 NewLB.get(), NewUB.get()); 6725 if (CondExpr.isUsable()) { 6726 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6727 SemaRef.Context.BoolTy)) 6728 CondExpr = SemaRef.PerformImplicitConversion( 6729 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6730 /*AllowExplicit=*/true); 6731 } 6732 6733 // Otherwise use original loop condition and evaluate it in runtime. 6734 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6735 } 6736 6737 /// Build reference expression to the counter be used for codegen. 6738 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6739 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6740 DSAStackTy &DSA) const { 6741 auto *VD = dyn_cast<VarDecl>(LCDecl); 6742 if (!VD) { 6743 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6744 DeclRefExpr *Ref = buildDeclRefExpr( 6745 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6746 const DSAStackTy::DSAVarData Data = 6747 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6748 // If the loop control decl is explicitly marked as private, do not mark it 6749 // as captured again. 6750 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6751 Captures.insert(std::make_pair(LCRef, Ref)); 6752 return Ref; 6753 } 6754 return cast<DeclRefExpr>(LCRef); 6755 } 6756 6757 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6758 if (LCDecl && !LCDecl->isInvalidDecl()) { 6759 QualType Type = LCDecl->getType().getNonReferenceType(); 6760 VarDecl *PrivateVar = buildVarDecl( 6761 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6762 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6763 isa<VarDecl>(LCDecl) 6764 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6765 : nullptr); 6766 if (PrivateVar->isInvalidDecl()) 6767 return nullptr; 6768 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6769 } 6770 return nullptr; 6771 } 6772 6773 /// Build initialization of the counter to be used for codegen. 6774 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6775 6776 /// Build step of the counter be used for codegen. 6777 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6778 6779 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6780 Scope *S, Expr *Counter, 6781 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6782 Expr *Inc, OverloadedOperatorKind OOK) { 6783 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6784 if (!Cnt) 6785 return nullptr; 6786 if (Inc) { 6787 assert((OOK == OO_Plus || OOK == OO_Minus) && 6788 "Expected only + or - operations for depend clauses."); 6789 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6790 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6791 if (!Cnt) 6792 return nullptr; 6793 } 6794 ExprResult Diff; 6795 QualType VarType = LCDecl->getType().getNonReferenceType(); 6796 if (VarType->isIntegerType() || VarType->isPointerType() || 6797 SemaRef.getLangOpts().CPlusPlus) { 6798 // Upper - Lower 6799 Expr *Upper = TestIsLessOp.getValue() 6800 ? Cnt 6801 : tryBuildCapture(SemaRef, UB, Captures).get(); 6802 Expr *Lower = TestIsLessOp.getValue() 6803 ? tryBuildCapture(SemaRef, LB, Captures).get() 6804 : Cnt; 6805 if (!Upper || !Lower) 6806 return nullptr; 6807 6808 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6809 6810 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6811 // BuildBinOp already emitted error, this one is to point user to upper 6812 // and lower bound, and to tell what is passed to 'operator-'. 6813 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6814 << Upper->getSourceRange() << Lower->getSourceRange(); 6815 return nullptr; 6816 } 6817 } 6818 6819 if (!Diff.isUsable()) 6820 return nullptr; 6821 6822 // Parentheses (for dumping/debugging purposes only). 6823 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6824 if (!Diff.isUsable()) 6825 return nullptr; 6826 6827 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6828 if (!NewStep.isUsable()) 6829 return nullptr; 6830 // (Upper - Lower) / Step 6831 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6832 if (!Diff.isUsable()) 6833 return nullptr; 6834 6835 return Diff.get(); 6836 } 6837 } // namespace 6838 6839 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6840 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6841 assert(Init && "Expected loop in canonical form."); 6842 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6843 if (AssociatedLoops > 0 && 6844 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6845 DSAStack->loopStart(); 6846 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6847 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6848 if (ValueDecl *D = ISC.getLoopDecl()) { 6849 auto *VD = dyn_cast<VarDecl>(D); 6850 DeclRefExpr *PrivateRef = nullptr; 6851 if (!VD) { 6852 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6853 VD = Private; 6854 } else { 6855 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6856 /*WithInit=*/false); 6857 VD = cast<VarDecl>(PrivateRef->getDecl()); 6858 } 6859 } 6860 DSAStack->addLoopControlVariable(D, VD); 6861 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6862 if (LD != D->getCanonicalDecl()) { 6863 DSAStack->resetPossibleLoopCounter(); 6864 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6865 MarkDeclarationsReferencedInExpr( 6866 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6867 Var->getType().getNonLValueExprType(Context), 6868 ForLoc, /*RefersToCapture=*/true)); 6869 } 6870 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6871 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6872 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6873 // associated for-loop of a simd construct with just one associated 6874 // for-loop may be listed in a linear clause with a constant-linear-step 6875 // that is the increment of the associated for-loop. The loop iteration 6876 // variable(s) in the associated for-loop(s) of a for or parallel for 6877 // construct may be listed in a private or lastprivate clause. 6878 DSAStackTy::DSAVarData DVar = 6879 DSAStack->getTopDSA(D, /*FromParent=*/false); 6880 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6881 // is declared in the loop and it is predetermined as a private. 6882 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6883 OpenMPClauseKind PredeterminedCKind = 6884 isOpenMPSimdDirective(DKind) 6885 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6886 : OMPC_private; 6887 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6888 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6889 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6890 DVar.CKind != OMPC_private))) || 6891 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6892 DKind == OMPD_master_taskloop || 6893 DKind == OMPD_parallel_master_taskloop || 6894 isOpenMPDistributeDirective(DKind)) && 6895 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6896 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6897 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6898 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6899 << getOpenMPClauseName(DVar.CKind) 6900 << getOpenMPDirectiveName(DKind) 6901 << getOpenMPClauseName(PredeterminedCKind); 6902 if (DVar.RefExpr == nullptr) 6903 DVar.CKind = PredeterminedCKind; 6904 reportOriginalDsa(*this, DSAStack, D, DVar, 6905 /*IsLoopIterVar=*/true); 6906 } else if (LoopDeclRefExpr) { 6907 // Make the loop iteration variable private (for worksharing 6908 // constructs), linear (for simd directives with the only one 6909 // associated loop) or lastprivate (for simd directives with several 6910 // collapsed or ordered loops). 6911 if (DVar.CKind == OMPC_unknown) 6912 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6913 PrivateRef); 6914 } 6915 } 6916 } 6917 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6918 } 6919 } 6920 6921 /// Called on a for stmt to check and extract its iteration space 6922 /// for further processing (such as collapsing). 6923 static bool checkOpenMPIterationSpace( 6924 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6925 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6926 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6927 Expr *OrderedLoopCountExpr, 6928 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6929 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6930 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6931 // OpenMP [2.9.1, Canonical Loop Form] 6932 // for (init-expr; test-expr; incr-expr) structured-block 6933 // for (range-decl: range-expr) structured-block 6934 auto *For = dyn_cast_or_null<ForStmt>(S); 6935 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6936 // Ranged for is supported only in OpenMP 5.0. 6937 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6938 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6939 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6940 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6941 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6942 if (TotalNestedLoopCount > 1) { 6943 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6944 SemaRef.Diag(DSA.getConstructLoc(), 6945 diag::note_omp_collapse_ordered_expr) 6946 << 2 << CollapseLoopCountExpr->getSourceRange() 6947 << OrderedLoopCountExpr->getSourceRange(); 6948 else if (CollapseLoopCountExpr) 6949 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6950 diag::note_omp_collapse_ordered_expr) 6951 << 0 << CollapseLoopCountExpr->getSourceRange(); 6952 else 6953 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6954 diag::note_omp_collapse_ordered_expr) 6955 << 1 << OrderedLoopCountExpr->getSourceRange(); 6956 } 6957 return true; 6958 } 6959 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6960 "No loop body."); 6961 6962 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6963 For ? For->getForLoc() : CXXFor->getForLoc()); 6964 6965 // Check init. 6966 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6967 if (ISC.checkAndSetInit(Init)) 6968 return true; 6969 6970 bool HasErrors = false; 6971 6972 // Check loop variable's type. 6973 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6974 // OpenMP [2.6, Canonical Loop Form] 6975 // Var is one of the following: 6976 // A variable of signed or unsigned integer type. 6977 // For C++, a variable of a random access iterator type. 6978 // For C, a variable of a pointer type. 6979 QualType VarType = LCDecl->getType().getNonReferenceType(); 6980 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6981 !VarType->isPointerType() && 6982 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6983 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6984 << SemaRef.getLangOpts().CPlusPlus; 6985 HasErrors = true; 6986 } 6987 6988 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6989 // a Construct 6990 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6991 // parallel for construct is (are) private. 6992 // The loop iteration variable in the associated for-loop of a simd 6993 // construct with just one associated for-loop is linear with a 6994 // constant-linear-step that is the increment of the associated for-loop. 6995 // Exclude loop var from the list of variables with implicitly defined data 6996 // sharing attributes. 6997 VarsWithImplicitDSA.erase(LCDecl); 6998 6999 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7000 7001 // Check test-expr. 7002 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7003 7004 // Check incr-expr. 7005 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7006 } 7007 7008 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7009 return HasErrors; 7010 7011 // Build the loop's iteration space representation. 7012 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7013 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7014 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7015 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7016 (isOpenMPWorksharingDirective(DKind) || 7017 isOpenMPTaskLoopDirective(DKind) || 7018 isOpenMPDistributeDirective(DKind)), 7019 Captures); 7020 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7021 ISC.buildCounterVar(Captures, DSA); 7022 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7023 ISC.buildPrivateCounterVar(); 7024 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7025 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7026 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7027 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7028 ISC.getConditionSrcRange(); 7029 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7030 ISC.getIncrementSrcRange(); 7031 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7032 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7033 ISC.isStrictTestOp(); 7034 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7035 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7036 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7037 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7038 ISC.buildFinalCondition(DSA.getCurScope()); 7039 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7040 ISC.doesInitDependOnLC(); 7041 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7042 ISC.doesCondDependOnLC(); 7043 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7044 ISC.getLoopDependentIdx(); 7045 7046 HasErrors |= 7047 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7048 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7049 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7050 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7051 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7052 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7053 if (!HasErrors && DSA.isOrderedRegion()) { 7054 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7055 if (CurrentNestedLoopCount < 7056 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7057 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7058 CurrentNestedLoopCount, 7059 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7060 DSA.getOrderedRegionParam().second->setLoopCounter( 7061 CurrentNestedLoopCount, 7062 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7063 } 7064 } 7065 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7066 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7067 // Erroneous case - clause has some problems. 7068 continue; 7069 } 7070 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7071 Pair.second.size() <= CurrentNestedLoopCount) { 7072 // Erroneous case - clause has some problems. 7073 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7074 continue; 7075 } 7076 Expr *CntValue; 7077 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7078 CntValue = ISC.buildOrderedLoopData( 7079 DSA.getCurScope(), 7080 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7081 Pair.first->getDependencyLoc()); 7082 else 7083 CntValue = ISC.buildOrderedLoopData( 7084 DSA.getCurScope(), 7085 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7086 Pair.first->getDependencyLoc(), 7087 Pair.second[CurrentNestedLoopCount].first, 7088 Pair.second[CurrentNestedLoopCount].second); 7089 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7090 } 7091 } 7092 7093 return HasErrors; 7094 } 7095 7096 /// Build 'VarRef = Start. 7097 static ExprResult 7098 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7099 ExprResult Start, bool IsNonRectangularLB, 7100 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7101 // Build 'VarRef = Start. 7102 ExprResult NewStart = IsNonRectangularLB 7103 ? Start.get() 7104 : tryBuildCapture(SemaRef, Start.get(), Captures); 7105 if (!NewStart.isUsable()) 7106 return ExprError(); 7107 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7108 VarRef.get()->getType())) { 7109 NewStart = SemaRef.PerformImplicitConversion( 7110 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7111 /*AllowExplicit=*/true); 7112 if (!NewStart.isUsable()) 7113 return ExprError(); 7114 } 7115 7116 ExprResult Init = 7117 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7118 return Init; 7119 } 7120 7121 /// Build 'VarRef = Start + Iter * Step'. 7122 static ExprResult buildCounterUpdate( 7123 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7124 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7125 bool IsNonRectangularLB, 7126 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7127 // Add parentheses (for debugging purposes only). 7128 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7129 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7130 !Step.isUsable()) 7131 return ExprError(); 7132 7133 ExprResult NewStep = Step; 7134 if (Captures) 7135 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7136 if (NewStep.isInvalid()) 7137 return ExprError(); 7138 ExprResult Update = 7139 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7140 if (!Update.isUsable()) 7141 return ExprError(); 7142 7143 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7144 // 'VarRef = Start (+|-) Iter * Step'. 7145 if (!Start.isUsable()) 7146 return ExprError(); 7147 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7148 if (!NewStart.isUsable()) 7149 return ExprError(); 7150 if (Captures && !IsNonRectangularLB) 7151 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7152 if (NewStart.isInvalid()) 7153 return ExprError(); 7154 7155 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7156 ExprResult SavedUpdate = Update; 7157 ExprResult UpdateVal; 7158 if (VarRef.get()->getType()->isOverloadableType() || 7159 NewStart.get()->getType()->isOverloadableType() || 7160 Update.get()->getType()->isOverloadableType()) { 7161 Sema::TentativeAnalysisScope Trap(SemaRef); 7162 7163 Update = 7164 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7165 if (Update.isUsable()) { 7166 UpdateVal = 7167 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7168 VarRef.get(), SavedUpdate.get()); 7169 if (UpdateVal.isUsable()) { 7170 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7171 UpdateVal.get()); 7172 } 7173 } 7174 } 7175 7176 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7177 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7178 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7179 NewStart.get(), SavedUpdate.get()); 7180 if (!Update.isUsable()) 7181 return ExprError(); 7182 7183 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7184 VarRef.get()->getType())) { 7185 Update = SemaRef.PerformImplicitConversion( 7186 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7187 if (!Update.isUsable()) 7188 return ExprError(); 7189 } 7190 7191 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7192 } 7193 return Update; 7194 } 7195 7196 /// Convert integer expression \a E to make it have at least \a Bits 7197 /// bits. 7198 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7199 if (E == nullptr) 7200 return ExprError(); 7201 ASTContext &C = SemaRef.Context; 7202 QualType OldType = E->getType(); 7203 unsigned HasBits = C.getTypeSize(OldType); 7204 if (HasBits >= Bits) 7205 return ExprResult(E); 7206 // OK to convert to signed, because new type has more bits than old. 7207 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7208 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7209 true); 7210 } 7211 7212 /// Check if the given expression \a E is a constant integer that fits 7213 /// into \a Bits bits. 7214 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7215 if (E == nullptr) 7216 return false; 7217 llvm::APSInt Result; 7218 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7219 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7220 return false; 7221 } 7222 7223 /// Build preinits statement for the given declarations. 7224 static Stmt *buildPreInits(ASTContext &Context, 7225 MutableArrayRef<Decl *> PreInits) { 7226 if (!PreInits.empty()) { 7227 return new (Context) DeclStmt( 7228 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7229 SourceLocation(), SourceLocation()); 7230 } 7231 return nullptr; 7232 } 7233 7234 /// Build preinits statement for the given declarations. 7235 static Stmt * 7236 buildPreInits(ASTContext &Context, 7237 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7238 if (!Captures.empty()) { 7239 SmallVector<Decl *, 16> PreInits; 7240 for (const auto &Pair : Captures) 7241 PreInits.push_back(Pair.second->getDecl()); 7242 return buildPreInits(Context, PreInits); 7243 } 7244 return nullptr; 7245 } 7246 7247 /// Build postupdate expression for the given list of postupdates expressions. 7248 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7249 Expr *PostUpdate = nullptr; 7250 if (!PostUpdates.empty()) { 7251 for (Expr *E : PostUpdates) { 7252 Expr *ConvE = S.BuildCStyleCastExpr( 7253 E->getExprLoc(), 7254 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7255 E->getExprLoc(), E) 7256 .get(); 7257 PostUpdate = PostUpdate 7258 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7259 PostUpdate, ConvE) 7260 .get() 7261 : ConvE; 7262 } 7263 } 7264 return PostUpdate; 7265 } 7266 7267 /// Called on a for stmt to check itself and nested loops (if any). 7268 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7269 /// number of collapsed loops otherwise. 7270 static unsigned 7271 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7272 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7273 DSAStackTy &DSA, 7274 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7275 OMPLoopDirective::HelperExprs &Built) { 7276 unsigned NestedLoopCount = 1; 7277 if (CollapseLoopCountExpr) { 7278 // Found 'collapse' clause - calculate collapse number. 7279 Expr::EvalResult Result; 7280 if (!CollapseLoopCountExpr->isValueDependent() && 7281 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7282 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7283 } else { 7284 Built.clear(/*Size=*/1); 7285 return 1; 7286 } 7287 } 7288 unsigned OrderedLoopCount = 1; 7289 if (OrderedLoopCountExpr) { 7290 // Found 'ordered' clause - calculate collapse number. 7291 Expr::EvalResult EVResult; 7292 if (!OrderedLoopCountExpr->isValueDependent() && 7293 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7294 SemaRef.getASTContext())) { 7295 llvm::APSInt Result = EVResult.Val.getInt(); 7296 if (Result.getLimitedValue() < NestedLoopCount) { 7297 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7298 diag::err_omp_wrong_ordered_loop_count) 7299 << OrderedLoopCountExpr->getSourceRange(); 7300 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7301 diag::note_collapse_loop_count) 7302 << CollapseLoopCountExpr->getSourceRange(); 7303 } 7304 OrderedLoopCount = Result.getLimitedValue(); 7305 } else { 7306 Built.clear(/*Size=*/1); 7307 return 1; 7308 } 7309 } 7310 // This is helper routine for loop directives (e.g., 'for', 'simd', 7311 // 'for simd', etc.). 7312 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7313 SmallVector<LoopIterationSpace, 4> IterSpaces( 7314 std::max(OrderedLoopCount, NestedLoopCount)); 7315 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7316 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7317 if (checkOpenMPIterationSpace( 7318 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7319 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7320 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7321 return 0; 7322 // Move on to the next nested for loop, or to the loop body. 7323 // OpenMP [2.8.1, simd construct, Restrictions] 7324 // All loops associated with the construct must be perfectly nested; that 7325 // is, there must be no intervening code nor any OpenMP directive between 7326 // any two loops. 7327 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7328 CurStmt = For->getBody(); 7329 } else { 7330 assert(isa<CXXForRangeStmt>(CurStmt) && 7331 "Expected canonical for or range-based for loops."); 7332 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7333 } 7334 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7335 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7336 } 7337 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7338 if (checkOpenMPIterationSpace( 7339 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7340 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7341 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7342 return 0; 7343 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7344 // Handle initialization of captured loop iterator variables. 7345 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7346 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7347 Captures[DRE] = DRE; 7348 } 7349 } 7350 // Move on to the next nested for loop, or to the loop body. 7351 // OpenMP [2.8.1, simd construct, Restrictions] 7352 // All loops associated with the construct must be perfectly nested; that 7353 // is, there must be no intervening code nor any OpenMP directive between 7354 // any two loops. 7355 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7356 CurStmt = For->getBody(); 7357 } else { 7358 assert(isa<CXXForRangeStmt>(CurStmt) && 7359 "Expected canonical for or range-based for loops."); 7360 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7361 } 7362 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7363 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7364 } 7365 7366 Built.clear(/* size */ NestedLoopCount); 7367 7368 if (SemaRef.CurContext->isDependentContext()) 7369 return NestedLoopCount; 7370 7371 // An example of what is generated for the following code: 7372 // 7373 // #pragma omp simd collapse(2) ordered(2) 7374 // for (i = 0; i < NI; ++i) 7375 // for (k = 0; k < NK; ++k) 7376 // for (j = J0; j < NJ; j+=2) { 7377 // <loop body> 7378 // } 7379 // 7380 // We generate the code below. 7381 // Note: the loop body may be outlined in CodeGen. 7382 // Note: some counters may be C++ classes, operator- is used to find number of 7383 // iterations and operator+= to calculate counter value. 7384 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7385 // or i64 is currently supported). 7386 // 7387 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7388 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7389 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7390 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7391 // // similar updates for vars in clauses (e.g. 'linear') 7392 // <loop body (using local i and j)> 7393 // } 7394 // i = NI; // assign final values of counters 7395 // j = NJ; 7396 // 7397 7398 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7399 // the iteration counts of the collapsed for loops. 7400 // Precondition tests if there is at least one iteration (all conditions are 7401 // true). 7402 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7403 Expr *N0 = IterSpaces[0].NumIterations; 7404 ExprResult LastIteration32 = 7405 widenIterationCount(/*Bits=*/32, 7406 SemaRef 7407 .PerformImplicitConversion( 7408 N0->IgnoreImpCasts(), N0->getType(), 7409 Sema::AA_Converting, /*AllowExplicit=*/true) 7410 .get(), 7411 SemaRef); 7412 ExprResult LastIteration64 = widenIterationCount( 7413 /*Bits=*/64, 7414 SemaRef 7415 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7416 Sema::AA_Converting, 7417 /*AllowExplicit=*/true) 7418 .get(), 7419 SemaRef); 7420 7421 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7422 return NestedLoopCount; 7423 7424 ASTContext &C = SemaRef.Context; 7425 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7426 7427 Scope *CurScope = DSA.getCurScope(); 7428 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7429 if (PreCond.isUsable()) { 7430 PreCond = 7431 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7432 PreCond.get(), IterSpaces[Cnt].PreCond); 7433 } 7434 Expr *N = IterSpaces[Cnt].NumIterations; 7435 SourceLocation Loc = N->getExprLoc(); 7436 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7437 if (LastIteration32.isUsable()) 7438 LastIteration32 = SemaRef.BuildBinOp( 7439 CurScope, Loc, BO_Mul, LastIteration32.get(), 7440 SemaRef 7441 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7442 Sema::AA_Converting, 7443 /*AllowExplicit=*/true) 7444 .get()); 7445 if (LastIteration64.isUsable()) 7446 LastIteration64 = SemaRef.BuildBinOp( 7447 CurScope, Loc, BO_Mul, LastIteration64.get(), 7448 SemaRef 7449 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7450 Sema::AA_Converting, 7451 /*AllowExplicit=*/true) 7452 .get()); 7453 } 7454 7455 // Choose either the 32-bit or 64-bit version. 7456 ExprResult LastIteration = LastIteration64; 7457 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7458 (LastIteration32.isUsable() && 7459 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7460 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7461 fitsInto( 7462 /*Bits=*/32, 7463 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7464 LastIteration64.get(), SemaRef)))) 7465 LastIteration = LastIteration32; 7466 QualType VType = LastIteration.get()->getType(); 7467 QualType RealVType = VType; 7468 QualType StrideVType = VType; 7469 if (isOpenMPTaskLoopDirective(DKind)) { 7470 VType = 7471 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7472 StrideVType = 7473 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7474 } 7475 7476 if (!LastIteration.isUsable()) 7477 return 0; 7478 7479 // Save the number of iterations. 7480 ExprResult NumIterations = LastIteration; 7481 { 7482 LastIteration = SemaRef.BuildBinOp( 7483 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7484 LastIteration.get(), 7485 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7486 if (!LastIteration.isUsable()) 7487 return 0; 7488 } 7489 7490 // Calculate the last iteration number beforehand instead of doing this on 7491 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7492 llvm::APSInt Result; 7493 bool IsConstant = 7494 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7495 ExprResult CalcLastIteration; 7496 if (!IsConstant) { 7497 ExprResult SaveRef = 7498 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7499 LastIteration = SaveRef; 7500 7501 // Prepare SaveRef + 1. 7502 NumIterations = SemaRef.BuildBinOp( 7503 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7504 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7505 if (!NumIterations.isUsable()) 7506 return 0; 7507 } 7508 7509 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7510 7511 // Build variables passed into runtime, necessary for worksharing directives. 7512 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7513 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7514 isOpenMPDistributeDirective(DKind)) { 7515 // Lower bound variable, initialized with zero. 7516 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7517 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7518 SemaRef.AddInitializerToDecl(LBDecl, 7519 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7520 /*DirectInit*/ false); 7521 7522 // Upper bound variable, initialized with last iteration number. 7523 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7524 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7525 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7526 /*DirectInit*/ false); 7527 7528 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7529 // This will be used to implement clause 'lastprivate'. 7530 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7531 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7532 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7533 SemaRef.AddInitializerToDecl(ILDecl, 7534 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7535 /*DirectInit*/ false); 7536 7537 // Stride variable returned by runtime (we initialize it to 1 by default). 7538 VarDecl *STDecl = 7539 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7540 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7541 SemaRef.AddInitializerToDecl(STDecl, 7542 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7543 /*DirectInit*/ false); 7544 7545 // Build expression: UB = min(UB, LastIteration) 7546 // It is necessary for CodeGen of directives with static scheduling. 7547 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7548 UB.get(), LastIteration.get()); 7549 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7550 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7551 LastIteration.get(), UB.get()); 7552 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7553 CondOp.get()); 7554 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7555 7556 // If we have a combined directive that combines 'distribute', 'for' or 7557 // 'simd' we need to be able to access the bounds of the schedule of the 7558 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7559 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7560 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7561 // Lower bound variable, initialized with zero. 7562 VarDecl *CombLBDecl = 7563 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7564 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7565 SemaRef.AddInitializerToDecl( 7566 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7567 /*DirectInit*/ false); 7568 7569 // Upper bound variable, initialized with last iteration number. 7570 VarDecl *CombUBDecl = 7571 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7572 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7573 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7574 /*DirectInit*/ false); 7575 7576 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7577 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7578 ExprResult CombCondOp = 7579 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7580 LastIteration.get(), CombUB.get()); 7581 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7582 CombCondOp.get()); 7583 CombEUB = 7584 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7585 7586 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7587 // We expect to have at least 2 more parameters than the 'parallel' 7588 // directive does - the lower and upper bounds of the previous schedule. 7589 assert(CD->getNumParams() >= 4 && 7590 "Unexpected number of parameters in loop combined directive"); 7591 7592 // Set the proper type for the bounds given what we learned from the 7593 // enclosed loops. 7594 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7595 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7596 7597 // Previous lower and upper bounds are obtained from the region 7598 // parameters. 7599 PrevLB = 7600 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7601 PrevUB = 7602 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7603 } 7604 } 7605 7606 // Build the iteration variable and its initialization before loop. 7607 ExprResult IV; 7608 ExprResult Init, CombInit; 7609 { 7610 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7611 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7612 Expr *RHS = 7613 (isOpenMPWorksharingDirective(DKind) || 7614 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7615 ? LB.get() 7616 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7617 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7618 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7619 7620 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7621 Expr *CombRHS = 7622 (isOpenMPWorksharingDirective(DKind) || 7623 isOpenMPTaskLoopDirective(DKind) || 7624 isOpenMPDistributeDirective(DKind)) 7625 ? CombLB.get() 7626 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7627 CombInit = 7628 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7629 CombInit = 7630 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7631 } 7632 } 7633 7634 bool UseStrictCompare = 7635 RealVType->hasUnsignedIntegerRepresentation() && 7636 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7637 return LIS.IsStrictCompare; 7638 }); 7639 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7640 // unsigned IV)) for worksharing loops. 7641 SourceLocation CondLoc = AStmt->getBeginLoc(); 7642 Expr *BoundUB = UB.get(); 7643 if (UseStrictCompare) { 7644 BoundUB = 7645 SemaRef 7646 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7647 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7648 .get(); 7649 BoundUB = 7650 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7651 } 7652 ExprResult Cond = 7653 (isOpenMPWorksharingDirective(DKind) || 7654 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7655 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7656 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7657 BoundUB) 7658 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7659 NumIterations.get()); 7660 ExprResult CombDistCond; 7661 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7662 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7663 NumIterations.get()); 7664 } 7665 7666 ExprResult CombCond; 7667 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7668 Expr *BoundCombUB = CombUB.get(); 7669 if (UseStrictCompare) { 7670 BoundCombUB = 7671 SemaRef 7672 .BuildBinOp( 7673 CurScope, CondLoc, BO_Add, BoundCombUB, 7674 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7675 .get(); 7676 BoundCombUB = 7677 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7678 .get(); 7679 } 7680 CombCond = 7681 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7682 IV.get(), BoundCombUB); 7683 } 7684 // Loop increment (IV = IV + 1) 7685 SourceLocation IncLoc = AStmt->getBeginLoc(); 7686 ExprResult Inc = 7687 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7688 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7689 if (!Inc.isUsable()) 7690 return 0; 7691 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7692 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7693 if (!Inc.isUsable()) 7694 return 0; 7695 7696 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7697 // Used for directives with static scheduling. 7698 // In combined construct, add combined version that use CombLB and CombUB 7699 // base variables for the update 7700 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7701 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7702 isOpenMPDistributeDirective(DKind)) { 7703 // LB + ST 7704 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7705 if (!NextLB.isUsable()) 7706 return 0; 7707 // LB = LB + ST 7708 NextLB = 7709 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7710 NextLB = 7711 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7712 if (!NextLB.isUsable()) 7713 return 0; 7714 // UB + ST 7715 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7716 if (!NextUB.isUsable()) 7717 return 0; 7718 // UB = UB + ST 7719 NextUB = 7720 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7721 NextUB = 7722 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7723 if (!NextUB.isUsable()) 7724 return 0; 7725 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7726 CombNextLB = 7727 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7728 if (!NextLB.isUsable()) 7729 return 0; 7730 // LB = LB + ST 7731 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7732 CombNextLB.get()); 7733 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7734 /*DiscardedValue*/ false); 7735 if (!CombNextLB.isUsable()) 7736 return 0; 7737 // UB + ST 7738 CombNextUB = 7739 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7740 if (!CombNextUB.isUsable()) 7741 return 0; 7742 // UB = UB + ST 7743 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7744 CombNextUB.get()); 7745 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7746 /*DiscardedValue*/ false); 7747 if (!CombNextUB.isUsable()) 7748 return 0; 7749 } 7750 } 7751 7752 // Create increment expression for distribute loop when combined in a same 7753 // directive with for as IV = IV + ST; ensure upper bound expression based 7754 // on PrevUB instead of NumIterations - used to implement 'for' when found 7755 // in combination with 'distribute', like in 'distribute parallel for' 7756 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7757 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7758 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7759 DistCond = SemaRef.BuildBinOp( 7760 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7761 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7762 7763 DistInc = 7764 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7765 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7766 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7767 DistInc.get()); 7768 DistInc = 7769 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7770 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7771 7772 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7773 // construct 7774 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7775 ExprResult IsUBGreater = 7776 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7777 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7778 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7779 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7780 CondOp.get()); 7781 PrevEUB = 7782 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7783 7784 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7785 // parallel for is in combination with a distribute directive with 7786 // schedule(static, 1) 7787 Expr *BoundPrevUB = PrevUB.get(); 7788 if (UseStrictCompare) { 7789 BoundPrevUB = 7790 SemaRef 7791 .BuildBinOp( 7792 CurScope, CondLoc, BO_Add, BoundPrevUB, 7793 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7794 .get(); 7795 BoundPrevUB = 7796 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7797 .get(); 7798 } 7799 ParForInDistCond = 7800 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7801 IV.get(), BoundPrevUB); 7802 } 7803 7804 // Build updates and final values of the loop counters. 7805 bool HasErrors = false; 7806 Built.Counters.resize(NestedLoopCount); 7807 Built.Inits.resize(NestedLoopCount); 7808 Built.Updates.resize(NestedLoopCount); 7809 Built.Finals.resize(NestedLoopCount); 7810 Built.DependentCounters.resize(NestedLoopCount); 7811 Built.DependentInits.resize(NestedLoopCount); 7812 Built.FinalsConditions.resize(NestedLoopCount); 7813 { 7814 // We implement the following algorithm for obtaining the 7815 // original loop iteration variable values based on the 7816 // value of the collapsed loop iteration variable IV. 7817 // 7818 // Let n+1 be the number of collapsed loops in the nest. 7819 // Iteration variables (I0, I1, .... In) 7820 // Iteration counts (N0, N1, ... Nn) 7821 // 7822 // Acc = IV; 7823 // 7824 // To compute Ik for loop k, 0 <= k <= n, generate: 7825 // Prod = N(k+1) * N(k+2) * ... * Nn; 7826 // Ik = Acc / Prod; 7827 // Acc -= Ik * Prod; 7828 // 7829 ExprResult Acc = IV; 7830 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7831 LoopIterationSpace &IS = IterSpaces[Cnt]; 7832 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7833 ExprResult Iter; 7834 7835 // Compute prod 7836 ExprResult Prod = 7837 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7838 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7839 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7840 IterSpaces[K].NumIterations); 7841 7842 // Iter = Acc / Prod 7843 // If there is at least one more inner loop to avoid 7844 // multiplication by 1. 7845 if (Cnt + 1 < NestedLoopCount) 7846 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7847 Acc.get(), Prod.get()); 7848 else 7849 Iter = Acc; 7850 if (!Iter.isUsable()) { 7851 HasErrors = true; 7852 break; 7853 } 7854 7855 // Update Acc: 7856 // Acc -= Iter * Prod 7857 // Check if there is at least one more inner loop to avoid 7858 // multiplication by 1. 7859 if (Cnt + 1 < NestedLoopCount) 7860 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7861 Iter.get(), Prod.get()); 7862 else 7863 Prod = Iter; 7864 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7865 Acc.get(), Prod.get()); 7866 7867 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7868 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7869 DeclRefExpr *CounterVar = buildDeclRefExpr( 7870 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7871 /*RefersToCapture=*/true); 7872 ExprResult Init = 7873 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7874 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7875 if (!Init.isUsable()) { 7876 HasErrors = true; 7877 break; 7878 } 7879 ExprResult Update = buildCounterUpdate( 7880 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7881 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7882 if (!Update.isUsable()) { 7883 HasErrors = true; 7884 break; 7885 } 7886 7887 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7888 ExprResult Final = 7889 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7890 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7891 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7892 if (!Final.isUsable()) { 7893 HasErrors = true; 7894 break; 7895 } 7896 7897 if (!Update.isUsable() || !Final.isUsable()) { 7898 HasErrors = true; 7899 break; 7900 } 7901 // Save results 7902 Built.Counters[Cnt] = IS.CounterVar; 7903 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7904 Built.Inits[Cnt] = Init.get(); 7905 Built.Updates[Cnt] = Update.get(); 7906 Built.Finals[Cnt] = Final.get(); 7907 Built.DependentCounters[Cnt] = nullptr; 7908 Built.DependentInits[Cnt] = nullptr; 7909 Built.FinalsConditions[Cnt] = nullptr; 7910 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7911 Built.DependentCounters[Cnt] = 7912 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7913 Built.DependentInits[Cnt] = 7914 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7915 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7916 } 7917 } 7918 } 7919 7920 if (HasErrors) 7921 return 0; 7922 7923 // Save results 7924 Built.IterationVarRef = IV.get(); 7925 Built.LastIteration = LastIteration.get(); 7926 Built.NumIterations = NumIterations.get(); 7927 Built.CalcLastIteration = SemaRef 7928 .ActOnFinishFullExpr(CalcLastIteration.get(), 7929 /*DiscardedValue=*/false) 7930 .get(); 7931 Built.PreCond = PreCond.get(); 7932 Built.PreInits = buildPreInits(C, Captures); 7933 Built.Cond = Cond.get(); 7934 Built.Init = Init.get(); 7935 Built.Inc = Inc.get(); 7936 Built.LB = LB.get(); 7937 Built.UB = UB.get(); 7938 Built.IL = IL.get(); 7939 Built.ST = ST.get(); 7940 Built.EUB = EUB.get(); 7941 Built.NLB = NextLB.get(); 7942 Built.NUB = NextUB.get(); 7943 Built.PrevLB = PrevLB.get(); 7944 Built.PrevUB = PrevUB.get(); 7945 Built.DistInc = DistInc.get(); 7946 Built.PrevEUB = PrevEUB.get(); 7947 Built.DistCombinedFields.LB = CombLB.get(); 7948 Built.DistCombinedFields.UB = CombUB.get(); 7949 Built.DistCombinedFields.EUB = CombEUB.get(); 7950 Built.DistCombinedFields.Init = CombInit.get(); 7951 Built.DistCombinedFields.Cond = CombCond.get(); 7952 Built.DistCombinedFields.NLB = CombNextLB.get(); 7953 Built.DistCombinedFields.NUB = CombNextUB.get(); 7954 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7955 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7956 7957 return NestedLoopCount; 7958 } 7959 7960 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7961 auto CollapseClauses = 7962 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7963 if (CollapseClauses.begin() != CollapseClauses.end()) 7964 return (*CollapseClauses.begin())->getNumForLoops(); 7965 return nullptr; 7966 } 7967 7968 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7969 auto OrderedClauses = 7970 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7971 if (OrderedClauses.begin() != OrderedClauses.end()) 7972 return (*OrderedClauses.begin())->getNumForLoops(); 7973 return nullptr; 7974 } 7975 7976 static bool checkSimdlenSafelenSpecified(Sema &S, 7977 const ArrayRef<OMPClause *> Clauses) { 7978 const OMPSafelenClause *Safelen = nullptr; 7979 const OMPSimdlenClause *Simdlen = nullptr; 7980 7981 for (const OMPClause *Clause : Clauses) { 7982 if (Clause->getClauseKind() == OMPC_safelen) 7983 Safelen = cast<OMPSafelenClause>(Clause); 7984 else if (Clause->getClauseKind() == OMPC_simdlen) 7985 Simdlen = cast<OMPSimdlenClause>(Clause); 7986 if (Safelen && Simdlen) 7987 break; 7988 } 7989 7990 if (Simdlen && Safelen) { 7991 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7992 const Expr *SafelenLength = Safelen->getSafelen(); 7993 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7994 SimdlenLength->isInstantiationDependent() || 7995 SimdlenLength->containsUnexpandedParameterPack()) 7996 return false; 7997 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7998 SafelenLength->isInstantiationDependent() || 7999 SafelenLength->containsUnexpandedParameterPack()) 8000 return false; 8001 Expr::EvalResult SimdlenResult, SafelenResult; 8002 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8003 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8004 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8005 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8006 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8007 // If both simdlen and safelen clauses are specified, the value of the 8008 // simdlen parameter must be less than or equal to the value of the safelen 8009 // parameter. 8010 if (SimdlenRes > SafelenRes) { 8011 S.Diag(SimdlenLength->getExprLoc(), 8012 diag::err_omp_wrong_simdlen_safelen_values) 8013 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8014 return true; 8015 } 8016 } 8017 return false; 8018 } 8019 8020 StmtResult 8021 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8022 SourceLocation StartLoc, SourceLocation EndLoc, 8023 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8024 if (!AStmt) 8025 return StmtError(); 8026 8027 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8028 OMPLoopDirective::HelperExprs B; 8029 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8030 // define the nested loops number. 8031 unsigned NestedLoopCount = checkOpenMPLoop( 8032 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8033 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8034 if (NestedLoopCount == 0) 8035 return StmtError(); 8036 8037 assert((CurContext->isDependentContext() || B.builtAll()) && 8038 "omp simd loop exprs were not built"); 8039 8040 if (!CurContext->isDependentContext()) { 8041 // Finalize the clauses that need pre-built expressions for CodeGen. 8042 for (OMPClause *C : Clauses) { 8043 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8044 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8045 B.NumIterations, *this, CurScope, 8046 DSAStack)) 8047 return StmtError(); 8048 } 8049 } 8050 8051 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8052 return StmtError(); 8053 8054 setFunctionHasBranchProtectedScope(); 8055 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8056 Clauses, AStmt, B); 8057 } 8058 8059 StmtResult 8060 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8061 SourceLocation StartLoc, SourceLocation EndLoc, 8062 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8063 if (!AStmt) 8064 return StmtError(); 8065 8066 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8067 OMPLoopDirective::HelperExprs B; 8068 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8069 // define the nested loops number. 8070 unsigned NestedLoopCount = checkOpenMPLoop( 8071 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8072 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8073 if (NestedLoopCount == 0) 8074 return StmtError(); 8075 8076 assert((CurContext->isDependentContext() || B.builtAll()) && 8077 "omp for loop exprs were not built"); 8078 8079 if (!CurContext->isDependentContext()) { 8080 // Finalize the clauses that need pre-built expressions for CodeGen. 8081 for (OMPClause *C : Clauses) { 8082 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8083 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8084 B.NumIterations, *this, CurScope, 8085 DSAStack)) 8086 return StmtError(); 8087 } 8088 } 8089 8090 setFunctionHasBranchProtectedScope(); 8091 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8092 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8093 } 8094 8095 StmtResult Sema::ActOnOpenMPForSimdDirective( 8096 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8097 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8098 if (!AStmt) 8099 return StmtError(); 8100 8101 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8102 OMPLoopDirective::HelperExprs B; 8103 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8104 // define the nested loops number. 8105 unsigned NestedLoopCount = 8106 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8107 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8108 VarsWithImplicitDSA, B); 8109 if (NestedLoopCount == 0) 8110 return StmtError(); 8111 8112 assert((CurContext->isDependentContext() || B.builtAll()) && 8113 "omp for simd loop exprs were not built"); 8114 8115 if (!CurContext->isDependentContext()) { 8116 // Finalize the clauses that need pre-built expressions for CodeGen. 8117 for (OMPClause *C : Clauses) { 8118 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8119 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8120 B.NumIterations, *this, CurScope, 8121 DSAStack)) 8122 return StmtError(); 8123 } 8124 } 8125 8126 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8127 return StmtError(); 8128 8129 setFunctionHasBranchProtectedScope(); 8130 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8131 Clauses, AStmt, B); 8132 } 8133 8134 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8135 Stmt *AStmt, 8136 SourceLocation StartLoc, 8137 SourceLocation EndLoc) { 8138 if (!AStmt) 8139 return StmtError(); 8140 8141 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8142 auto BaseStmt = AStmt; 8143 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8144 BaseStmt = CS->getCapturedStmt(); 8145 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8146 auto S = C->children(); 8147 if (S.begin() == S.end()) 8148 return StmtError(); 8149 // All associated statements must be '#pragma omp section' except for 8150 // the first one. 8151 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8152 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8153 if (SectionStmt) 8154 Diag(SectionStmt->getBeginLoc(), 8155 diag::err_omp_sections_substmt_not_section); 8156 return StmtError(); 8157 } 8158 cast<OMPSectionDirective>(SectionStmt) 8159 ->setHasCancel(DSAStack->isCancelRegion()); 8160 } 8161 } else { 8162 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8163 return StmtError(); 8164 } 8165 8166 setFunctionHasBranchProtectedScope(); 8167 8168 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8169 DSAStack->isCancelRegion()); 8170 } 8171 8172 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8173 SourceLocation StartLoc, 8174 SourceLocation EndLoc) { 8175 if (!AStmt) 8176 return StmtError(); 8177 8178 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8179 8180 setFunctionHasBranchProtectedScope(); 8181 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8182 8183 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8184 DSAStack->isCancelRegion()); 8185 } 8186 8187 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8188 Stmt *AStmt, 8189 SourceLocation StartLoc, 8190 SourceLocation EndLoc) { 8191 if (!AStmt) 8192 return StmtError(); 8193 8194 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8195 8196 setFunctionHasBranchProtectedScope(); 8197 8198 // OpenMP [2.7.3, single Construct, Restrictions] 8199 // The copyprivate clause must not be used with the nowait clause. 8200 const OMPClause *Nowait = nullptr; 8201 const OMPClause *Copyprivate = nullptr; 8202 for (const OMPClause *Clause : Clauses) { 8203 if (Clause->getClauseKind() == OMPC_nowait) 8204 Nowait = Clause; 8205 else if (Clause->getClauseKind() == OMPC_copyprivate) 8206 Copyprivate = Clause; 8207 if (Copyprivate && Nowait) { 8208 Diag(Copyprivate->getBeginLoc(), 8209 diag::err_omp_single_copyprivate_with_nowait); 8210 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8211 return StmtError(); 8212 } 8213 } 8214 8215 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8216 } 8217 8218 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8219 SourceLocation StartLoc, 8220 SourceLocation EndLoc) { 8221 if (!AStmt) 8222 return StmtError(); 8223 8224 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8225 8226 setFunctionHasBranchProtectedScope(); 8227 8228 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8229 } 8230 8231 StmtResult Sema::ActOnOpenMPCriticalDirective( 8232 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8233 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8234 if (!AStmt) 8235 return StmtError(); 8236 8237 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8238 8239 bool ErrorFound = false; 8240 llvm::APSInt Hint; 8241 SourceLocation HintLoc; 8242 bool DependentHint = false; 8243 for (const OMPClause *C : Clauses) { 8244 if (C->getClauseKind() == OMPC_hint) { 8245 if (!DirName.getName()) { 8246 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8247 ErrorFound = true; 8248 } 8249 Expr *E = cast<OMPHintClause>(C)->getHint(); 8250 if (E->isTypeDependent() || E->isValueDependent() || 8251 E->isInstantiationDependent()) { 8252 DependentHint = true; 8253 } else { 8254 Hint = E->EvaluateKnownConstInt(Context); 8255 HintLoc = C->getBeginLoc(); 8256 } 8257 } 8258 } 8259 if (ErrorFound) 8260 return StmtError(); 8261 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8262 if (Pair.first && DirName.getName() && !DependentHint) { 8263 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8264 Diag(StartLoc, diag::err_omp_critical_with_hint); 8265 if (HintLoc.isValid()) 8266 Diag(HintLoc, diag::note_omp_critical_hint_here) 8267 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8268 else 8269 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8270 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8271 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8272 << 1 8273 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8274 /*Radix=*/10, /*Signed=*/false); 8275 } else { 8276 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8277 } 8278 } 8279 } 8280 8281 setFunctionHasBranchProtectedScope(); 8282 8283 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8284 Clauses, AStmt); 8285 if (!Pair.first && DirName.getName() && !DependentHint) 8286 DSAStack->addCriticalWithHint(Dir, Hint); 8287 return Dir; 8288 } 8289 8290 StmtResult Sema::ActOnOpenMPParallelForDirective( 8291 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8292 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8293 if (!AStmt) 8294 return StmtError(); 8295 8296 auto *CS = cast<CapturedStmt>(AStmt); 8297 // 1.2.2 OpenMP Language Terminology 8298 // Structured block - An executable statement with a single entry at the 8299 // top and a single exit at the bottom. 8300 // The point of exit cannot be a branch out of the structured block. 8301 // longjmp() and throw() must not violate the entry/exit criteria. 8302 CS->getCapturedDecl()->setNothrow(); 8303 8304 OMPLoopDirective::HelperExprs B; 8305 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8306 // define the nested loops number. 8307 unsigned NestedLoopCount = 8308 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8309 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8310 VarsWithImplicitDSA, B); 8311 if (NestedLoopCount == 0) 8312 return StmtError(); 8313 8314 assert((CurContext->isDependentContext() || B.builtAll()) && 8315 "omp parallel for loop exprs were not built"); 8316 8317 if (!CurContext->isDependentContext()) { 8318 // Finalize the clauses that need pre-built expressions for CodeGen. 8319 for (OMPClause *C : Clauses) { 8320 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8321 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8322 B.NumIterations, *this, CurScope, 8323 DSAStack)) 8324 return StmtError(); 8325 } 8326 } 8327 8328 setFunctionHasBranchProtectedScope(); 8329 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8330 NestedLoopCount, Clauses, AStmt, B, 8331 DSAStack->isCancelRegion()); 8332 } 8333 8334 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8335 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8336 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8337 if (!AStmt) 8338 return StmtError(); 8339 8340 auto *CS = cast<CapturedStmt>(AStmt); 8341 // 1.2.2 OpenMP Language Terminology 8342 // Structured block - An executable statement with a single entry at the 8343 // top and a single exit at the bottom. 8344 // The point of exit cannot be a branch out of the structured block. 8345 // longjmp() and throw() must not violate the entry/exit criteria. 8346 CS->getCapturedDecl()->setNothrow(); 8347 8348 OMPLoopDirective::HelperExprs B; 8349 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8350 // define the nested loops number. 8351 unsigned NestedLoopCount = 8352 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8353 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8354 VarsWithImplicitDSA, B); 8355 if (NestedLoopCount == 0) 8356 return StmtError(); 8357 8358 if (!CurContext->isDependentContext()) { 8359 // Finalize the clauses that need pre-built expressions for CodeGen. 8360 for (OMPClause *C : Clauses) { 8361 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8362 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8363 B.NumIterations, *this, CurScope, 8364 DSAStack)) 8365 return StmtError(); 8366 } 8367 } 8368 8369 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8370 return StmtError(); 8371 8372 setFunctionHasBranchProtectedScope(); 8373 return OMPParallelForSimdDirective::Create( 8374 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8375 } 8376 8377 StmtResult 8378 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8379 Stmt *AStmt, SourceLocation StartLoc, 8380 SourceLocation EndLoc) { 8381 if (!AStmt) 8382 return StmtError(); 8383 8384 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8385 auto *CS = cast<CapturedStmt>(AStmt); 8386 // 1.2.2 OpenMP Language Terminology 8387 // Structured block - An executable statement with a single entry at the 8388 // top and a single exit at the bottom. 8389 // The point of exit cannot be a branch out of the structured block. 8390 // longjmp() and throw() must not violate the entry/exit criteria. 8391 CS->getCapturedDecl()->setNothrow(); 8392 8393 setFunctionHasBranchProtectedScope(); 8394 8395 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8396 AStmt); 8397 } 8398 8399 StmtResult 8400 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8401 Stmt *AStmt, SourceLocation StartLoc, 8402 SourceLocation EndLoc) { 8403 if (!AStmt) 8404 return StmtError(); 8405 8406 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8407 auto BaseStmt = AStmt; 8408 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8409 BaseStmt = CS->getCapturedStmt(); 8410 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8411 auto S = C->children(); 8412 if (S.begin() == S.end()) 8413 return StmtError(); 8414 // All associated statements must be '#pragma omp section' except for 8415 // the first one. 8416 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8417 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8418 if (SectionStmt) 8419 Diag(SectionStmt->getBeginLoc(), 8420 diag::err_omp_parallel_sections_substmt_not_section); 8421 return StmtError(); 8422 } 8423 cast<OMPSectionDirective>(SectionStmt) 8424 ->setHasCancel(DSAStack->isCancelRegion()); 8425 } 8426 } else { 8427 Diag(AStmt->getBeginLoc(), 8428 diag::err_omp_parallel_sections_not_compound_stmt); 8429 return StmtError(); 8430 } 8431 8432 setFunctionHasBranchProtectedScope(); 8433 8434 return OMPParallelSectionsDirective::Create( 8435 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8436 } 8437 8438 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8439 Stmt *AStmt, SourceLocation StartLoc, 8440 SourceLocation EndLoc) { 8441 if (!AStmt) 8442 return StmtError(); 8443 8444 auto *CS = cast<CapturedStmt>(AStmt); 8445 // 1.2.2 OpenMP Language Terminology 8446 // Structured block - An executable statement with a single entry at the 8447 // top and a single exit at the bottom. 8448 // The point of exit cannot be a branch out of the structured block. 8449 // longjmp() and throw() must not violate the entry/exit criteria. 8450 CS->getCapturedDecl()->setNothrow(); 8451 8452 setFunctionHasBranchProtectedScope(); 8453 8454 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8455 DSAStack->isCancelRegion()); 8456 } 8457 8458 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8459 SourceLocation EndLoc) { 8460 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8461 } 8462 8463 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8464 SourceLocation EndLoc) { 8465 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8466 } 8467 8468 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8469 SourceLocation EndLoc) { 8470 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8471 } 8472 8473 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8474 Stmt *AStmt, 8475 SourceLocation StartLoc, 8476 SourceLocation EndLoc) { 8477 if (!AStmt) 8478 return StmtError(); 8479 8480 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8481 8482 setFunctionHasBranchProtectedScope(); 8483 8484 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8485 AStmt, 8486 DSAStack->getTaskgroupReductionRef()); 8487 } 8488 8489 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8490 SourceLocation StartLoc, 8491 SourceLocation EndLoc) { 8492 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8493 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8494 } 8495 8496 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8497 Stmt *AStmt, 8498 SourceLocation StartLoc, 8499 SourceLocation EndLoc) { 8500 const OMPClause *DependFound = nullptr; 8501 const OMPClause *DependSourceClause = nullptr; 8502 const OMPClause *DependSinkClause = nullptr; 8503 bool ErrorFound = false; 8504 const OMPThreadsClause *TC = nullptr; 8505 const OMPSIMDClause *SC = nullptr; 8506 for (const OMPClause *C : Clauses) { 8507 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8508 DependFound = C; 8509 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8510 if (DependSourceClause) { 8511 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8512 << getOpenMPDirectiveName(OMPD_ordered) 8513 << getOpenMPClauseName(OMPC_depend) << 2; 8514 ErrorFound = true; 8515 } else { 8516 DependSourceClause = C; 8517 } 8518 if (DependSinkClause) { 8519 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8520 << 0; 8521 ErrorFound = true; 8522 } 8523 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8524 if (DependSourceClause) { 8525 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8526 << 1; 8527 ErrorFound = true; 8528 } 8529 DependSinkClause = C; 8530 } 8531 } else if (C->getClauseKind() == OMPC_threads) { 8532 TC = cast<OMPThreadsClause>(C); 8533 } else if (C->getClauseKind() == OMPC_simd) { 8534 SC = cast<OMPSIMDClause>(C); 8535 } 8536 } 8537 if (!ErrorFound && !SC && 8538 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8539 // OpenMP [2.8.1,simd Construct, Restrictions] 8540 // An ordered construct with the simd clause is the only OpenMP construct 8541 // that can appear in the simd region. 8542 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8543 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8544 ErrorFound = true; 8545 } else if (DependFound && (TC || SC)) { 8546 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8547 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8548 ErrorFound = true; 8549 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8550 Diag(DependFound->getBeginLoc(), 8551 diag::err_omp_ordered_directive_without_param); 8552 ErrorFound = true; 8553 } else if (TC || Clauses.empty()) { 8554 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8555 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8556 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8557 << (TC != nullptr); 8558 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8559 ErrorFound = true; 8560 } 8561 } 8562 if ((!AStmt && !DependFound) || ErrorFound) 8563 return StmtError(); 8564 8565 if (AStmt) { 8566 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8567 8568 setFunctionHasBranchProtectedScope(); 8569 } 8570 8571 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8572 } 8573 8574 namespace { 8575 /// Helper class for checking expression in 'omp atomic [update]' 8576 /// construct. 8577 class OpenMPAtomicUpdateChecker { 8578 /// Error results for atomic update expressions. 8579 enum ExprAnalysisErrorCode { 8580 /// A statement is not an expression statement. 8581 NotAnExpression, 8582 /// Expression is not builtin binary or unary operation. 8583 NotABinaryOrUnaryExpression, 8584 /// Unary operation is not post-/pre- increment/decrement operation. 8585 NotAnUnaryIncDecExpression, 8586 /// An expression is not of scalar type. 8587 NotAScalarType, 8588 /// A binary operation is not an assignment operation. 8589 NotAnAssignmentOp, 8590 /// RHS part of the binary operation is not a binary expression. 8591 NotABinaryExpression, 8592 /// RHS part is not additive/multiplicative/shift/biwise binary 8593 /// expression. 8594 NotABinaryOperator, 8595 /// RHS binary operation does not have reference to the updated LHS 8596 /// part. 8597 NotAnUpdateExpression, 8598 /// No errors is found. 8599 NoError 8600 }; 8601 /// Reference to Sema. 8602 Sema &SemaRef; 8603 /// A location for note diagnostics (when error is found). 8604 SourceLocation NoteLoc; 8605 /// 'x' lvalue part of the source atomic expression. 8606 Expr *X; 8607 /// 'expr' rvalue part of the source atomic expression. 8608 Expr *E; 8609 /// Helper expression of the form 8610 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8611 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8612 Expr *UpdateExpr; 8613 /// Is 'x' a LHS in a RHS part of full update expression. It is 8614 /// important for non-associative operations. 8615 bool IsXLHSInRHSPart; 8616 BinaryOperatorKind Op; 8617 SourceLocation OpLoc; 8618 /// true if the source expression is a postfix unary operation, false 8619 /// if it is a prefix unary operation. 8620 bool IsPostfixUpdate; 8621 8622 public: 8623 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8624 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8625 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8626 /// Check specified statement that it is suitable for 'atomic update' 8627 /// constructs and extract 'x', 'expr' and Operation from the original 8628 /// expression. If DiagId and NoteId == 0, then only check is performed 8629 /// without error notification. 8630 /// \param DiagId Diagnostic which should be emitted if error is found. 8631 /// \param NoteId Diagnostic note for the main error message. 8632 /// \return true if statement is not an update expression, false otherwise. 8633 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8634 /// Return the 'x' lvalue part of the source atomic expression. 8635 Expr *getX() const { return X; } 8636 /// Return the 'expr' rvalue part of the source atomic expression. 8637 Expr *getExpr() const { return E; } 8638 /// Return the update expression used in calculation of the updated 8639 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8640 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8641 Expr *getUpdateExpr() const { return UpdateExpr; } 8642 /// Return true if 'x' is LHS in RHS part of full update expression, 8643 /// false otherwise. 8644 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8645 8646 /// true if the source expression is a postfix unary operation, false 8647 /// if it is a prefix unary operation. 8648 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8649 8650 private: 8651 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8652 unsigned NoteId = 0); 8653 }; 8654 } // namespace 8655 8656 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8657 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8658 ExprAnalysisErrorCode ErrorFound = NoError; 8659 SourceLocation ErrorLoc, NoteLoc; 8660 SourceRange ErrorRange, NoteRange; 8661 // Allowed constructs are: 8662 // x = x binop expr; 8663 // x = expr binop x; 8664 if (AtomicBinOp->getOpcode() == BO_Assign) { 8665 X = AtomicBinOp->getLHS(); 8666 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8667 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8668 if (AtomicInnerBinOp->isMultiplicativeOp() || 8669 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8670 AtomicInnerBinOp->isBitwiseOp()) { 8671 Op = AtomicInnerBinOp->getOpcode(); 8672 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8673 Expr *LHS = AtomicInnerBinOp->getLHS(); 8674 Expr *RHS = AtomicInnerBinOp->getRHS(); 8675 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8676 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8677 /*Canonical=*/true); 8678 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8679 /*Canonical=*/true); 8680 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8681 /*Canonical=*/true); 8682 if (XId == LHSId) { 8683 E = RHS; 8684 IsXLHSInRHSPart = true; 8685 } else if (XId == RHSId) { 8686 E = LHS; 8687 IsXLHSInRHSPart = false; 8688 } else { 8689 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8690 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8691 NoteLoc = X->getExprLoc(); 8692 NoteRange = X->getSourceRange(); 8693 ErrorFound = NotAnUpdateExpression; 8694 } 8695 } else { 8696 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8697 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8698 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8699 NoteRange = SourceRange(NoteLoc, NoteLoc); 8700 ErrorFound = NotABinaryOperator; 8701 } 8702 } else { 8703 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8704 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8705 ErrorFound = NotABinaryExpression; 8706 } 8707 } else { 8708 ErrorLoc = AtomicBinOp->getExprLoc(); 8709 ErrorRange = AtomicBinOp->getSourceRange(); 8710 NoteLoc = AtomicBinOp->getOperatorLoc(); 8711 NoteRange = SourceRange(NoteLoc, NoteLoc); 8712 ErrorFound = NotAnAssignmentOp; 8713 } 8714 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8715 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8716 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8717 return true; 8718 } 8719 if (SemaRef.CurContext->isDependentContext()) 8720 E = X = UpdateExpr = nullptr; 8721 return ErrorFound != NoError; 8722 } 8723 8724 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8725 unsigned NoteId) { 8726 ExprAnalysisErrorCode ErrorFound = NoError; 8727 SourceLocation ErrorLoc, NoteLoc; 8728 SourceRange ErrorRange, NoteRange; 8729 // Allowed constructs are: 8730 // x++; 8731 // x--; 8732 // ++x; 8733 // --x; 8734 // x binop= expr; 8735 // x = x binop expr; 8736 // x = expr binop x; 8737 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8738 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8739 if (AtomicBody->getType()->isScalarType() || 8740 AtomicBody->isInstantiationDependent()) { 8741 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8742 AtomicBody->IgnoreParenImpCasts())) { 8743 // Check for Compound Assignment Operation 8744 Op = BinaryOperator::getOpForCompoundAssignment( 8745 AtomicCompAssignOp->getOpcode()); 8746 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8747 E = AtomicCompAssignOp->getRHS(); 8748 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8749 IsXLHSInRHSPart = true; 8750 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8751 AtomicBody->IgnoreParenImpCasts())) { 8752 // Check for Binary Operation 8753 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8754 return true; 8755 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8756 AtomicBody->IgnoreParenImpCasts())) { 8757 // Check for Unary Operation 8758 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8759 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8760 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8761 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8762 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8763 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8764 IsXLHSInRHSPart = true; 8765 } else { 8766 ErrorFound = NotAnUnaryIncDecExpression; 8767 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8768 ErrorRange = AtomicUnaryOp->getSourceRange(); 8769 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8770 NoteRange = SourceRange(NoteLoc, NoteLoc); 8771 } 8772 } else if (!AtomicBody->isInstantiationDependent()) { 8773 ErrorFound = NotABinaryOrUnaryExpression; 8774 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8775 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8776 } 8777 } else { 8778 ErrorFound = NotAScalarType; 8779 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8780 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8781 } 8782 } else { 8783 ErrorFound = NotAnExpression; 8784 NoteLoc = ErrorLoc = S->getBeginLoc(); 8785 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8786 } 8787 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8788 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8789 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8790 return true; 8791 } 8792 if (SemaRef.CurContext->isDependentContext()) 8793 E = X = UpdateExpr = nullptr; 8794 if (ErrorFound == NoError && E && X) { 8795 // Build an update expression of form 'OpaqueValueExpr(x) binop 8796 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8797 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8798 auto *OVEX = new (SemaRef.getASTContext()) 8799 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8800 auto *OVEExpr = new (SemaRef.getASTContext()) 8801 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8802 ExprResult Update = 8803 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8804 IsXLHSInRHSPart ? OVEExpr : OVEX); 8805 if (Update.isInvalid()) 8806 return true; 8807 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8808 Sema::AA_Casting); 8809 if (Update.isInvalid()) 8810 return true; 8811 UpdateExpr = Update.get(); 8812 } 8813 return ErrorFound != NoError; 8814 } 8815 8816 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8817 Stmt *AStmt, 8818 SourceLocation StartLoc, 8819 SourceLocation EndLoc) { 8820 if (!AStmt) 8821 return StmtError(); 8822 8823 auto *CS = cast<CapturedStmt>(AStmt); 8824 // 1.2.2 OpenMP Language Terminology 8825 // Structured block - An executable statement with a single entry at the 8826 // top and a single exit at the bottom. 8827 // The point of exit cannot be a branch out of the structured block. 8828 // longjmp() and throw() must not violate the entry/exit criteria. 8829 OpenMPClauseKind AtomicKind = OMPC_unknown; 8830 SourceLocation AtomicKindLoc; 8831 for (const OMPClause *C : Clauses) { 8832 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8833 C->getClauseKind() == OMPC_update || 8834 C->getClauseKind() == OMPC_capture) { 8835 if (AtomicKind != OMPC_unknown) { 8836 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8837 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8838 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8839 << getOpenMPClauseName(AtomicKind); 8840 } else { 8841 AtomicKind = C->getClauseKind(); 8842 AtomicKindLoc = C->getBeginLoc(); 8843 } 8844 } 8845 } 8846 8847 Stmt *Body = CS->getCapturedStmt(); 8848 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8849 Body = EWC->getSubExpr(); 8850 8851 Expr *X = nullptr; 8852 Expr *V = nullptr; 8853 Expr *E = nullptr; 8854 Expr *UE = nullptr; 8855 bool IsXLHSInRHSPart = false; 8856 bool IsPostfixUpdate = false; 8857 // OpenMP [2.12.6, atomic Construct] 8858 // In the next expressions: 8859 // * x and v (as applicable) are both l-value expressions with scalar type. 8860 // * During the execution of an atomic region, multiple syntactic 8861 // occurrences of x must designate the same storage location. 8862 // * Neither of v and expr (as applicable) may access the storage location 8863 // designated by x. 8864 // * Neither of x and expr (as applicable) may access the storage location 8865 // designated by v. 8866 // * expr is an expression with scalar type. 8867 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8868 // * binop, binop=, ++, and -- are not overloaded operators. 8869 // * The expression x binop expr must be numerically equivalent to x binop 8870 // (expr). This requirement is satisfied if the operators in expr have 8871 // precedence greater than binop, or by using parentheses around expr or 8872 // subexpressions of expr. 8873 // * The expression expr binop x must be numerically equivalent to (expr) 8874 // binop x. This requirement is satisfied if the operators in expr have 8875 // precedence equal to or greater than binop, or by using parentheses around 8876 // expr or subexpressions of expr. 8877 // * For forms that allow multiple occurrences of x, the number of times 8878 // that x is evaluated is unspecified. 8879 if (AtomicKind == OMPC_read) { 8880 enum { 8881 NotAnExpression, 8882 NotAnAssignmentOp, 8883 NotAScalarType, 8884 NotAnLValue, 8885 NoError 8886 } ErrorFound = NoError; 8887 SourceLocation ErrorLoc, NoteLoc; 8888 SourceRange ErrorRange, NoteRange; 8889 // If clause is read: 8890 // v = x; 8891 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8892 const auto *AtomicBinOp = 8893 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8894 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8895 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8896 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8897 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8898 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8899 if (!X->isLValue() || !V->isLValue()) { 8900 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8901 ErrorFound = NotAnLValue; 8902 ErrorLoc = AtomicBinOp->getExprLoc(); 8903 ErrorRange = AtomicBinOp->getSourceRange(); 8904 NoteLoc = NotLValueExpr->getExprLoc(); 8905 NoteRange = NotLValueExpr->getSourceRange(); 8906 } 8907 } else if (!X->isInstantiationDependent() || 8908 !V->isInstantiationDependent()) { 8909 const Expr *NotScalarExpr = 8910 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8911 ? V 8912 : X; 8913 ErrorFound = NotAScalarType; 8914 ErrorLoc = AtomicBinOp->getExprLoc(); 8915 ErrorRange = AtomicBinOp->getSourceRange(); 8916 NoteLoc = NotScalarExpr->getExprLoc(); 8917 NoteRange = NotScalarExpr->getSourceRange(); 8918 } 8919 } else if (!AtomicBody->isInstantiationDependent()) { 8920 ErrorFound = NotAnAssignmentOp; 8921 ErrorLoc = AtomicBody->getExprLoc(); 8922 ErrorRange = AtomicBody->getSourceRange(); 8923 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8924 : AtomicBody->getExprLoc(); 8925 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8926 : AtomicBody->getSourceRange(); 8927 } 8928 } else { 8929 ErrorFound = NotAnExpression; 8930 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8931 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8932 } 8933 if (ErrorFound != NoError) { 8934 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8935 << ErrorRange; 8936 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8937 << NoteRange; 8938 return StmtError(); 8939 } 8940 if (CurContext->isDependentContext()) 8941 V = X = nullptr; 8942 } else if (AtomicKind == OMPC_write) { 8943 enum { 8944 NotAnExpression, 8945 NotAnAssignmentOp, 8946 NotAScalarType, 8947 NotAnLValue, 8948 NoError 8949 } ErrorFound = NoError; 8950 SourceLocation ErrorLoc, NoteLoc; 8951 SourceRange ErrorRange, NoteRange; 8952 // If clause is write: 8953 // x = expr; 8954 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8955 const auto *AtomicBinOp = 8956 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8957 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8958 X = AtomicBinOp->getLHS(); 8959 E = AtomicBinOp->getRHS(); 8960 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8961 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8962 if (!X->isLValue()) { 8963 ErrorFound = NotAnLValue; 8964 ErrorLoc = AtomicBinOp->getExprLoc(); 8965 ErrorRange = AtomicBinOp->getSourceRange(); 8966 NoteLoc = X->getExprLoc(); 8967 NoteRange = X->getSourceRange(); 8968 } 8969 } else if (!X->isInstantiationDependent() || 8970 !E->isInstantiationDependent()) { 8971 const Expr *NotScalarExpr = 8972 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8973 ? E 8974 : X; 8975 ErrorFound = NotAScalarType; 8976 ErrorLoc = AtomicBinOp->getExprLoc(); 8977 ErrorRange = AtomicBinOp->getSourceRange(); 8978 NoteLoc = NotScalarExpr->getExprLoc(); 8979 NoteRange = NotScalarExpr->getSourceRange(); 8980 } 8981 } else if (!AtomicBody->isInstantiationDependent()) { 8982 ErrorFound = NotAnAssignmentOp; 8983 ErrorLoc = AtomicBody->getExprLoc(); 8984 ErrorRange = AtomicBody->getSourceRange(); 8985 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8986 : AtomicBody->getExprLoc(); 8987 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8988 : AtomicBody->getSourceRange(); 8989 } 8990 } else { 8991 ErrorFound = NotAnExpression; 8992 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8993 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8994 } 8995 if (ErrorFound != NoError) { 8996 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8997 << ErrorRange; 8998 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8999 << NoteRange; 9000 return StmtError(); 9001 } 9002 if (CurContext->isDependentContext()) 9003 E = X = nullptr; 9004 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9005 // If clause is update: 9006 // x++; 9007 // x--; 9008 // ++x; 9009 // --x; 9010 // x binop= expr; 9011 // x = x binop expr; 9012 // x = expr binop x; 9013 OpenMPAtomicUpdateChecker Checker(*this); 9014 if (Checker.checkStatement( 9015 Body, (AtomicKind == OMPC_update) 9016 ? diag::err_omp_atomic_update_not_expression_statement 9017 : diag::err_omp_atomic_not_expression_statement, 9018 diag::note_omp_atomic_update)) 9019 return StmtError(); 9020 if (!CurContext->isDependentContext()) { 9021 E = Checker.getExpr(); 9022 X = Checker.getX(); 9023 UE = Checker.getUpdateExpr(); 9024 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9025 } 9026 } else if (AtomicKind == OMPC_capture) { 9027 enum { 9028 NotAnAssignmentOp, 9029 NotACompoundStatement, 9030 NotTwoSubstatements, 9031 NotASpecificExpression, 9032 NoError 9033 } ErrorFound = NoError; 9034 SourceLocation ErrorLoc, NoteLoc; 9035 SourceRange ErrorRange, NoteRange; 9036 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9037 // If clause is a capture: 9038 // v = x++; 9039 // v = x--; 9040 // v = ++x; 9041 // v = --x; 9042 // v = x binop= expr; 9043 // v = x = x binop expr; 9044 // v = x = expr binop x; 9045 const auto *AtomicBinOp = 9046 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9047 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9048 V = AtomicBinOp->getLHS(); 9049 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9050 OpenMPAtomicUpdateChecker Checker(*this); 9051 if (Checker.checkStatement( 9052 Body, diag::err_omp_atomic_capture_not_expression_statement, 9053 diag::note_omp_atomic_update)) 9054 return StmtError(); 9055 E = Checker.getExpr(); 9056 X = Checker.getX(); 9057 UE = Checker.getUpdateExpr(); 9058 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9059 IsPostfixUpdate = Checker.isPostfixUpdate(); 9060 } else if (!AtomicBody->isInstantiationDependent()) { 9061 ErrorLoc = AtomicBody->getExprLoc(); 9062 ErrorRange = AtomicBody->getSourceRange(); 9063 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9064 : AtomicBody->getExprLoc(); 9065 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9066 : AtomicBody->getSourceRange(); 9067 ErrorFound = NotAnAssignmentOp; 9068 } 9069 if (ErrorFound != NoError) { 9070 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9071 << ErrorRange; 9072 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9073 return StmtError(); 9074 } 9075 if (CurContext->isDependentContext()) 9076 UE = V = E = X = nullptr; 9077 } else { 9078 // If clause is a capture: 9079 // { v = x; x = expr; } 9080 // { v = x; x++; } 9081 // { v = x; x--; } 9082 // { v = x; ++x; } 9083 // { v = x; --x; } 9084 // { v = x; x binop= expr; } 9085 // { v = x; x = x binop expr; } 9086 // { v = x; x = expr binop x; } 9087 // { x++; v = x; } 9088 // { x--; v = x; } 9089 // { ++x; v = x; } 9090 // { --x; v = x; } 9091 // { x binop= expr; v = x; } 9092 // { x = x binop expr; v = x; } 9093 // { x = expr binop x; v = x; } 9094 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9095 // Check that this is { expr1; expr2; } 9096 if (CS->size() == 2) { 9097 Stmt *First = CS->body_front(); 9098 Stmt *Second = CS->body_back(); 9099 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9100 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9101 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9102 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9103 // Need to find what subexpression is 'v' and what is 'x'. 9104 OpenMPAtomicUpdateChecker Checker(*this); 9105 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9106 BinaryOperator *BinOp = nullptr; 9107 if (IsUpdateExprFound) { 9108 BinOp = dyn_cast<BinaryOperator>(First); 9109 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9110 } 9111 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9112 // { v = x; x++; } 9113 // { v = x; x--; } 9114 // { v = x; ++x; } 9115 // { v = x; --x; } 9116 // { v = x; x binop= expr; } 9117 // { v = x; x = x binop expr; } 9118 // { v = x; x = expr binop x; } 9119 // Check that the first expression has form v = x. 9120 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9121 llvm::FoldingSetNodeID XId, PossibleXId; 9122 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9123 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9124 IsUpdateExprFound = XId == PossibleXId; 9125 if (IsUpdateExprFound) { 9126 V = BinOp->getLHS(); 9127 X = Checker.getX(); 9128 E = Checker.getExpr(); 9129 UE = Checker.getUpdateExpr(); 9130 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9131 IsPostfixUpdate = true; 9132 } 9133 } 9134 if (!IsUpdateExprFound) { 9135 IsUpdateExprFound = !Checker.checkStatement(First); 9136 BinOp = nullptr; 9137 if (IsUpdateExprFound) { 9138 BinOp = dyn_cast<BinaryOperator>(Second); 9139 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9140 } 9141 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9142 // { x++; v = x; } 9143 // { x--; v = x; } 9144 // { ++x; v = x; } 9145 // { --x; v = x; } 9146 // { x binop= expr; v = x; } 9147 // { x = x binop expr; v = x; } 9148 // { x = expr binop x; v = x; } 9149 // Check that the second expression has form v = x. 9150 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9151 llvm::FoldingSetNodeID XId, PossibleXId; 9152 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9153 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9154 IsUpdateExprFound = XId == PossibleXId; 9155 if (IsUpdateExprFound) { 9156 V = BinOp->getLHS(); 9157 X = Checker.getX(); 9158 E = Checker.getExpr(); 9159 UE = Checker.getUpdateExpr(); 9160 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9161 IsPostfixUpdate = false; 9162 } 9163 } 9164 } 9165 if (!IsUpdateExprFound) { 9166 // { v = x; x = expr; } 9167 auto *FirstExpr = dyn_cast<Expr>(First); 9168 auto *SecondExpr = dyn_cast<Expr>(Second); 9169 if (!FirstExpr || !SecondExpr || 9170 !(FirstExpr->isInstantiationDependent() || 9171 SecondExpr->isInstantiationDependent())) { 9172 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9173 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9174 ErrorFound = NotAnAssignmentOp; 9175 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9176 : First->getBeginLoc(); 9177 NoteRange = ErrorRange = FirstBinOp 9178 ? FirstBinOp->getSourceRange() 9179 : SourceRange(ErrorLoc, ErrorLoc); 9180 } else { 9181 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9182 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9183 ErrorFound = NotAnAssignmentOp; 9184 NoteLoc = ErrorLoc = SecondBinOp 9185 ? SecondBinOp->getOperatorLoc() 9186 : Second->getBeginLoc(); 9187 NoteRange = ErrorRange = 9188 SecondBinOp ? SecondBinOp->getSourceRange() 9189 : SourceRange(ErrorLoc, ErrorLoc); 9190 } else { 9191 Expr *PossibleXRHSInFirst = 9192 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9193 Expr *PossibleXLHSInSecond = 9194 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9195 llvm::FoldingSetNodeID X1Id, X2Id; 9196 PossibleXRHSInFirst->Profile(X1Id, Context, 9197 /*Canonical=*/true); 9198 PossibleXLHSInSecond->Profile(X2Id, Context, 9199 /*Canonical=*/true); 9200 IsUpdateExprFound = X1Id == X2Id; 9201 if (IsUpdateExprFound) { 9202 V = FirstBinOp->getLHS(); 9203 X = SecondBinOp->getLHS(); 9204 E = SecondBinOp->getRHS(); 9205 UE = nullptr; 9206 IsXLHSInRHSPart = false; 9207 IsPostfixUpdate = true; 9208 } else { 9209 ErrorFound = NotASpecificExpression; 9210 ErrorLoc = FirstBinOp->getExprLoc(); 9211 ErrorRange = FirstBinOp->getSourceRange(); 9212 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9213 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9214 } 9215 } 9216 } 9217 } 9218 } 9219 } else { 9220 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9221 NoteRange = ErrorRange = 9222 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9223 ErrorFound = NotTwoSubstatements; 9224 } 9225 } else { 9226 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9227 NoteRange = ErrorRange = 9228 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9229 ErrorFound = NotACompoundStatement; 9230 } 9231 if (ErrorFound != NoError) { 9232 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9233 << ErrorRange; 9234 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9235 return StmtError(); 9236 } 9237 if (CurContext->isDependentContext()) 9238 UE = V = E = X = nullptr; 9239 } 9240 } 9241 9242 setFunctionHasBranchProtectedScope(); 9243 9244 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9245 X, V, E, UE, IsXLHSInRHSPart, 9246 IsPostfixUpdate); 9247 } 9248 9249 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9250 Stmt *AStmt, 9251 SourceLocation StartLoc, 9252 SourceLocation EndLoc) { 9253 if (!AStmt) 9254 return StmtError(); 9255 9256 auto *CS = cast<CapturedStmt>(AStmt); 9257 // 1.2.2 OpenMP Language Terminology 9258 // Structured block - An executable statement with a single entry at the 9259 // top and a single exit at the bottom. 9260 // The point of exit cannot be a branch out of the structured block. 9261 // longjmp() and throw() must not violate the entry/exit criteria. 9262 CS->getCapturedDecl()->setNothrow(); 9263 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9264 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9265 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9266 // 1.2.2 OpenMP Language Terminology 9267 // Structured block - An executable statement with a single entry at the 9268 // top and a single exit at the bottom. 9269 // The point of exit cannot be a branch out of the structured block. 9270 // longjmp() and throw() must not violate the entry/exit criteria. 9271 CS->getCapturedDecl()->setNothrow(); 9272 } 9273 9274 // OpenMP [2.16, Nesting of Regions] 9275 // If specified, a teams construct must be contained within a target 9276 // construct. That target construct must contain no statements or directives 9277 // outside of the teams construct. 9278 if (DSAStack->hasInnerTeamsRegion()) { 9279 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9280 bool OMPTeamsFound = true; 9281 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9282 auto I = CS->body_begin(); 9283 while (I != CS->body_end()) { 9284 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9285 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9286 OMPTeamsFound) { 9287 9288 OMPTeamsFound = false; 9289 break; 9290 } 9291 ++I; 9292 } 9293 assert(I != CS->body_end() && "Not found statement"); 9294 S = *I; 9295 } else { 9296 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9297 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9298 } 9299 if (!OMPTeamsFound) { 9300 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9301 Diag(DSAStack->getInnerTeamsRegionLoc(), 9302 diag::note_omp_nested_teams_construct_here); 9303 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9304 << isa<OMPExecutableDirective>(S); 9305 return StmtError(); 9306 } 9307 } 9308 9309 setFunctionHasBranchProtectedScope(); 9310 9311 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9312 } 9313 9314 StmtResult 9315 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9316 Stmt *AStmt, SourceLocation StartLoc, 9317 SourceLocation EndLoc) { 9318 if (!AStmt) 9319 return StmtError(); 9320 9321 auto *CS = cast<CapturedStmt>(AStmt); 9322 // 1.2.2 OpenMP Language Terminology 9323 // Structured block - An executable statement with a single entry at the 9324 // top and a single exit at the bottom. 9325 // The point of exit cannot be a branch out of the structured block. 9326 // longjmp() and throw() must not violate the entry/exit criteria. 9327 CS->getCapturedDecl()->setNothrow(); 9328 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9329 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9330 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9331 // 1.2.2 OpenMP Language Terminology 9332 // Structured block - An executable statement with a single entry at the 9333 // top and a single exit at the bottom. 9334 // The point of exit cannot be a branch out of the structured block. 9335 // longjmp() and throw() must not violate the entry/exit criteria. 9336 CS->getCapturedDecl()->setNothrow(); 9337 } 9338 9339 setFunctionHasBranchProtectedScope(); 9340 9341 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9342 AStmt); 9343 } 9344 9345 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9346 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9347 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9348 if (!AStmt) 9349 return StmtError(); 9350 9351 auto *CS = cast<CapturedStmt>(AStmt); 9352 // 1.2.2 OpenMP Language Terminology 9353 // Structured block - An executable statement with a single entry at the 9354 // top and a single exit at the bottom. 9355 // The point of exit cannot be a branch out of the structured block. 9356 // longjmp() and throw() must not violate the entry/exit criteria. 9357 CS->getCapturedDecl()->setNothrow(); 9358 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9359 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9360 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9361 // 1.2.2 OpenMP Language Terminology 9362 // Structured block - An executable statement with a single entry at the 9363 // top and a single exit at the bottom. 9364 // The point of exit cannot be a branch out of the structured block. 9365 // longjmp() and throw() must not violate the entry/exit criteria. 9366 CS->getCapturedDecl()->setNothrow(); 9367 } 9368 9369 OMPLoopDirective::HelperExprs B; 9370 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9371 // define the nested loops number. 9372 unsigned NestedLoopCount = 9373 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9374 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9375 VarsWithImplicitDSA, B); 9376 if (NestedLoopCount == 0) 9377 return StmtError(); 9378 9379 assert((CurContext->isDependentContext() || B.builtAll()) && 9380 "omp target parallel for loop exprs were not built"); 9381 9382 if (!CurContext->isDependentContext()) { 9383 // Finalize the clauses that need pre-built expressions for CodeGen. 9384 for (OMPClause *C : Clauses) { 9385 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9386 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9387 B.NumIterations, *this, CurScope, 9388 DSAStack)) 9389 return StmtError(); 9390 } 9391 } 9392 9393 setFunctionHasBranchProtectedScope(); 9394 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9395 NestedLoopCount, Clauses, AStmt, 9396 B, DSAStack->isCancelRegion()); 9397 } 9398 9399 /// Check for existence of a map clause in the list of clauses. 9400 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9401 const OpenMPClauseKind K) { 9402 return llvm::any_of( 9403 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9404 } 9405 9406 template <typename... Params> 9407 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9408 const Params... ClauseTypes) { 9409 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9410 } 9411 9412 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9413 Stmt *AStmt, 9414 SourceLocation StartLoc, 9415 SourceLocation EndLoc) { 9416 if (!AStmt) 9417 return StmtError(); 9418 9419 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9420 9421 // OpenMP [2.10.1, Restrictions, p. 97] 9422 // At least one map clause must appear on the directive. 9423 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9424 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9425 << "'map' or 'use_device_ptr'" 9426 << getOpenMPDirectiveName(OMPD_target_data); 9427 return StmtError(); 9428 } 9429 9430 setFunctionHasBranchProtectedScope(); 9431 9432 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9433 AStmt); 9434 } 9435 9436 StmtResult 9437 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9438 SourceLocation StartLoc, 9439 SourceLocation EndLoc, Stmt *AStmt) { 9440 if (!AStmt) 9441 return StmtError(); 9442 9443 auto *CS = cast<CapturedStmt>(AStmt); 9444 // 1.2.2 OpenMP Language Terminology 9445 // Structured block - An executable statement with a single entry at the 9446 // top and a single exit at the bottom. 9447 // The point of exit cannot be a branch out of the structured block. 9448 // longjmp() and throw() must not violate the entry/exit criteria. 9449 CS->getCapturedDecl()->setNothrow(); 9450 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9451 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9452 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9453 // 1.2.2 OpenMP Language Terminology 9454 // Structured block - An executable statement with a single entry at the 9455 // top and a single exit at the bottom. 9456 // The point of exit cannot be a branch out of the structured block. 9457 // longjmp() and throw() must not violate the entry/exit criteria. 9458 CS->getCapturedDecl()->setNothrow(); 9459 } 9460 9461 // OpenMP [2.10.2, Restrictions, p. 99] 9462 // At least one map clause must appear on the directive. 9463 if (!hasClauses(Clauses, OMPC_map)) { 9464 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9465 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9466 return StmtError(); 9467 } 9468 9469 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9470 AStmt); 9471 } 9472 9473 StmtResult 9474 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9475 SourceLocation StartLoc, 9476 SourceLocation EndLoc, Stmt *AStmt) { 9477 if (!AStmt) 9478 return StmtError(); 9479 9480 auto *CS = cast<CapturedStmt>(AStmt); 9481 // 1.2.2 OpenMP Language Terminology 9482 // Structured block - An executable statement with a single entry at the 9483 // top and a single exit at the bottom. 9484 // The point of exit cannot be a branch out of the structured block. 9485 // longjmp() and throw() must not violate the entry/exit criteria. 9486 CS->getCapturedDecl()->setNothrow(); 9487 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9488 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9489 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9490 // 1.2.2 OpenMP Language Terminology 9491 // Structured block - An executable statement with a single entry at the 9492 // top and a single exit at the bottom. 9493 // The point of exit cannot be a branch out of the structured block. 9494 // longjmp() and throw() must not violate the entry/exit criteria. 9495 CS->getCapturedDecl()->setNothrow(); 9496 } 9497 9498 // OpenMP [2.10.3, Restrictions, p. 102] 9499 // At least one map clause must appear on the directive. 9500 if (!hasClauses(Clauses, OMPC_map)) { 9501 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9502 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9503 return StmtError(); 9504 } 9505 9506 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9507 AStmt); 9508 } 9509 9510 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9511 SourceLocation StartLoc, 9512 SourceLocation EndLoc, 9513 Stmt *AStmt) { 9514 if (!AStmt) 9515 return StmtError(); 9516 9517 auto *CS = cast<CapturedStmt>(AStmt); 9518 // 1.2.2 OpenMP Language Terminology 9519 // Structured block - An executable statement with a single entry at the 9520 // top and a single exit at the bottom. 9521 // The point of exit cannot be a branch out of the structured block. 9522 // longjmp() and throw() must not violate the entry/exit criteria. 9523 CS->getCapturedDecl()->setNothrow(); 9524 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9525 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9526 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9527 // 1.2.2 OpenMP Language Terminology 9528 // Structured block - An executable statement with a single entry at the 9529 // top and a single exit at the bottom. 9530 // The point of exit cannot be a branch out of the structured block. 9531 // longjmp() and throw() must not violate the entry/exit criteria. 9532 CS->getCapturedDecl()->setNothrow(); 9533 } 9534 9535 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9536 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9537 return StmtError(); 9538 } 9539 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9540 AStmt); 9541 } 9542 9543 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9544 Stmt *AStmt, SourceLocation StartLoc, 9545 SourceLocation EndLoc) { 9546 if (!AStmt) 9547 return StmtError(); 9548 9549 auto *CS = cast<CapturedStmt>(AStmt); 9550 // 1.2.2 OpenMP Language Terminology 9551 // Structured block - An executable statement with a single entry at the 9552 // top and a single exit at the bottom. 9553 // The point of exit cannot be a branch out of the structured block. 9554 // longjmp() and throw() must not violate the entry/exit criteria. 9555 CS->getCapturedDecl()->setNothrow(); 9556 9557 setFunctionHasBranchProtectedScope(); 9558 9559 DSAStack->setParentTeamsRegionLoc(StartLoc); 9560 9561 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9562 } 9563 9564 StmtResult 9565 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9566 SourceLocation EndLoc, 9567 OpenMPDirectiveKind CancelRegion) { 9568 if (DSAStack->isParentNowaitRegion()) { 9569 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9570 return StmtError(); 9571 } 9572 if (DSAStack->isParentOrderedRegion()) { 9573 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9574 return StmtError(); 9575 } 9576 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9577 CancelRegion); 9578 } 9579 9580 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9581 SourceLocation StartLoc, 9582 SourceLocation EndLoc, 9583 OpenMPDirectiveKind CancelRegion) { 9584 if (DSAStack->isParentNowaitRegion()) { 9585 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9586 return StmtError(); 9587 } 9588 if (DSAStack->isParentOrderedRegion()) { 9589 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9590 return StmtError(); 9591 } 9592 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9593 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9594 CancelRegion); 9595 } 9596 9597 static bool checkGrainsizeNumTasksClauses(Sema &S, 9598 ArrayRef<OMPClause *> Clauses) { 9599 const OMPClause *PrevClause = nullptr; 9600 bool ErrorFound = false; 9601 for (const OMPClause *C : Clauses) { 9602 if (C->getClauseKind() == OMPC_grainsize || 9603 C->getClauseKind() == OMPC_num_tasks) { 9604 if (!PrevClause) 9605 PrevClause = C; 9606 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9607 S.Diag(C->getBeginLoc(), 9608 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9609 << getOpenMPClauseName(C->getClauseKind()) 9610 << getOpenMPClauseName(PrevClause->getClauseKind()); 9611 S.Diag(PrevClause->getBeginLoc(), 9612 diag::note_omp_previous_grainsize_num_tasks) 9613 << getOpenMPClauseName(PrevClause->getClauseKind()); 9614 ErrorFound = true; 9615 } 9616 } 9617 } 9618 return ErrorFound; 9619 } 9620 9621 static bool checkReductionClauseWithNogroup(Sema &S, 9622 ArrayRef<OMPClause *> Clauses) { 9623 const OMPClause *ReductionClause = nullptr; 9624 const OMPClause *NogroupClause = nullptr; 9625 for (const OMPClause *C : Clauses) { 9626 if (C->getClauseKind() == OMPC_reduction) { 9627 ReductionClause = C; 9628 if (NogroupClause) 9629 break; 9630 continue; 9631 } 9632 if (C->getClauseKind() == OMPC_nogroup) { 9633 NogroupClause = C; 9634 if (ReductionClause) 9635 break; 9636 continue; 9637 } 9638 } 9639 if (ReductionClause && NogroupClause) { 9640 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9641 << SourceRange(NogroupClause->getBeginLoc(), 9642 NogroupClause->getEndLoc()); 9643 return true; 9644 } 9645 return false; 9646 } 9647 9648 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9649 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9650 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9651 if (!AStmt) 9652 return StmtError(); 9653 9654 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9655 OMPLoopDirective::HelperExprs B; 9656 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9657 // define the nested loops number. 9658 unsigned NestedLoopCount = 9659 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9660 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9661 VarsWithImplicitDSA, B); 9662 if (NestedLoopCount == 0) 9663 return StmtError(); 9664 9665 assert((CurContext->isDependentContext() || B.builtAll()) && 9666 "omp for loop exprs were not built"); 9667 9668 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9669 // The grainsize clause and num_tasks clause are mutually exclusive and may 9670 // not appear on the same taskloop directive. 9671 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9672 return StmtError(); 9673 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9674 // If a reduction clause is present on the taskloop directive, the nogroup 9675 // clause must not be specified. 9676 if (checkReductionClauseWithNogroup(*this, Clauses)) 9677 return StmtError(); 9678 9679 setFunctionHasBranchProtectedScope(); 9680 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9681 NestedLoopCount, Clauses, AStmt, B); 9682 } 9683 9684 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9685 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9686 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9687 if (!AStmt) 9688 return StmtError(); 9689 9690 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9691 OMPLoopDirective::HelperExprs B; 9692 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9693 // define the nested loops number. 9694 unsigned NestedLoopCount = 9695 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9696 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9697 VarsWithImplicitDSA, B); 9698 if (NestedLoopCount == 0) 9699 return StmtError(); 9700 9701 assert((CurContext->isDependentContext() || B.builtAll()) && 9702 "omp for loop exprs were not built"); 9703 9704 if (!CurContext->isDependentContext()) { 9705 // Finalize the clauses that need pre-built expressions for CodeGen. 9706 for (OMPClause *C : Clauses) { 9707 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9708 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9709 B.NumIterations, *this, CurScope, 9710 DSAStack)) 9711 return StmtError(); 9712 } 9713 } 9714 9715 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9716 // The grainsize clause and num_tasks clause are mutually exclusive and may 9717 // not appear on the same taskloop directive. 9718 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9719 return StmtError(); 9720 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9721 // If a reduction clause is present on the taskloop directive, the nogroup 9722 // clause must not be specified. 9723 if (checkReductionClauseWithNogroup(*this, Clauses)) 9724 return StmtError(); 9725 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9726 return StmtError(); 9727 9728 setFunctionHasBranchProtectedScope(); 9729 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9730 NestedLoopCount, Clauses, AStmt, B); 9731 } 9732 9733 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9734 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9735 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9736 if (!AStmt) 9737 return StmtError(); 9738 9739 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9740 OMPLoopDirective::HelperExprs B; 9741 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9742 // define the nested loops number. 9743 unsigned NestedLoopCount = 9744 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9745 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9746 VarsWithImplicitDSA, B); 9747 if (NestedLoopCount == 0) 9748 return StmtError(); 9749 9750 assert((CurContext->isDependentContext() || B.builtAll()) && 9751 "omp for loop exprs were not built"); 9752 9753 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9754 // The grainsize clause and num_tasks clause are mutually exclusive and may 9755 // not appear on the same taskloop directive. 9756 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9757 return StmtError(); 9758 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9759 // If a reduction clause is present on the taskloop directive, the nogroup 9760 // clause must not be specified. 9761 if (checkReductionClauseWithNogroup(*this, Clauses)) 9762 return StmtError(); 9763 9764 setFunctionHasBranchProtectedScope(); 9765 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9766 NestedLoopCount, Clauses, AStmt, B); 9767 } 9768 9769 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9770 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9771 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9772 if (!AStmt) 9773 return StmtError(); 9774 9775 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9776 OMPLoopDirective::HelperExprs B; 9777 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9778 // define the nested loops number. 9779 unsigned NestedLoopCount = 9780 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9781 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9782 VarsWithImplicitDSA, B); 9783 if (NestedLoopCount == 0) 9784 return StmtError(); 9785 9786 assert((CurContext->isDependentContext() || B.builtAll()) && 9787 "omp for loop exprs were not built"); 9788 9789 if (!CurContext->isDependentContext()) { 9790 // Finalize the clauses that need pre-built expressions for CodeGen. 9791 for (OMPClause *C : Clauses) { 9792 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9793 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9794 B.NumIterations, *this, CurScope, 9795 DSAStack)) 9796 return StmtError(); 9797 } 9798 } 9799 9800 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9801 // The grainsize clause and num_tasks clause are mutually exclusive and may 9802 // not appear on the same taskloop directive. 9803 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9804 return StmtError(); 9805 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9806 // If a reduction clause is present on the taskloop directive, the nogroup 9807 // clause must not be specified. 9808 if (checkReductionClauseWithNogroup(*this, Clauses)) 9809 return StmtError(); 9810 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9811 return StmtError(); 9812 9813 setFunctionHasBranchProtectedScope(); 9814 return OMPMasterTaskLoopSimdDirective::Create( 9815 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9816 } 9817 9818 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9819 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9820 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9821 if (!AStmt) 9822 return StmtError(); 9823 9824 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9825 auto *CS = cast<CapturedStmt>(AStmt); 9826 // 1.2.2 OpenMP Language Terminology 9827 // Structured block - An executable statement with a single entry at the 9828 // top and a single exit at the bottom. 9829 // The point of exit cannot be a branch out of the structured block. 9830 // longjmp() and throw() must not violate the entry/exit criteria. 9831 CS->getCapturedDecl()->setNothrow(); 9832 for (int ThisCaptureLevel = 9833 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9834 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9835 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9836 // 1.2.2 OpenMP Language Terminology 9837 // Structured block - An executable statement with a single entry at the 9838 // top and a single exit at the bottom. 9839 // The point of exit cannot be a branch out of the structured block. 9840 // longjmp() and throw() must not violate the entry/exit criteria. 9841 CS->getCapturedDecl()->setNothrow(); 9842 } 9843 9844 OMPLoopDirective::HelperExprs B; 9845 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9846 // define the nested loops number. 9847 unsigned NestedLoopCount = checkOpenMPLoop( 9848 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9849 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9850 VarsWithImplicitDSA, B); 9851 if (NestedLoopCount == 0) 9852 return StmtError(); 9853 9854 assert((CurContext->isDependentContext() || B.builtAll()) && 9855 "omp for loop exprs were not built"); 9856 9857 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9858 // The grainsize clause and num_tasks clause are mutually exclusive and may 9859 // not appear on the same taskloop directive. 9860 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9861 return StmtError(); 9862 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9863 // If a reduction clause is present on the taskloop directive, the nogroup 9864 // clause must not be specified. 9865 if (checkReductionClauseWithNogroup(*this, Clauses)) 9866 return StmtError(); 9867 9868 setFunctionHasBranchProtectedScope(); 9869 return OMPParallelMasterTaskLoopDirective::Create( 9870 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9871 } 9872 9873 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9874 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9875 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9876 if (!AStmt) 9877 return StmtError(); 9878 9879 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9880 auto *CS = cast<CapturedStmt>(AStmt); 9881 // 1.2.2 OpenMP Language Terminology 9882 // Structured block - An executable statement with a single entry at the 9883 // top and a single exit at the bottom. 9884 // The point of exit cannot be a branch out of the structured block. 9885 // longjmp() and throw() must not violate the entry/exit criteria. 9886 CS->getCapturedDecl()->setNothrow(); 9887 for (int ThisCaptureLevel = 9888 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9889 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9890 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9891 // 1.2.2 OpenMP Language Terminology 9892 // Structured block - An executable statement with a single entry at the 9893 // top and a single exit at the bottom. 9894 // The point of exit cannot be a branch out of the structured block. 9895 // longjmp() and throw() must not violate the entry/exit criteria. 9896 CS->getCapturedDecl()->setNothrow(); 9897 } 9898 9899 OMPLoopDirective::HelperExprs B; 9900 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9901 // define the nested loops number. 9902 unsigned NestedLoopCount = checkOpenMPLoop( 9903 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9904 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9905 VarsWithImplicitDSA, B); 9906 if (NestedLoopCount == 0) 9907 return StmtError(); 9908 9909 assert((CurContext->isDependentContext() || B.builtAll()) && 9910 "omp for loop exprs were not built"); 9911 9912 if (!CurContext->isDependentContext()) { 9913 // Finalize the clauses that need pre-built expressions for CodeGen. 9914 for (OMPClause *C : Clauses) { 9915 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9916 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9917 B.NumIterations, *this, CurScope, 9918 DSAStack)) 9919 return StmtError(); 9920 } 9921 } 9922 9923 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9924 // The grainsize clause and num_tasks clause are mutually exclusive and may 9925 // not appear on the same taskloop directive. 9926 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9927 return StmtError(); 9928 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9929 // If a reduction clause is present on the taskloop directive, the nogroup 9930 // clause must not be specified. 9931 if (checkReductionClauseWithNogroup(*this, Clauses)) 9932 return StmtError(); 9933 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9934 return StmtError(); 9935 9936 setFunctionHasBranchProtectedScope(); 9937 return OMPParallelMasterTaskLoopSimdDirective::Create( 9938 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9939 } 9940 9941 StmtResult Sema::ActOnOpenMPDistributeDirective( 9942 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9943 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9944 if (!AStmt) 9945 return StmtError(); 9946 9947 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9948 OMPLoopDirective::HelperExprs B; 9949 // In presence of clause 'collapse' with number of loops, it will 9950 // define the nested loops number. 9951 unsigned NestedLoopCount = 9952 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9953 nullptr /*ordered not a clause on distribute*/, AStmt, 9954 *this, *DSAStack, VarsWithImplicitDSA, B); 9955 if (NestedLoopCount == 0) 9956 return StmtError(); 9957 9958 assert((CurContext->isDependentContext() || B.builtAll()) && 9959 "omp for loop exprs were not built"); 9960 9961 setFunctionHasBranchProtectedScope(); 9962 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9963 NestedLoopCount, Clauses, AStmt, B); 9964 } 9965 9966 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9967 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9968 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9969 if (!AStmt) 9970 return StmtError(); 9971 9972 auto *CS = cast<CapturedStmt>(AStmt); 9973 // 1.2.2 OpenMP Language Terminology 9974 // Structured block - An executable statement with a single entry at the 9975 // top and a single exit at the bottom. 9976 // The point of exit cannot be a branch out of the structured block. 9977 // longjmp() and throw() must not violate the entry/exit criteria. 9978 CS->getCapturedDecl()->setNothrow(); 9979 for (int ThisCaptureLevel = 9980 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9981 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9982 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9983 // 1.2.2 OpenMP Language Terminology 9984 // Structured block - An executable statement with a single entry at the 9985 // top and a single exit at the bottom. 9986 // The point of exit cannot be a branch out of the structured block. 9987 // longjmp() and throw() must not violate the entry/exit criteria. 9988 CS->getCapturedDecl()->setNothrow(); 9989 } 9990 9991 OMPLoopDirective::HelperExprs B; 9992 // In presence of clause 'collapse' with number of loops, it will 9993 // define the nested loops number. 9994 unsigned NestedLoopCount = checkOpenMPLoop( 9995 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9996 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9997 VarsWithImplicitDSA, B); 9998 if (NestedLoopCount == 0) 9999 return StmtError(); 10000 10001 assert((CurContext->isDependentContext() || B.builtAll()) && 10002 "omp for loop exprs were not built"); 10003 10004 setFunctionHasBranchProtectedScope(); 10005 return OMPDistributeParallelForDirective::Create( 10006 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10007 DSAStack->isCancelRegion()); 10008 } 10009 10010 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10011 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10012 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10013 if (!AStmt) 10014 return StmtError(); 10015 10016 auto *CS = cast<CapturedStmt>(AStmt); 10017 // 1.2.2 OpenMP Language Terminology 10018 // Structured block - An executable statement with a single entry at the 10019 // top and a single exit at the bottom. 10020 // The point of exit cannot be a branch out of the structured block. 10021 // longjmp() and throw() must not violate the entry/exit criteria. 10022 CS->getCapturedDecl()->setNothrow(); 10023 for (int ThisCaptureLevel = 10024 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10025 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10026 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10027 // 1.2.2 OpenMP Language Terminology 10028 // Structured block - An executable statement with a single entry at the 10029 // top and a single exit at the bottom. 10030 // The point of exit cannot be a branch out of the structured block. 10031 // longjmp() and throw() must not violate the entry/exit criteria. 10032 CS->getCapturedDecl()->setNothrow(); 10033 } 10034 10035 OMPLoopDirective::HelperExprs B; 10036 // In presence of clause 'collapse' with number of loops, it will 10037 // define the nested loops number. 10038 unsigned NestedLoopCount = checkOpenMPLoop( 10039 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10040 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10041 VarsWithImplicitDSA, B); 10042 if (NestedLoopCount == 0) 10043 return StmtError(); 10044 10045 assert((CurContext->isDependentContext() || B.builtAll()) && 10046 "omp for loop exprs were not built"); 10047 10048 if (!CurContext->isDependentContext()) { 10049 // Finalize the clauses that need pre-built expressions for CodeGen. 10050 for (OMPClause *C : Clauses) { 10051 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10052 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10053 B.NumIterations, *this, CurScope, 10054 DSAStack)) 10055 return StmtError(); 10056 } 10057 } 10058 10059 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10060 return StmtError(); 10061 10062 setFunctionHasBranchProtectedScope(); 10063 return OMPDistributeParallelForSimdDirective::Create( 10064 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10065 } 10066 10067 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10068 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10069 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10070 if (!AStmt) 10071 return StmtError(); 10072 10073 auto *CS = cast<CapturedStmt>(AStmt); 10074 // 1.2.2 OpenMP Language Terminology 10075 // Structured block - An executable statement with a single entry at the 10076 // top and a single exit at the bottom. 10077 // The point of exit cannot be a branch out of the structured block. 10078 // longjmp() and throw() must not violate the entry/exit criteria. 10079 CS->getCapturedDecl()->setNothrow(); 10080 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10081 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10082 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10083 // 1.2.2 OpenMP Language Terminology 10084 // Structured block - An executable statement with a single entry at the 10085 // top and a single exit at the bottom. 10086 // The point of exit cannot be a branch out of the structured block. 10087 // longjmp() and throw() must not violate the entry/exit criteria. 10088 CS->getCapturedDecl()->setNothrow(); 10089 } 10090 10091 OMPLoopDirective::HelperExprs B; 10092 // In presence of clause 'collapse' with number of loops, it will 10093 // define the nested loops number. 10094 unsigned NestedLoopCount = 10095 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10096 nullptr /*ordered not a clause on distribute*/, CS, *this, 10097 *DSAStack, VarsWithImplicitDSA, B); 10098 if (NestedLoopCount == 0) 10099 return StmtError(); 10100 10101 assert((CurContext->isDependentContext() || B.builtAll()) && 10102 "omp for loop exprs were not built"); 10103 10104 if (!CurContext->isDependentContext()) { 10105 // Finalize the clauses that need pre-built expressions for CodeGen. 10106 for (OMPClause *C : Clauses) { 10107 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10108 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10109 B.NumIterations, *this, CurScope, 10110 DSAStack)) 10111 return StmtError(); 10112 } 10113 } 10114 10115 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10116 return StmtError(); 10117 10118 setFunctionHasBranchProtectedScope(); 10119 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10120 NestedLoopCount, Clauses, AStmt, B); 10121 } 10122 10123 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10124 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10125 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10126 if (!AStmt) 10127 return StmtError(); 10128 10129 auto *CS = cast<CapturedStmt>(AStmt); 10130 // 1.2.2 OpenMP Language Terminology 10131 // Structured block - An executable statement with a single entry at the 10132 // top and a single exit at the bottom. 10133 // The point of exit cannot be a branch out of the structured block. 10134 // longjmp() and throw() must not violate the entry/exit criteria. 10135 CS->getCapturedDecl()->setNothrow(); 10136 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10137 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10138 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10139 // 1.2.2 OpenMP Language Terminology 10140 // Structured block - An executable statement with a single entry at the 10141 // top and a single exit at the bottom. 10142 // The point of exit cannot be a branch out of the structured block. 10143 // longjmp() and throw() must not violate the entry/exit criteria. 10144 CS->getCapturedDecl()->setNothrow(); 10145 } 10146 10147 OMPLoopDirective::HelperExprs B; 10148 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10149 // define the nested loops number. 10150 unsigned NestedLoopCount = checkOpenMPLoop( 10151 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10152 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10153 VarsWithImplicitDSA, B); 10154 if (NestedLoopCount == 0) 10155 return StmtError(); 10156 10157 assert((CurContext->isDependentContext() || B.builtAll()) && 10158 "omp target parallel for simd loop exprs were not built"); 10159 10160 if (!CurContext->isDependentContext()) { 10161 // Finalize the clauses that need pre-built expressions for CodeGen. 10162 for (OMPClause *C : Clauses) { 10163 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10164 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10165 B.NumIterations, *this, CurScope, 10166 DSAStack)) 10167 return StmtError(); 10168 } 10169 } 10170 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10171 return StmtError(); 10172 10173 setFunctionHasBranchProtectedScope(); 10174 return OMPTargetParallelForSimdDirective::Create( 10175 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10176 } 10177 10178 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10179 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10180 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10181 if (!AStmt) 10182 return StmtError(); 10183 10184 auto *CS = cast<CapturedStmt>(AStmt); 10185 // 1.2.2 OpenMP Language Terminology 10186 // Structured block - An executable statement with a single entry at the 10187 // top and a single exit at the bottom. 10188 // The point of exit cannot be a branch out of the structured block. 10189 // longjmp() and throw() must not violate the entry/exit criteria. 10190 CS->getCapturedDecl()->setNothrow(); 10191 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10192 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10193 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10194 // 1.2.2 OpenMP Language Terminology 10195 // Structured block - An executable statement with a single entry at the 10196 // top and a single exit at the bottom. 10197 // The point of exit cannot be a branch out of the structured block. 10198 // longjmp() and throw() must not violate the entry/exit criteria. 10199 CS->getCapturedDecl()->setNothrow(); 10200 } 10201 10202 OMPLoopDirective::HelperExprs B; 10203 // In presence of clause 'collapse' with number of loops, it will define the 10204 // nested loops number. 10205 unsigned NestedLoopCount = 10206 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10207 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10208 VarsWithImplicitDSA, B); 10209 if (NestedLoopCount == 0) 10210 return StmtError(); 10211 10212 assert((CurContext->isDependentContext() || B.builtAll()) && 10213 "omp target simd loop exprs were not built"); 10214 10215 if (!CurContext->isDependentContext()) { 10216 // Finalize the clauses that need pre-built expressions for CodeGen. 10217 for (OMPClause *C : Clauses) { 10218 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10219 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10220 B.NumIterations, *this, CurScope, 10221 DSAStack)) 10222 return StmtError(); 10223 } 10224 } 10225 10226 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10227 return StmtError(); 10228 10229 setFunctionHasBranchProtectedScope(); 10230 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10231 NestedLoopCount, Clauses, AStmt, B); 10232 } 10233 10234 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10235 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10236 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10237 if (!AStmt) 10238 return StmtError(); 10239 10240 auto *CS = cast<CapturedStmt>(AStmt); 10241 // 1.2.2 OpenMP Language Terminology 10242 // Structured block - An executable statement with a single entry at the 10243 // top and a single exit at the bottom. 10244 // The point of exit cannot be a branch out of the structured block. 10245 // longjmp() and throw() must not violate the entry/exit criteria. 10246 CS->getCapturedDecl()->setNothrow(); 10247 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10248 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10249 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10250 // 1.2.2 OpenMP Language Terminology 10251 // Structured block - An executable statement with a single entry at the 10252 // top and a single exit at the bottom. 10253 // The point of exit cannot be a branch out of the structured block. 10254 // longjmp() and throw() must not violate the entry/exit criteria. 10255 CS->getCapturedDecl()->setNothrow(); 10256 } 10257 10258 OMPLoopDirective::HelperExprs B; 10259 // In presence of clause 'collapse' with number of loops, it will 10260 // define the nested loops number. 10261 unsigned NestedLoopCount = 10262 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10263 nullptr /*ordered not a clause on distribute*/, CS, *this, 10264 *DSAStack, VarsWithImplicitDSA, B); 10265 if (NestedLoopCount == 0) 10266 return StmtError(); 10267 10268 assert((CurContext->isDependentContext() || B.builtAll()) && 10269 "omp teams distribute loop exprs were not built"); 10270 10271 setFunctionHasBranchProtectedScope(); 10272 10273 DSAStack->setParentTeamsRegionLoc(StartLoc); 10274 10275 return OMPTeamsDistributeDirective::Create( 10276 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10277 } 10278 10279 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10280 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10281 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10282 if (!AStmt) 10283 return StmtError(); 10284 10285 auto *CS = cast<CapturedStmt>(AStmt); 10286 // 1.2.2 OpenMP Language Terminology 10287 // Structured block - An executable statement with a single entry at the 10288 // top and a single exit at the bottom. 10289 // The point of exit cannot be a branch out of the structured block. 10290 // longjmp() and throw() must not violate the entry/exit criteria. 10291 CS->getCapturedDecl()->setNothrow(); 10292 for (int ThisCaptureLevel = 10293 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10294 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10295 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10296 // 1.2.2 OpenMP Language Terminology 10297 // Structured block - An executable statement with a single entry at the 10298 // top and a single exit at the bottom. 10299 // The point of exit cannot be a branch out of the structured block. 10300 // longjmp() and throw() must not violate the entry/exit criteria. 10301 CS->getCapturedDecl()->setNothrow(); 10302 } 10303 10304 10305 OMPLoopDirective::HelperExprs B; 10306 // In presence of clause 'collapse' with number of loops, it will 10307 // define the nested loops number. 10308 unsigned NestedLoopCount = checkOpenMPLoop( 10309 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10310 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10311 VarsWithImplicitDSA, B); 10312 10313 if (NestedLoopCount == 0) 10314 return StmtError(); 10315 10316 assert((CurContext->isDependentContext() || B.builtAll()) && 10317 "omp teams distribute simd loop exprs were not built"); 10318 10319 if (!CurContext->isDependentContext()) { 10320 // Finalize the clauses that need pre-built expressions for CodeGen. 10321 for (OMPClause *C : Clauses) { 10322 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10323 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10324 B.NumIterations, *this, CurScope, 10325 DSAStack)) 10326 return StmtError(); 10327 } 10328 } 10329 10330 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10331 return StmtError(); 10332 10333 setFunctionHasBranchProtectedScope(); 10334 10335 DSAStack->setParentTeamsRegionLoc(StartLoc); 10336 10337 return OMPTeamsDistributeSimdDirective::Create( 10338 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10339 } 10340 10341 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10342 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10343 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10344 if (!AStmt) 10345 return StmtError(); 10346 10347 auto *CS = cast<CapturedStmt>(AStmt); 10348 // 1.2.2 OpenMP Language Terminology 10349 // Structured block - An executable statement with a single entry at the 10350 // top and a single exit at the bottom. 10351 // The point of exit cannot be a branch out of the structured block. 10352 // longjmp() and throw() must not violate the entry/exit criteria. 10353 CS->getCapturedDecl()->setNothrow(); 10354 10355 for (int ThisCaptureLevel = 10356 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10357 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10358 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10359 // 1.2.2 OpenMP Language Terminology 10360 // Structured block - An executable statement with a single entry at the 10361 // top and a single exit at the bottom. 10362 // The point of exit cannot be a branch out of the structured block. 10363 // longjmp() and throw() must not violate the entry/exit criteria. 10364 CS->getCapturedDecl()->setNothrow(); 10365 } 10366 10367 OMPLoopDirective::HelperExprs B; 10368 // In presence of clause 'collapse' with number of loops, it will 10369 // define the nested loops number. 10370 unsigned NestedLoopCount = checkOpenMPLoop( 10371 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10372 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10373 VarsWithImplicitDSA, B); 10374 10375 if (NestedLoopCount == 0) 10376 return StmtError(); 10377 10378 assert((CurContext->isDependentContext() || B.builtAll()) && 10379 "omp for loop exprs were not built"); 10380 10381 if (!CurContext->isDependentContext()) { 10382 // Finalize the clauses that need pre-built expressions for CodeGen. 10383 for (OMPClause *C : Clauses) { 10384 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10385 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10386 B.NumIterations, *this, CurScope, 10387 DSAStack)) 10388 return StmtError(); 10389 } 10390 } 10391 10392 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10393 return StmtError(); 10394 10395 setFunctionHasBranchProtectedScope(); 10396 10397 DSAStack->setParentTeamsRegionLoc(StartLoc); 10398 10399 return OMPTeamsDistributeParallelForSimdDirective::Create( 10400 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10401 } 10402 10403 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10404 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10405 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10406 if (!AStmt) 10407 return StmtError(); 10408 10409 auto *CS = cast<CapturedStmt>(AStmt); 10410 // 1.2.2 OpenMP Language Terminology 10411 // Structured block - An executable statement with a single entry at the 10412 // top and a single exit at the bottom. 10413 // The point of exit cannot be a branch out of the structured block. 10414 // longjmp() and throw() must not violate the entry/exit criteria. 10415 CS->getCapturedDecl()->setNothrow(); 10416 10417 for (int ThisCaptureLevel = 10418 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10419 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10420 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10421 // 1.2.2 OpenMP Language Terminology 10422 // Structured block - An executable statement with a single entry at the 10423 // top and a single exit at the bottom. 10424 // The point of exit cannot be a branch out of the structured block. 10425 // longjmp() and throw() must not violate the entry/exit criteria. 10426 CS->getCapturedDecl()->setNothrow(); 10427 } 10428 10429 OMPLoopDirective::HelperExprs B; 10430 // In presence of clause 'collapse' with number of loops, it will 10431 // define the nested loops number. 10432 unsigned NestedLoopCount = checkOpenMPLoop( 10433 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10434 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10435 VarsWithImplicitDSA, B); 10436 10437 if (NestedLoopCount == 0) 10438 return StmtError(); 10439 10440 assert((CurContext->isDependentContext() || B.builtAll()) && 10441 "omp for loop exprs were not built"); 10442 10443 setFunctionHasBranchProtectedScope(); 10444 10445 DSAStack->setParentTeamsRegionLoc(StartLoc); 10446 10447 return OMPTeamsDistributeParallelForDirective::Create( 10448 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10449 DSAStack->isCancelRegion()); 10450 } 10451 10452 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10453 Stmt *AStmt, 10454 SourceLocation StartLoc, 10455 SourceLocation EndLoc) { 10456 if (!AStmt) 10457 return StmtError(); 10458 10459 auto *CS = cast<CapturedStmt>(AStmt); 10460 // 1.2.2 OpenMP Language Terminology 10461 // Structured block - An executable statement with a single entry at the 10462 // top and a single exit at the bottom. 10463 // The point of exit cannot be a branch out of the structured block. 10464 // longjmp() and throw() must not violate the entry/exit criteria. 10465 CS->getCapturedDecl()->setNothrow(); 10466 10467 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10468 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10469 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10470 // 1.2.2 OpenMP Language Terminology 10471 // Structured block - An executable statement with a single entry at the 10472 // top and a single exit at the bottom. 10473 // The point of exit cannot be a branch out of the structured block. 10474 // longjmp() and throw() must not violate the entry/exit criteria. 10475 CS->getCapturedDecl()->setNothrow(); 10476 } 10477 setFunctionHasBranchProtectedScope(); 10478 10479 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10480 AStmt); 10481 } 10482 10483 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10484 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10485 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10486 if (!AStmt) 10487 return StmtError(); 10488 10489 auto *CS = cast<CapturedStmt>(AStmt); 10490 // 1.2.2 OpenMP Language Terminology 10491 // Structured block - An executable statement with a single entry at the 10492 // top and a single exit at the bottom. 10493 // The point of exit cannot be a branch out of the structured block. 10494 // longjmp() and throw() must not violate the entry/exit criteria. 10495 CS->getCapturedDecl()->setNothrow(); 10496 for (int ThisCaptureLevel = 10497 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10498 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10499 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10500 // 1.2.2 OpenMP Language Terminology 10501 // Structured block - An executable statement with a single entry at the 10502 // top and a single exit at the bottom. 10503 // The point of exit cannot be a branch out of the structured block. 10504 // longjmp() and throw() must not violate the entry/exit criteria. 10505 CS->getCapturedDecl()->setNothrow(); 10506 } 10507 10508 OMPLoopDirective::HelperExprs B; 10509 // In presence of clause 'collapse' with number of loops, it will 10510 // define the nested loops number. 10511 unsigned NestedLoopCount = checkOpenMPLoop( 10512 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10513 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10514 VarsWithImplicitDSA, B); 10515 if (NestedLoopCount == 0) 10516 return StmtError(); 10517 10518 assert((CurContext->isDependentContext() || B.builtAll()) && 10519 "omp target teams distribute loop exprs were not built"); 10520 10521 setFunctionHasBranchProtectedScope(); 10522 return OMPTargetTeamsDistributeDirective::Create( 10523 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10524 } 10525 10526 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10527 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10528 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10529 if (!AStmt) 10530 return StmtError(); 10531 10532 auto *CS = cast<CapturedStmt>(AStmt); 10533 // 1.2.2 OpenMP Language Terminology 10534 // Structured block - An executable statement with a single entry at the 10535 // top and a single exit at the bottom. 10536 // The point of exit cannot be a branch out of the structured block. 10537 // longjmp() and throw() must not violate the entry/exit criteria. 10538 CS->getCapturedDecl()->setNothrow(); 10539 for (int ThisCaptureLevel = 10540 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10541 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10542 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10543 // 1.2.2 OpenMP Language Terminology 10544 // Structured block - An executable statement with a single entry at the 10545 // top and a single exit at the bottom. 10546 // The point of exit cannot be a branch out of the structured block. 10547 // longjmp() and throw() must not violate the entry/exit criteria. 10548 CS->getCapturedDecl()->setNothrow(); 10549 } 10550 10551 OMPLoopDirective::HelperExprs B; 10552 // In presence of clause 'collapse' with number of loops, it will 10553 // define the nested loops number. 10554 unsigned NestedLoopCount = checkOpenMPLoop( 10555 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10556 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10557 VarsWithImplicitDSA, B); 10558 if (NestedLoopCount == 0) 10559 return StmtError(); 10560 10561 assert((CurContext->isDependentContext() || B.builtAll()) && 10562 "omp target teams distribute parallel for loop exprs were not built"); 10563 10564 if (!CurContext->isDependentContext()) { 10565 // Finalize the clauses that need pre-built expressions for CodeGen. 10566 for (OMPClause *C : Clauses) { 10567 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10568 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10569 B.NumIterations, *this, CurScope, 10570 DSAStack)) 10571 return StmtError(); 10572 } 10573 } 10574 10575 setFunctionHasBranchProtectedScope(); 10576 return OMPTargetTeamsDistributeParallelForDirective::Create( 10577 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10578 DSAStack->isCancelRegion()); 10579 } 10580 10581 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10582 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10583 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10584 if (!AStmt) 10585 return StmtError(); 10586 10587 auto *CS = cast<CapturedStmt>(AStmt); 10588 // 1.2.2 OpenMP Language Terminology 10589 // Structured block - An executable statement with a single entry at the 10590 // top and a single exit at the bottom. 10591 // The point of exit cannot be a branch out of the structured block. 10592 // longjmp() and throw() must not violate the entry/exit criteria. 10593 CS->getCapturedDecl()->setNothrow(); 10594 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10595 OMPD_target_teams_distribute_parallel_for_simd); 10596 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10597 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10598 // 1.2.2 OpenMP Language Terminology 10599 // Structured block - An executable statement with a single entry at the 10600 // top and a single exit at the bottom. 10601 // The point of exit cannot be a branch out of the structured block. 10602 // longjmp() and throw() must not violate the entry/exit criteria. 10603 CS->getCapturedDecl()->setNothrow(); 10604 } 10605 10606 OMPLoopDirective::HelperExprs B; 10607 // In presence of clause 'collapse' with number of loops, it will 10608 // define the nested loops number. 10609 unsigned NestedLoopCount = 10610 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10611 getCollapseNumberExpr(Clauses), 10612 nullptr /*ordered not a clause on distribute*/, CS, *this, 10613 *DSAStack, VarsWithImplicitDSA, B); 10614 if (NestedLoopCount == 0) 10615 return StmtError(); 10616 10617 assert((CurContext->isDependentContext() || B.builtAll()) && 10618 "omp target teams distribute parallel for simd loop exprs were not " 10619 "built"); 10620 10621 if (!CurContext->isDependentContext()) { 10622 // Finalize the clauses that need pre-built expressions for CodeGen. 10623 for (OMPClause *C : Clauses) { 10624 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10625 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10626 B.NumIterations, *this, CurScope, 10627 DSAStack)) 10628 return StmtError(); 10629 } 10630 } 10631 10632 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10633 return StmtError(); 10634 10635 setFunctionHasBranchProtectedScope(); 10636 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10637 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10638 } 10639 10640 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10641 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10642 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10643 if (!AStmt) 10644 return StmtError(); 10645 10646 auto *CS = cast<CapturedStmt>(AStmt); 10647 // 1.2.2 OpenMP Language Terminology 10648 // Structured block - An executable statement with a single entry at the 10649 // top and a single exit at the bottom. 10650 // The point of exit cannot be a branch out of the structured block. 10651 // longjmp() and throw() must not violate the entry/exit criteria. 10652 CS->getCapturedDecl()->setNothrow(); 10653 for (int ThisCaptureLevel = 10654 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10655 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10656 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10657 // 1.2.2 OpenMP Language Terminology 10658 // Structured block - An executable statement with a single entry at the 10659 // top and a single exit at the bottom. 10660 // The point of exit cannot be a branch out of the structured block. 10661 // longjmp() and throw() must not violate the entry/exit criteria. 10662 CS->getCapturedDecl()->setNothrow(); 10663 } 10664 10665 OMPLoopDirective::HelperExprs B; 10666 // In presence of clause 'collapse' with number of loops, it will 10667 // define the nested loops number. 10668 unsigned NestedLoopCount = checkOpenMPLoop( 10669 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10670 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10671 VarsWithImplicitDSA, B); 10672 if (NestedLoopCount == 0) 10673 return StmtError(); 10674 10675 assert((CurContext->isDependentContext() || B.builtAll()) && 10676 "omp target teams distribute simd loop exprs were not built"); 10677 10678 if (!CurContext->isDependentContext()) { 10679 // Finalize the clauses that need pre-built expressions for CodeGen. 10680 for (OMPClause *C : Clauses) { 10681 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10682 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10683 B.NumIterations, *this, CurScope, 10684 DSAStack)) 10685 return StmtError(); 10686 } 10687 } 10688 10689 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10690 return StmtError(); 10691 10692 setFunctionHasBranchProtectedScope(); 10693 return OMPTargetTeamsDistributeSimdDirective::Create( 10694 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10695 } 10696 10697 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10698 SourceLocation StartLoc, 10699 SourceLocation LParenLoc, 10700 SourceLocation EndLoc) { 10701 OMPClause *Res = nullptr; 10702 switch (Kind) { 10703 case OMPC_final: 10704 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10705 break; 10706 case OMPC_num_threads: 10707 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10708 break; 10709 case OMPC_safelen: 10710 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10711 break; 10712 case OMPC_simdlen: 10713 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10714 break; 10715 case OMPC_allocator: 10716 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10717 break; 10718 case OMPC_collapse: 10719 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10720 break; 10721 case OMPC_ordered: 10722 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10723 break; 10724 case OMPC_device: 10725 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10726 break; 10727 case OMPC_num_teams: 10728 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10729 break; 10730 case OMPC_thread_limit: 10731 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10732 break; 10733 case OMPC_priority: 10734 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10735 break; 10736 case OMPC_grainsize: 10737 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10738 break; 10739 case OMPC_num_tasks: 10740 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10741 break; 10742 case OMPC_hint: 10743 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10744 break; 10745 case OMPC_if: 10746 case OMPC_default: 10747 case OMPC_proc_bind: 10748 case OMPC_schedule: 10749 case OMPC_private: 10750 case OMPC_firstprivate: 10751 case OMPC_lastprivate: 10752 case OMPC_shared: 10753 case OMPC_reduction: 10754 case OMPC_task_reduction: 10755 case OMPC_in_reduction: 10756 case OMPC_linear: 10757 case OMPC_aligned: 10758 case OMPC_copyin: 10759 case OMPC_copyprivate: 10760 case OMPC_nowait: 10761 case OMPC_untied: 10762 case OMPC_mergeable: 10763 case OMPC_threadprivate: 10764 case OMPC_allocate: 10765 case OMPC_flush: 10766 case OMPC_read: 10767 case OMPC_write: 10768 case OMPC_update: 10769 case OMPC_capture: 10770 case OMPC_seq_cst: 10771 case OMPC_depend: 10772 case OMPC_threads: 10773 case OMPC_simd: 10774 case OMPC_map: 10775 case OMPC_nogroup: 10776 case OMPC_dist_schedule: 10777 case OMPC_defaultmap: 10778 case OMPC_unknown: 10779 case OMPC_uniform: 10780 case OMPC_to: 10781 case OMPC_from: 10782 case OMPC_use_device_ptr: 10783 case OMPC_is_device_ptr: 10784 case OMPC_unified_address: 10785 case OMPC_unified_shared_memory: 10786 case OMPC_reverse_offload: 10787 case OMPC_dynamic_allocators: 10788 case OMPC_atomic_default_mem_order: 10789 case OMPC_device_type: 10790 case OMPC_match: 10791 case OMPC_nontemporal: 10792 llvm_unreachable("Clause is not allowed."); 10793 } 10794 return Res; 10795 } 10796 10797 // An OpenMP directive such as 'target parallel' has two captured regions: 10798 // for the 'target' and 'parallel' respectively. This function returns 10799 // the region in which to capture expressions associated with a clause. 10800 // A return value of OMPD_unknown signifies that the expression should not 10801 // be captured. 10802 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10803 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10804 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10805 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10806 switch (CKind) { 10807 case OMPC_if: 10808 switch (DKind) { 10809 case OMPD_target_parallel_for_simd: 10810 if (OpenMPVersion >= 50 && 10811 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10812 CaptureRegion = OMPD_parallel; 10813 break; 10814 } 10815 LLVM_FALLTHROUGH; 10816 case OMPD_target_parallel: 10817 case OMPD_target_parallel_for: 10818 // If this clause applies to the nested 'parallel' region, capture within 10819 // the 'target' region, otherwise do not capture. 10820 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10821 CaptureRegion = OMPD_target; 10822 break; 10823 case OMPD_target_teams_distribute_parallel_for_simd: 10824 if (OpenMPVersion >= 50 && 10825 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10826 CaptureRegion = OMPD_parallel; 10827 break; 10828 } 10829 LLVM_FALLTHROUGH; 10830 case OMPD_target_teams_distribute_parallel_for: 10831 // If this clause applies to the nested 'parallel' region, capture within 10832 // the 'teams' region, otherwise do not capture. 10833 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10834 CaptureRegion = OMPD_teams; 10835 break; 10836 case OMPD_teams_distribute_parallel_for_simd: 10837 if (OpenMPVersion >= 50 && 10838 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10839 CaptureRegion = OMPD_parallel; 10840 break; 10841 } 10842 LLVM_FALLTHROUGH; 10843 case OMPD_teams_distribute_parallel_for: 10844 CaptureRegion = OMPD_teams; 10845 break; 10846 case OMPD_target_update: 10847 case OMPD_target_enter_data: 10848 case OMPD_target_exit_data: 10849 CaptureRegion = OMPD_task; 10850 break; 10851 case OMPD_parallel_master_taskloop: 10852 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10853 CaptureRegion = OMPD_parallel; 10854 break; 10855 case OMPD_parallel_master_taskloop_simd: 10856 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 10857 NameModifier == OMPD_taskloop) { 10858 CaptureRegion = OMPD_parallel; 10859 break; 10860 } 10861 if (OpenMPVersion <= 45) 10862 break; 10863 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10864 CaptureRegion = OMPD_taskloop; 10865 break; 10866 case OMPD_parallel_for_simd: 10867 if (OpenMPVersion <= 45) 10868 break; 10869 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10870 CaptureRegion = OMPD_parallel; 10871 break; 10872 case OMPD_taskloop_simd: 10873 case OMPD_master_taskloop_simd: 10874 if (OpenMPVersion <= 45) 10875 break; 10876 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10877 CaptureRegion = OMPD_taskloop; 10878 break; 10879 case OMPD_distribute_parallel_for_simd: 10880 if (OpenMPVersion <= 45) 10881 break; 10882 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10883 CaptureRegion = OMPD_parallel; 10884 break; 10885 case OMPD_target_simd: 10886 if (OpenMPVersion >= 50 && 10887 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10888 CaptureRegion = OMPD_target; 10889 break; 10890 case OMPD_teams_distribute_simd: 10891 case OMPD_target_teams_distribute_simd: 10892 if (OpenMPVersion >= 50 && 10893 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10894 CaptureRegion = OMPD_teams; 10895 break; 10896 case OMPD_cancel: 10897 case OMPD_parallel: 10898 case OMPD_parallel_master: 10899 case OMPD_parallel_sections: 10900 case OMPD_parallel_for: 10901 case OMPD_target: 10902 case OMPD_target_teams: 10903 case OMPD_target_teams_distribute: 10904 case OMPD_distribute_parallel_for: 10905 case OMPD_task: 10906 case OMPD_taskloop: 10907 case OMPD_master_taskloop: 10908 case OMPD_target_data: 10909 case OMPD_simd: 10910 case OMPD_for_simd: 10911 case OMPD_distribute_simd: 10912 // Do not capture if-clause expressions. 10913 break; 10914 case OMPD_threadprivate: 10915 case OMPD_allocate: 10916 case OMPD_taskyield: 10917 case OMPD_barrier: 10918 case OMPD_taskwait: 10919 case OMPD_cancellation_point: 10920 case OMPD_flush: 10921 case OMPD_declare_reduction: 10922 case OMPD_declare_mapper: 10923 case OMPD_declare_simd: 10924 case OMPD_declare_variant: 10925 case OMPD_declare_target: 10926 case OMPD_end_declare_target: 10927 case OMPD_teams: 10928 case OMPD_for: 10929 case OMPD_sections: 10930 case OMPD_section: 10931 case OMPD_single: 10932 case OMPD_master: 10933 case OMPD_critical: 10934 case OMPD_taskgroup: 10935 case OMPD_distribute: 10936 case OMPD_ordered: 10937 case OMPD_atomic: 10938 case OMPD_teams_distribute: 10939 case OMPD_requires: 10940 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10941 case OMPD_unknown: 10942 llvm_unreachable("Unknown OpenMP directive"); 10943 } 10944 break; 10945 case OMPC_num_threads: 10946 switch (DKind) { 10947 case OMPD_target_parallel: 10948 case OMPD_target_parallel_for: 10949 case OMPD_target_parallel_for_simd: 10950 CaptureRegion = OMPD_target; 10951 break; 10952 case OMPD_teams_distribute_parallel_for: 10953 case OMPD_teams_distribute_parallel_for_simd: 10954 case OMPD_target_teams_distribute_parallel_for: 10955 case OMPD_target_teams_distribute_parallel_for_simd: 10956 CaptureRegion = OMPD_teams; 10957 break; 10958 case OMPD_parallel: 10959 case OMPD_parallel_master: 10960 case OMPD_parallel_sections: 10961 case OMPD_parallel_for: 10962 case OMPD_parallel_for_simd: 10963 case OMPD_distribute_parallel_for: 10964 case OMPD_distribute_parallel_for_simd: 10965 case OMPD_parallel_master_taskloop: 10966 case OMPD_parallel_master_taskloop_simd: 10967 // Do not capture num_threads-clause expressions. 10968 break; 10969 case OMPD_target_data: 10970 case OMPD_target_enter_data: 10971 case OMPD_target_exit_data: 10972 case OMPD_target_update: 10973 case OMPD_target: 10974 case OMPD_target_simd: 10975 case OMPD_target_teams: 10976 case OMPD_target_teams_distribute: 10977 case OMPD_target_teams_distribute_simd: 10978 case OMPD_cancel: 10979 case OMPD_task: 10980 case OMPD_taskloop: 10981 case OMPD_taskloop_simd: 10982 case OMPD_master_taskloop: 10983 case OMPD_master_taskloop_simd: 10984 case OMPD_threadprivate: 10985 case OMPD_allocate: 10986 case OMPD_taskyield: 10987 case OMPD_barrier: 10988 case OMPD_taskwait: 10989 case OMPD_cancellation_point: 10990 case OMPD_flush: 10991 case OMPD_declare_reduction: 10992 case OMPD_declare_mapper: 10993 case OMPD_declare_simd: 10994 case OMPD_declare_variant: 10995 case OMPD_declare_target: 10996 case OMPD_end_declare_target: 10997 case OMPD_teams: 10998 case OMPD_simd: 10999 case OMPD_for: 11000 case OMPD_for_simd: 11001 case OMPD_sections: 11002 case OMPD_section: 11003 case OMPD_single: 11004 case OMPD_master: 11005 case OMPD_critical: 11006 case OMPD_taskgroup: 11007 case OMPD_distribute: 11008 case OMPD_ordered: 11009 case OMPD_atomic: 11010 case OMPD_distribute_simd: 11011 case OMPD_teams_distribute: 11012 case OMPD_teams_distribute_simd: 11013 case OMPD_requires: 11014 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11015 case OMPD_unknown: 11016 llvm_unreachable("Unknown OpenMP directive"); 11017 } 11018 break; 11019 case OMPC_num_teams: 11020 switch (DKind) { 11021 case OMPD_target_teams: 11022 case OMPD_target_teams_distribute: 11023 case OMPD_target_teams_distribute_simd: 11024 case OMPD_target_teams_distribute_parallel_for: 11025 case OMPD_target_teams_distribute_parallel_for_simd: 11026 CaptureRegion = OMPD_target; 11027 break; 11028 case OMPD_teams_distribute_parallel_for: 11029 case OMPD_teams_distribute_parallel_for_simd: 11030 case OMPD_teams: 11031 case OMPD_teams_distribute: 11032 case OMPD_teams_distribute_simd: 11033 // Do not capture num_teams-clause expressions. 11034 break; 11035 case OMPD_distribute_parallel_for: 11036 case OMPD_distribute_parallel_for_simd: 11037 case OMPD_task: 11038 case OMPD_taskloop: 11039 case OMPD_taskloop_simd: 11040 case OMPD_master_taskloop: 11041 case OMPD_master_taskloop_simd: 11042 case OMPD_parallel_master_taskloop: 11043 case OMPD_parallel_master_taskloop_simd: 11044 case OMPD_target_data: 11045 case OMPD_target_enter_data: 11046 case OMPD_target_exit_data: 11047 case OMPD_target_update: 11048 case OMPD_cancel: 11049 case OMPD_parallel: 11050 case OMPD_parallel_master: 11051 case OMPD_parallel_sections: 11052 case OMPD_parallel_for: 11053 case OMPD_parallel_for_simd: 11054 case OMPD_target: 11055 case OMPD_target_simd: 11056 case OMPD_target_parallel: 11057 case OMPD_target_parallel_for: 11058 case OMPD_target_parallel_for_simd: 11059 case OMPD_threadprivate: 11060 case OMPD_allocate: 11061 case OMPD_taskyield: 11062 case OMPD_barrier: 11063 case OMPD_taskwait: 11064 case OMPD_cancellation_point: 11065 case OMPD_flush: 11066 case OMPD_declare_reduction: 11067 case OMPD_declare_mapper: 11068 case OMPD_declare_simd: 11069 case OMPD_declare_variant: 11070 case OMPD_declare_target: 11071 case OMPD_end_declare_target: 11072 case OMPD_simd: 11073 case OMPD_for: 11074 case OMPD_for_simd: 11075 case OMPD_sections: 11076 case OMPD_section: 11077 case OMPD_single: 11078 case OMPD_master: 11079 case OMPD_critical: 11080 case OMPD_taskgroup: 11081 case OMPD_distribute: 11082 case OMPD_ordered: 11083 case OMPD_atomic: 11084 case OMPD_distribute_simd: 11085 case OMPD_requires: 11086 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11087 case OMPD_unknown: 11088 llvm_unreachable("Unknown OpenMP directive"); 11089 } 11090 break; 11091 case OMPC_thread_limit: 11092 switch (DKind) { 11093 case OMPD_target_teams: 11094 case OMPD_target_teams_distribute: 11095 case OMPD_target_teams_distribute_simd: 11096 case OMPD_target_teams_distribute_parallel_for: 11097 case OMPD_target_teams_distribute_parallel_for_simd: 11098 CaptureRegion = OMPD_target; 11099 break; 11100 case OMPD_teams_distribute_parallel_for: 11101 case OMPD_teams_distribute_parallel_for_simd: 11102 case OMPD_teams: 11103 case OMPD_teams_distribute: 11104 case OMPD_teams_distribute_simd: 11105 // Do not capture thread_limit-clause expressions. 11106 break; 11107 case OMPD_distribute_parallel_for: 11108 case OMPD_distribute_parallel_for_simd: 11109 case OMPD_task: 11110 case OMPD_taskloop: 11111 case OMPD_taskloop_simd: 11112 case OMPD_master_taskloop: 11113 case OMPD_master_taskloop_simd: 11114 case OMPD_parallel_master_taskloop: 11115 case OMPD_parallel_master_taskloop_simd: 11116 case OMPD_target_data: 11117 case OMPD_target_enter_data: 11118 case OMPD_target_exit_data: 11119 case OMPD_target_update: 11120 case OMPD_cancel: 11121 case OMPD_parallel: 11122 case OMPD_parallel_master: 11123 case OMPD_parallel_sections: 11124 case OMPD_parallel_for: 11125 case OMPD_parallel_for_simd: 11126 case OMPD_target: 11127 case OMPD_target_simd: 11128 case OMPD_target_parallel: 11129 case OMPD_target_parallel_for: 11130 case OMPD_target_parallel_for_simd: 11131 case OMPD_threadprivate: 11132 case OMPD_allocate: 11133 case OMPD_taskyield: 11134 case OMPD_barrier: 11135 case OMPD_taskwait: 11136 case OMPD_cancellation_point: 11137 case OMPD_flush: 11138 case OMPD_declare_reduction: 11139 case OMPD_declare_mapper: 11140 case OMPD_declare_simd: 11141 case OMPD_declare_variant: 11142 case OMPD_declare_target: 11143 case OMPD_end_declare_target: 11144 case OMPD_simd: 11145 case OMPD_for: 11146 case OMPD_for_simd: 11147 case OMPD_sections: 11148 case OMPD_section: 11149 case OMPD_single: 11150 case OMPD_master: 11151 case OMPD_critical: 11152 case OMPD_taskgroup: 11153 case OMPD_distribute: 11154 case OMPD_ordered: 11155 case OMPD_atomic: 11156 case OMPD_distribute_simd: 11157 case OMPD_requires: 11158 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11159 case OMPD_unknown: 11160 llvm_unreachable("Unknown OpenMP directive"); 11161 } 11162 break; 11163 case OMPC_schedule: 11164 switch (DKind) { 11165 case OMPD_parallel_for: 11166 case OMPD_parallel_for_simd: 11167 case OMPD_distribute_parallel_for: 11168 case OMPD_distribute_parallel_for_simd: 11169 case OMPD_teams_distribute_parallel_for: 11170 case OMPD_teams_distribute_parallel_for_simd: 11171 case OMPD_target_parallel_for: 11172 case OMPD_target_parallel_for_simd: 11173 case OMPD_target_teams_distribute_parallel_for: 11174 case OMPD_target_teams_distribute_parallel_for_simd: 11175 CaptureRegion = OMPD_parallel; 11176 break; 11177 case OMPD_for: 11178 case OMPD_for_simd: 11179 // Do not capture schedule-clause expressions. 11180 break; 11181 case OMPD_task: 11182 case OMPD_taskloop: 11183 case OMPD_taskloop_simd: 11184 case OMPD_master_taskloop: 11185 case OMPD_master_taskloop_simd: 11186 case OMPD_parallel_master_taskloop: 11187 case OMPD_parallel_master_taskloop_simd: 11188 case OMPD_target_data: 11189 case OMPD_target_enter_data: 11190 case OMPD_target_exit_data: 11191 case OMPD_target_update: 11192 case OMPD_teams: 11193 case OMPD_teams_distribute: 11194 case OMPD_teams_distribute_simd: 11195 case OMPD_target_teams_distribute: 11196 case OMPD_target_teams_distribute_simd: 11197 case OMPD_target: 11198 case OMPD_target_simd: 11199 case OMPD_target_parallel: 11200 case OMPD_cancel: 11201 case OMPD_parallel: 11202 case OMPD_parallel_master: 11203 case OMPD_parallel_sections: 11204 case OMPD_threadprivate: 11205 case OMPD_allocate: 11206 case OMPD_taskyield: 11207 case OMPD_barrier: 11208 case OMPD_taskwait: 11209 case OMPD_cancellation_point: 11210 case OMPD_flush: 11211 case OMPD_declare_reduction: 11212 case OMPD_declare_mapper: 11213 case OMPD_declare_simd: 11214 case OMPD_declare_variant: 11215 case OMPD_declare_target: 11216 case OMPD_end_declare_target: 11217 case OMPD_simd: 11218 case OMPD_sections: 11219 case OMPD_section: 11220 case OMPD_single: 11221 case OMPD_master: 11222 case OMPD_critical: 11223 case OMPD_taskgroup: 11224 case OMPD_distribute: 11225 case OMPD_ordered: 11226 case OMPD_atomic: 11227 case OMPD_distribute_simd: 11228 case OMPD_target_teams: 11229 case OMPD_requires: 11230 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11231 case OMPD_unknown: 11232 llvm_unreachable("Unknown OpenMP directive"); 11233 } 11234 break; 11235 case OMPC_dist_schedule: 11236 switch (DKind) { 11237 case OMPD_teams_distribute_parallel_for: 11238 case OMPD_teams_distribute_parallel_for_simd: 11239 case OMPD_teams_distribute: 11240 case OMPD_teams_distribute_simd: 11241 case OMPD_target_teams_distribute_parallel_for: 11242 case OMPD_target_teams_distribute_parallel_for_simd: 11243 case OMPD_target_teams_distribute: 11244 case OMPD_target_teams_distribute_simd: 11245 CaptureRegion = OMPD_teams; 11246 break; 11247 case OMPD_distribute_parallel_for: 11248 case OMPD_distribute_parallel_for_simd: 11249 case OMPD_distribute: 11250 case OMPD_distribute_simd: 11251 // Do not capture thread_limit-clause expressions. 11252 break; 11253 case OMPD_parallel_for: 11254 case OMPD_parallel_for_simd: 11255 case OMPD_target_parallel_for_simd: 11256 case OMPD_target_parallel_for: 11257 case OMPD_task: 11258 case OMPD_taskloop: 11259 case OMPD_taskloop_simd: 11260 case OMPD_master_taskloop: 11261 case OMPD_master_taskloop_simd: 11262 case OMPD_parallel_master_taskloop: 11263 case OMPD_parallel_master_taskloop_simd: 11264 case OMPD_target_data: 11265 case OMPD_target_enter_data: 11266 case OMPD_target_exit_data: 11267 case OMPD_target_update: 11268 case OMPD_teams: 11269 case OMPD_target: 11270 case OMPD_target_simd: 11271 case OMPD_target_parallel: 11272 case OMPD_cancel: 11273 case OMPD_parallel: 11274 case OMPD_parallel_master: 11275 case OMPD_parallel_sections: 11276 case OMPD_threadprivate: 11277 case OMPD_allocate: 11278 case OMPD_taskyield: 11279 case OMPD_barrier: 11280 case OMPD_taskwait: 11281 case OMPD_cancellation_point: 11282 case OMPD_flush: 11283 case OMPD_declare_reduction: 11284 case OMPD_declare_mapper: 11285 case OMPD_declare_simd: 11286 case OMPD_declare_variant: 11287 case OMPD_declare_target: 11288 case OMPD_end_declare_target: 11289 case OMPD_simd: 11290 case OMPD_for: 11291 case OMPD_for_simd: 11292 case OMPD_sections: 11293 case OMPD_section: 11294 case OMPD_single: 11295 case OMPD_master: 11296 case OMPD_critical: 11297 case OMPD_taskgroup: 11298 case OMPD_ordered: 11299 case OMPD_atomic: 11300 case OMPD_target_teams: 11301 case OMPD_requires: 11302 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11303 case OMPD_unknown: 11304 llvm_unreachable("Unknown OpenMP directive"); 11305 } 11306 break; 11307 case OMPC_device: 11308 switch (DKind) { 11309 case OMPD_target_update: 11310 case OMPD_target_enter_data: 11311 case OMPD_target_exit_data: 11312 case OMPD_target: 11313 case OMPD_target_simd: 11314 case OMPD_target_teams: 11315 case OMPD_target_parallel: 11316 case OMPD_target_teams_distribute: 11317 case OMPD_target_teams_distribute_simd: 11318 case OMPD_target_parallel_for: 11319 case OMPD_target_parallel_for_simd: 11320 case OMPD_target_teams_distribute_parallel_for: 11321 case OMPD_target_teams_distribute_parallel_for_simd: 11322 CaptureRegion = OMPD_task; 11323 break; 11324 case OMPD_target_data: 11325 // Do not capture device-clause expressions. 11326 break; 11327 case OMPD_teams_distribute_parallel_for: 11328 case OMPD_teams_distribute_parallel_for_simd: 11329 case OMPD_teams: 11330 case OMPD_teams_distribute: 11331 case OMPD_teams_distribute_simd: 11332 case OMPD_distribute_parallel_for: 11333 case OMPD_distribute_parallel_for_simd: 11334 case OMPD_task: 11335 case OMPD_taskloop: 11336 case OMPD_taskloop_simd: 11337 case OMPD_master_taskloop: 11338 case OMPD_master_taskloop_simd: 11339 case OMPD_parallel_master_taskloop: 11340 case OMPD_parallel_master_taskloop_simd: 11341 case OMPD_cancel: 11342 case OMPD_parallel: 11343 case OMPD_parallel_master: 11344 case OMPD_parallel_sections: 11345 case OMPD_parallel_for: 11346 case OMPD_parallel_for_simd: 11347 case OMPD_threadprivate: 11348 case OMPD_allocate: 11349 case OMPD_taskyield: 11350 case OMPD_barrier: 11351 case OMPD_taskwait: 11352 case OMPD_cancellation_point: 11353 case OMPD_flush: 11354 case OMPD_declare_reduction: 11355 case OMPD_declare_mapper: 11356 case OMPD_declare_simd: 11357 case OMPD_declare_variant: 11358 case OMPD_declare_target: 11359 case OMPD_end_declare_target: 11360 case OMPD_simd: 11361 case OMPD_for: 11362 case OMPD_for_simd: 11363 case OMPD_sections: 11364 case OMPD_section: 11365 case OMPD_single: 11366 case OMPD_master: 11367 case OMPD_critical: 11368 case OMPD_taskgroup: 11369 case OMPD_distribute: 11370 case OMPD_ordered: 11371 case OMPD_atomic: 11372 case OMPD_distribute_simd: 11373 case OMPD_requires: 11374 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11375 case OMPD_unknown: 11376 llvm_unreachable("Unknown OpenMP directive"); 11377 } 11378 break; 11379 case OMPC_grainsize: 11380 case OMPC_num_tasks: 11381 case OMPC_final: 11382 case OMPC_priority: 11383 switch (DKind) { 11384 case OMPD_task: 11385 case OMPD_taskloop: 11386 case OMPD_taskloop_simd: 11387 case OMPD_master_taskloop: 11388 case OMPD_master_taskloop_simd: 11389 break; 11390 case OMPD_parallel_master_taskloop: 11391 case OMPD_parallel_master_taskloop_simd: 11392 CaptureRegion = OMPD_parallel; 11393 break; 11394 case OMPD_target_update: 11395 case OMPD_target_enter_data: 11396 case OMPD_target_exit_data: 11397 case OMPD_target: 11398 case OMPD_target_simd: 11399 case OMPD_target_teams: 11400 case OMPD_target_parallel: 11401 case OMPD_target_teams_distribute: 11402 case OMPD_target_teams_distribute_simd: 11403 case OMPD_target_parallel_for: 11404 case OMPD_target_parallel_for_simd: 11405 case OMPD_target_teams_distribute_parallel_for: 11406 case OMPD_target_teams_distribute_parallel_for_simd: 11407 case OMPD_target_data: 11408 case OMPD_teams_distribute_parallel_for: 11409 case OMPD_teams_distribute_parallel_for_simd: 11410 case OMPD_teams: 11411 case OMPD_teams_distribute: 11412 case OMPD_teams_distribute_simd: 11413 case OMPD_distribute_parallel_for: 11414 case OMPD_distribute_parallel_for_simd: 11415 case OMPD_cancel: 11416 case OMPD_parallel: 11417 case OMPD_parallel_master: 11418 case OMPD_parallel_sections: 11419 case OMPD_parallel_for: 11420 case OMPD_parallel_for_simd: 11421 case OMPD_threadprivate: 11422 case OMPD_allocate: 11423 case OMPD_taskyield: 11424 case OMPD_barrier: 11425 case OMPD_taskwait: 11426 case OMPD_cancellation_point: 11427 case OMPD_flush: 11428 case OMPD_declare_reduction: 11429 case OMPD_declare_mapper: 11430 case OMPD_declare_simd: 11431 case OMPD_declare_variant: 11432 case OMPD_declare_target: 11433 case OMPD_end_declare_target: 11434 case OMPD_simd: 11435 case OMPD_for: 11436 case OMPD_for_simd: 11437 case OMPD_sections: 11438 case OMPD_section: 11439 case OMPD_single: 11440 case OMPD_master: 11441 case OMPD_critical: 11442 case OMPD_taskgroup: 11443 case OMPD_distribute: 11444 case OMPD_ordered: 11445 case OMPD_atomic: 11446 case OMPD_distribute_simd: 11447 case OMPD_requires: 11448 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11449 case OMPD_unknown: 11450 llvm_unreachable("Unknown OpenMP directive"); 11451 } 11452 break; 11453 case OMPC_firstprivate: 11454 case OMPC_lastprivate: 11455 case OMPC_reduction: 11456 case OMPC_task_reduction: 11457 case OMPC_in_reduction: 11458 case OMPC_linear: 11459 case OMPC_default: 11460 case OMPC_proc_bind: 11461 case OMPC_safelen: 11462 case OMPC_simdlen: 11463 case OMPC_allocator: 11464 case OMPC_collapse: 11465 case OMPC_private: 11466 case OMPC_shared: 11467 case OMPC_aligned: 11468 case OMPC_copyin: 11469 case OMPC_copyprivate: 11470 case OMPC_ordered: 11471 case OMPC_nowait: 11472 case OMPC_untied: 11473 case OMPC_mergeable: 11474 case OMPC_threadprivate: 11475 case OMPC_allocate: 11476 case OMPC_flush: 11477 case OMPC_read: 11478 case OMPC_write: 11479 case OMPC_update: 11480 case OMPC_capture: 11481 case OMPC_seq_cst: 11482 case OMPC_depend: 11483 case OMPC_threads: 11484 case OMPC_simd: 11485 case OMPC_map: 11486 case OMPC_nogroup: 11487 case OMPC_hint: 11488 case OMPC_defaultmap: 11489 case OMPC_unknown: 11490 case OMPC_uniform: 11491 case OMPC_to: 11492 case OMPC_from: 11493 case OMPC_use_device_ptr: 11494 case OMPC_is_device_ptr: 11495 case OMPC_unified_address: 11496 case OMPC_unified_shared_memory: 11497 case OMPC_reverse_offload: 11498 case OMPC_dynamic_allocators: 11499 case OMPC_atomic_default_mem_order: 11500 case OMPC_device_type: 11501 case OMPC_match: 11502 case OMPC_nontemporal: 11503 llvm_unreachable("Unexpected OpenMP clause."); 11504 } 11505 return CaptureRegion; 11506 } 11507 11508 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11509 Expr *Condition, SourceLocation StartLoc, 11510 SourceLocation LParenLoc, 11511 SourceLocation NameModifierLoc, 11512 SourceLocation ColonLoc, 11513 SourceLocation EndLoc) { 11514 Expr *ValExpr = Condition; 11515 Stmt *HelperValStmt = nullptr; 11516 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11517 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11518 !Condition->isInstantiationDependent() && 11519 !Condition->containsUnexpandedParameterPack()) { 11520 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11521 if (Val.isInvalid()) 11522 return nullptr; 11523 11524 ValExpr = Val.get(); 11525 11526 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11527 CaptureRegion = getOpenMPCaptureRegionForClause( 11528 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11529 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11530 ValExpr = MakeFullExpr(ValExpr).get(); 11531 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11532 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11533 HelperValStmt = buildPreInits(Context, Captures); 11534 } 11535 } 11536 11537 return new (Context) 11538 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11539 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11540 } 11541 11542 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11543 SourceLocation StartLoc, 11544 SourceLocation LParenLoc, 11545 SourceLocation EndLoc) { 11546 Expr *ValExpr = Condition; 11547 Stmt *HelperValStmt = nullptr; 11548 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11549 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11550 !Condition->isInstantiationDependent() && 11551 !Condition->containsUnexpandedParameterPack()) { 11552 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11553 if (Val.isInvalid()) 11554 return nullptr; 11555 11556 ValExpr = MakeFullExpr(Val.get()).get(); 11557 11558 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11559 CaptureRegion = 11560 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11561 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11562 ValExpr = MakeFullExpr(ValExpr).get(); 11563 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11564 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11565 HelperValStmt = buildPreInits(Context, Captures); 11566 } 11567 } 11568 11569 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11570 StartLoc, LParenLoc, EndLoc); 11571 } 11572 11573 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11574 Expr *Op) { 11575 if (!Op) 11576 return ExprError(); 11577 11578 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11579 public: 11580 IntConvertDiagnoser() 11581 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11582 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11583 QualType T) override { 11584 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11585 } 11586 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11587 QualType T) override { 11588 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11589 } 11590 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11591 QualType T, 11592 QualType ConvTy) override { 11593 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11594 } 11595 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11596 QualType ConvTy) override { 11597 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11598 << ConvTy->isEnumeralType() << ConvTy; 11599 } 11600 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11601 QualType T) override { 11602 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11603 } 11604 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11605 QualType ConvTy) override { 11606 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11607 << ConvTy->isEnumeralType() << ConvTy; 11608 } 11609 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11610 QualType) override { 11611 llvm_unreachable("conversion functions are permitted"); 11612 } 11613 } ConvertDiagnoser; 11614 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11615 } 11616 11617 static bool 11618 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11619 bool StrictlyPositive, bool BuildCapture = false, 11620 OpenMPDirectiveKind DKind = OMPD_unknown, 11621 OpenMPDirectiveKind *CaptureRegion = nullptr, 11622 Stmt **HelperValStmt = nullptr) { 11623 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11624 !ValExpr->isInstantiationDependent()) { 11625 SourceLocation Loc = ValExpr->getExprLoc(); 11626 ExprResult Value = 11627 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11628 if (Value.isInvalid()) 11629 return false; 11630 11631 ValExpr = Value.get(); 11632 // The expression must evaluate to a non-negative integer value. 11633 llvm::APSInt Result; 11634 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11635 Result.isSigned() && 11636 !((!StrictlyPositive && Result.isNonNegative()) || 11637 (StrictlyPositive && Result.isStrictlyPositive()))) { 11638 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11639 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11640 << ValExpr->getSourceRange(); 11641 return false; 11642 } 11643 if (!BuildCapture) 11644 return true; 11645 *CaptureRegion = 11646 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11647 if (*CaptureRegion != OMPD_unknown && 11648 !SemaRef.CurContext->isDependentContext()) { 11649 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11650 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11651 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11652 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11653 } 11654 } 11655 return true; 11656 } 11657 11658 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11659 SourceLocation StartLoc, 11660 SourceLocation LParenLoc, 11661 SourceLocation EndLoc) { 11662 Expr *ValExpr = NumThreads; 11663 Stmt *HelperValStmt = nullptr; 11664 11665 // OpenMP [2.5, Restrictions] 11666 // The num_threads expression must evaluate to a positive integer value. 11667 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11668 /*StrictlyPositive=*/true)) 11669 return nullptr; 11670 11671 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11672 OpenMPDirectiveKind CaptureRegion = 11673 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11674 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11675 ValExpr = MakeFullExpr(ValExpr).get(); 11676 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11677 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11678 HelperValStmt = buildPreInits(Context, Captures); 11679 } 11680 11681 return new (Context) OMPNumThreadsClause( 11682 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11683 } 11684 11685 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11686 OpenMPClauseKind CKind, 11687 bool StrictlyPositive) { 11688 if (!E) 11689 return ExprError(); 11690 if (E->isValueDependent() || E->isTypeDependent() || 11691 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11692 return E; 11693 llvm::APSInt Result; 11694 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11695 if (ICE.isInvalid()) 11696 return ExprError(); 11697 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11698 (!StrictlyPositive && !Result.isNonNegative())) { 11699 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11700 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11701 << E->getSourceRange(); 11702 return ExprError(); 11703 } 11704 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11705 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11706 << E->getSourceRange(); 11707 return ExprError(); 11708 } 11709 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11710 DSAStack->setAssociatedLoops(Result.getExtValue()); 11711 else if (CKind == OMPC_ordered) 11712 DSAStack->setAssociatedLoops(Result.getExtValue()); 11713 return ICE; 11714 } 11715 11716 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11717 SourceLocation LParenLoc, 11718 SourceLocation EndLoc) { 11719 // OpenMP [2.8.1, simd construct, Description] 11720 // The parameter of the safelen clause must be a constant 11721 // positive integer expression. 11722 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11723 if (Safelen.isInvalid()) 11724 return nullptr; 11725 return new (Context) 11726 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11727 } 11728 11729 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11730 SourceLocation LParenLoc, 11731 SourceLocation EndLoc) { 11732 // OpenMP [2.8.1, simd construct, Description] 11733 // The parameter of the simdlen clause must be a constant 11734 // positive integer expression. 11735 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11736 if (Simdlen.isInvalid()) 11737 return nullptr; 11738 return new (Context) 11739 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11740 } 11741 11742 /// Tries to find omp_allocator_handle_t type. 11743 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11744 DSAStackTy *Stack) { 11745 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11746 if (!OMPAllocatorHandleT.isNull()) 11747 return true; 11748 // Build the predefined allocator expressions. 11749 bool ErrorFound = false; 11750 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11751 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11752 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11753 StringRef Allocator = 11754 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11755 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11756 auto *VD = dyn_cast_or_null<ValueDecl>( 11757 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11758 if (!VD) { 11759 ErrorFound = true; 11760 break; 11761 } 11762 QualType AllocatorType = 11763 VD->getType().getNonLValueExprType(S.getASTContext()); 11764 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11765 if (!Res.isUsable()) { 11766 ErrorFound = true; 11767 break; 11768 } 11769 if (OMPAllocatorHandleT.isNull()) 11770 OMPAllocatorHandleT = AllocatorType; 11771 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11772 ErrorFound = true; 11773 break; 11774 } 11775 Stack->setAllocator(AllocatorKind, Res.get()); 11776 } 11777 if (ErrorFound) { 11778 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11779 return false; 11780 } 11781 OMPAllocatorHandleT.addConst(); 11782 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11783 return true; 11784 } 11785 11786 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11787 SourceLocation LParenLoc, 11788 SourceLocation EndLoc) { 11789 // OpenMP [2.11.3, allocate Directive, Description] 11790 // allocator is an expression of omp_allocator_handle_t type. 11791 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11792 return nullptr; 11793 11794 ExprResult Allocator = DefaultLvalueConversion(A); 11795 if (Allocator.isInvalid()) 11796 return nullptr; 11797 Allocator = PerformImplicitConversion(Allocator.get(), 11798 DSAStack->getOMPAllocatorHandleT(), 11799 Sema::AA_Initializing, 11800 /*AllowExplicit=*/true); 11801 if (Allocator.isInvalid()) 11802 return nullptr; 11803 return new (Context) 11804 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11805 } 11806 11807 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11808 SourceLocation StartLoc, 11809 SourceLocation LParenLoc, 11810 SourceLocation EndLoc) { 11811 // OpenMP [2.7.1, loop construct, Description] 11812 // OpenMP [2.8.1, simd construct, Description] 11813 // OpenMP [2.9.6, distribute construct, Description] 11814 // The parameter of the collapse clause must be a constant 11815 // positive integer expression. 11816 ExprResult NumForLoopsResult = 11817 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11818 if (NumForLoopsResult.isInvalid()) 11819 return nullptr; 11820 return new (Context) 11821 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11822 } 11823 11824 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11825 SourceLocation EndLoc, 11826 SourceLocation LParenLoc, 11827 Expr *NumForLoops) { 11828 // OpenMP [2.7.1, loop construct, Description] 11829 // OpenMP [2.8.1, simd construct, Description] 11830 // OpenMP [2.9.6, distribute construct, Description] 11831 // The parameter of the ordered clause must be a constant 11832 // positive integer expression if any. 11833 if (NumForLoops && LParenLoc.isValid()) { 11834 ExprResult NumForLoopsResult = 11835 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11836 if (NumForLoopsResult.isInvalid()) 11837 return nullptr; 11838 NumForLoops = NumForLoopsResult.get(); 11839 } else { 11840 NumForLoops = nullptr; 11841 } 11842 auto *Clause = OMPOrderedClause::Create( 11843 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11844 StartLoc, LParenLoc, EndLoc); 11845 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11846 return Clause; 11847 } 11848 11849 OMPClause *Sema::ActOnOpenMPSimpleClause( 11850 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11851 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11852 OMPClause *Res = nullptr; 11853 switch (Kind) { 11854 case OMPC_default: 11855 Res = 11856 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11857 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11858 break; 11859 case OMPC_proc_bind: 11860 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 11861 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11862 break; 11863 case OMPC_atomic_default_mem_order: 11864 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11865 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11866 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11867 break; 11868 case OMPC_if: 11869 case OMPC_final: 11870 case OMPC_num_threads: 11871 case OMPC_safelen: 11872 case OMPC_simdlen: 11873 case OMPC_allocator: 11874 case OMPC_collapse: 11875 case OMPC_schedule: 11876 case OMPC_private: 11877 case OMPC_firstprivate: 11878 case OMPC_lastprivate: 11879 case OMPC_shared: 11880 case OMPC_reduction: 11881 case OMPC_task_reduction: 11882 case OMPC_in_reduction: 11883 case OMPC_linear: 11884 case OMPC_aligned: 11885 case OMPC_copyin: 11886 case OMPC_copyprivate: 11887 case OMPC_ordered: 11888 case OMPC_nowait: 11889 case OMPC_untied: 11890 case OMPC_mergeable: 11891 case OMPC_threadprivate: 11892 case OMPC_allocate: 11893 case OMPC_flush: 11894 case OMPC_read: 11895 case OMPC_write: 11896 case OMPC_update: 11897 case OMPC_capture: 11898 case OMPC_seq_cst: 11899 case OMPC_depend: 11900 case OMPC_device: 11901 case OMPC_threads: 11902 case OMPC_simd: 11903 case OMPC_map: 11904 case OMPC_num_teams: 11905 case OMPC_thread_limit: 11906 case OMPC_priority: 11907 case OMPC_grainsize: 11908 case OMPC_nogroup: 11909 case OMPC_num_tasks: 11910 case OMPC_hint: 11911 case OMPC_dist_schedule: 11912 case OMPC_defaultmap: 11913 case OMPC_unknown: 11914 case OMPC_uniform: 11915 case OMPC_to: 11916 case OMPC_from: 11917 case OMPC_use_device_ptr: 11918 case OMPC_is_device_ptr: 11919 case OMPC_unified_address: 11920 case OMPC_unified_shared_memory: 11921 case OMPC_reverse_offload: 11922 case OMPC_dynamic_allocators: 11923 case OMPC_device_type: 11924 case OMPC_match: 11925 case OMPC_nontemporal: 11926 llvm_unreachable("Clause is not allowed."); 11927 } 11928 return Res; 11929 } 11930 11931 static std::string 11932 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11933 ArrayRef<unsigned> Exclude = llvm::None) { 11934 SmallString<256> Buffer; 11935 llvm::raw_svector_ostream Out(Buffer); 11936 unsigned Skipped = Exclude.size(); 11937 auto S = Exclude.begin(), E = Exclude.end(); 11938 for (unsigned I = First; I < Last; ++I) { 11939 if (std::find(S, E, I) != E) { 11940 --Skipped; 11941 continue; 11942 } 11943 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11944 if (I + Skipped + 2 == Last) 11945 Out << " or "; 11946 else if (I + Skipped + 1 != Last) 11947 Out << ", "; 11948 } 11949 return Out.str(); 11950 } 11951 11952 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11953 SourceLocation KindKwLoc, 11954 SourceLocation StartLoc, 11955 SourceLocation LParenLoc, 11956 SourceLocation EndLoc) { 11957 if (Kind == OMPC_DEFAULT_unknown) { 11958 static_assert(OMPC_DEFAULT_unknown > 0, 11959 "OMPC_DEFAULT_unknown not greater than 0"); 11960 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11961 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11962 /*Last=*/OMPC_DEFAULT_unknown) 11963 << getOpenMPClauseName(OMPC_default); 11964 return nullptr; 11965 } 11966 switch (Kind) { 11967 case OMPC_DEFAULT_none: 11968 DSAStack->setDefaultDSANone(KindKwLoc); 11969 break; 11970 case OMPC_DEFAULT_shared: 11971 DSAStack->setDefaultDSAShared(KindKwLoc); 11972 break; 11973 case OMPC_DEFAULT_unknown: 11974 llvm_unreachable("Clause kind is not allowed."); 11975 break; 11976 } 11977 return new (Context) 11978 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11979 } 11980 11981 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 11982 SourceLocation KindKwLoc, 11983 SourceLocation StartLoc, 11984 SourceLocation LParenLoc, 11985 SourceLocation EndLoc) { 11986 if (Kind == OMP_PROC_BIND_unknown) { 11987 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11988 << getListOfPossibleValues(OMPC_proc_bind, 11989 /*First=*/unsigned(OMP_PROC_BIND_master), 11990 /*Last=*/5) 11991 << getOpenMPClauseName(OMPC_proc_bind); 11992 return nullptr; 11993 } 11994 return new (Context) 11995 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11996 } 11997 11998 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11999 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12000 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12001 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12002 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12003 << getListOfPossibleValues( 12004 OMPC_atomic_default_mem_order, /*First=*/0, 12005 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12006 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12007 return nullptr; 12008 } 12009 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12010 LParenLoc, EndLoc); 12011 } 12012 12013 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12014 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12015 SourceLocation StartLoc, SourceLocation LParenLoc, 12016 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12017 SourceLocation EndLoc) { 12018 OMPClause *Res = nullptr; 12019 switch (Kind) { 12020 case OMPC_schedule: 12021 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12022 assert(Argument.size() == NumberOfElements && 12023 ArgumentLoc.size() == NumberOfElements); 12024 Res = ActOnOpenMPScheduleClause( 12025 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12026 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12027 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12028 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12029 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12030 break; 12031 case OMPC_if: 12032 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12033 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12034 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12035 DelimLoc, EndLoc); 12036 break; 12037 case OMPC_dist_schedule: 12038 Res = ActOnOpenMPDistScheduleClause( 12039 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12040 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12041 break; 12042 case OMPC_defaultmap: 12043 enum { Modifier, DefaultmapKind }; 12044 Res = ActOnOpenMPDefaultmapClause( 12045 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12046 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12047 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12048 EndLoc); 12049 break; 12050 case OMPC_final: 12051 case OMPC_num_threads: 12052 case OMPC_safelen: 12053 case OMPC_simdlen: 12054 case OMPC_allocator: 12055 case OMPC_collapse: 12056 case OMPC_default: 12057 case OMPC_proc_bind: 12058 case OMPC_private: 12059 case OMPC_firstprivate: 12060 case OMPC_lastprivate: 12061 case OMPC_shared: 12062 case OMPC_reduction: 12063 case OMPC_task_reduction: 12064 case OMPC_in_reduction: 12065 case OMPC_linear: 12066 case OMPC_aligned: 12067 case OMPC_copyin: 12068 case OMPC_copyprivate: 12069 case OMPC_ordered: 12070 case OMPC_nowait: 12071 case OMPC_untied: 12072 case OMPC_mergeable: 12073 case OMPC_threadprivate: 12074 case OMPC_allocate: 12075 case OMPC_flush: 12076 case OMPC_read: 12077 case OMPC_write: 12078 case OMPC_update: 12079 case OMPC_capture: 12080 case OMPC_seq_cst: 12081 case OMPC_depend: 12082 case OMPC_device: 12083 case OMPC_threads: 12084 case OMPC_simd: 12085 case OMPC_map: 12086 case OMPC_num_teams: 12087 case OMPC_thread_limit: 12088 case OMPC_priority: 12089 case OMPC_grainsize: 12090 case OMPC_nogroup: 12091 case OMPC_num_tasks: 12092 case OMPC_hint: 12093 case OMPC_unknown: 12094 case OMPC_uniform: 12095 case OMPC_to: 12096 case OMPC_from: 12097 case OMPC_use_device_ptr: 12098 case OMPC_is_device_ptr: 12099 case OMPC_unified_address: 12100 case OMPC_unified_shared_memory: 12101 case OMPC_reverse_offload: 12102 case OMPC_dynamic_allocators: 12103 case OMPC_atomic_default_mem_order: 12104 case OMPC_device_type: 12105 case OMPC_match: 12106 case OMPC_nontemporal: 12107 llvm_unreachable("Clause is not allowed."); 12108 } 12109 return Res; 12110 } 12111 12112 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12113 OpenMPScheduleClauseModifier M2, 12114 SourceLocation M1Loc, SourceLocation M2Loc) { 12115 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12116 SmallVector<unsigned, 2> Excluded; 12117 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12118 Excluded.push_back(M2); 12119 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12120 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12121 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12122 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12123 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12124 << getListOfPossibleValues(OMPC_schedule, 12125 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12126 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12127 Excluded) 12128 << getOpenMPClauseName(OMPC_schedule); 12129 return true; 12130 } 12131 return false; 12132 } 12133 12134 OMPClause *Sema::ActOnOpenMPScheduleClause( 12135 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12136 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12137 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12138 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12139 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12140 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12141 return nullptr; 12142 // OpenMP, 2.7.1, Loop Construct, Restrictions 12143 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12144 // but not both. 12145 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12146 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12147 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12148 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12149 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12150 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12151 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12152 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12153 return nullptr; 12154 } 12155 if (Kind == OMPC_SCHEDULE_unknown) { 12156 std::string Values; 12157 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12158 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12159 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12160 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12161 Exclude); 12162 } else { 12163 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12164 /*Last=*/OMPC_SCHEDULE_unknown); 12165 } 12166 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12167 << Values << getOpenMPClauseName(OMPC_schedule); 12168 return nullptr; 12169 } 12170 // OpenMP, 2.7.1, Loop Construct, Restrictions 12171 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12172 // schedule(guided). 12173 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12174 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12175 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12176 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12177 diag::err_omp_schedule_nonmonotonic_static); 12178 return nullptr; 12179 } 12180 Expr *ValExpr = ChunkSize; 12181 Stmt *HelperValStmt = nullptr; 12182 if (ChunkSize) { 12183 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12184 !ChunkSize->isInstantiationDependent() && 12185 !ChunkSize->containsUnexpandedParameterPack()) { 12186 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12187 ExprResult Val = 12188 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12189 if (Val.isInvalid()) 12190 return nullptr; 12191 12192 ValExpr = Val.get(); 12193 12194 // OpenMP [2.7.1, Restrictions] 12195 // chunk_size must be a loop invariant integer expression with a positive 12196 // value. 12197 llvm::APSInt Result; 12198 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12199 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12200 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12201 << "schedule" << 1 << ChunkSize->getSourceRange(); 12202 return nullptr; 12203 } 12204 } else if (getOpenMPCaptureRegionForClause( 12205 DSAStack->getCurrentDirective(), OMPC_schedule, 12206 LangOpts.OpenMP) != OMPD_unknown && 12207 !CurContext->isDependentContext()) { 12208 ValExpr = MakeFullExpr(ValExpr).get(); 12209 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12210 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12211 HelperValStmt = buildPreInits(Context, Captures); 12212 } 12213 } 12214 } 12215 12216 return new (Context) 12217 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12218 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12219 } 12220 12221 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12222 SourceLocation StartLoc, 12223 SourceLocation EndLoc) { 12224 OMPClause *Res = nullptr; 12225 switch (Kind) { 12226 case OMPC_ordered: 12227 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12228 break; 12229 case OMPC_nowait: 12230 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12231 break; 12232 case OMPC_untied: 12233 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12234 break; 12235 case OMPC_mergeable: 12236 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12237 break; 12238 case OMPC_read: 12239 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12240 break; 12241 case OMPC_write: 12242 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12243 break; 12244 case OMPC_update: 12245 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12246 break; 12247 case OMPC_capture: 12248 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12249 break; 12250 case OMPC_seq_cst: 12251 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12252 break; 12253 case OMPC_threads: 12254 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12255 break; 12256 case OMPC_simd: 12257 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12258 break; 12259 case OMPC_nogroup: 12260 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12261 break; 12262 case OMPC_unified_address: 12263 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12264 break; 12265 case OMPC_unified_shared_memory: 12266 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12267 break; 12268 case OMPC_reverse_offload: 12269 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12270 break; 12271 case OMPC_dynamic_allocators: 12272 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12273 break; 12274 case OMPC_if: 12275 case OMPC_final: 12276 case OMPC_num_threads: 12277 case OMPC_safelen: 12278 case OMPC_simdlen: 12279 case OMPC_allocator: 12280 case OMPC_collapse: 12281 case OMPC_schedule: 12282 case OMPC_private: 12283 case OMPC_firstprivate: 12284 case OMPC_lastprivate: 12285 case OMPC_shared: 12286 case OMPC_reduction: 12287 case OMPC_task_reduction: 12288 case OMPC_in_reduction: 12289 case OMPC_linear: 12290 case OMPC_aligned: 12291 case OMPC_copyin: 12292 case OMPC_copyprivate: 12293 case OMPC_default: 12294 case OMPC_proc_bind: 12295 case OMPC_threadprivate: 12296 case OMPC_allocate: 12297 case OMPC_flush: 12298 case OMPC_depend: 12299 case OMPC_device: 12300 case OMPC_map: 12301 case OMPC_num_teams: 12302 case OMPC_thread_limit: 12303 case OMPC_priority: 12304 case OMPC_grainsize: 12305 case OMPC_num_tasks: 12306 case OMPC_hint: 12307 case OMPC_dist_schedule: 12308 case OMPC_defaultmap: 12309 case OMPC_unknown: 12310 case OMPC_uniform: 12311 case OMPC_to: 12312 case OMPC_from: 12313 case OMPC_use_device_ptr: 12314 case OMPC_is_device_ptr: 12315 case OMPC_atomic_default_mem_order: 12316 case OMPC_device_type: 12317 case OMPC_match: 12318 case OMPC_nontemporal: 12319 llvm_unreachable("Clause is not allowed."); 12320 } 12321 return Res; 12322 } 12323 12324 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12325 SourceLocation EndLoc) { 12326 DSAStack->setNowaitRegion(); 12327 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12328 } 12329 12330 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12331 SourceLocation EndLoc) { 12332 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12333 } 12334 12335 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12336 SourceLocation EndLoc) { 12337 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12338 } 12339 12340 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12341 SourceLocation EndLoc) { 12342 return new (Context) OMPReadClause(StartLoc, EndLoc); 12343 } 12344 12345 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12346 SourceLocation EndLoc) { 12347 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12348 } 12349 12350 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12351 SourceLocation EndLoc) { 12352 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12353 } 12354 12355 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12356 SourceLocation EndLoc) { 12357 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12358 } 12359 12360 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12361 SourceLocation EndLoc) { 12362 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12363 } 12364 12365 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12366 SourceLocation EndLoc) { 12367 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12368 } 12369 12370 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12371 SourceLocation EndLoc) { 12372 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12373 } 12374 12375 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12376 SourceLocation EndLoc) { 12377 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12378 } 12379 12380 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12381 SourceLocation EndLoc) { 12382 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12383 } 12384 12385 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12386 SourceLocation EndLoc) { 12387 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12388 } 12389 12390 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12391 SourceLocation EndLoc) { 12392 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12393 } 12394 12395 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12396 SourceLocation EndLoc) { 12397 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12398 } 12399 12400 OMPClause *Sema::ActOnOpenMPVarListClause( 12401 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12402 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12403 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12404 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 12405 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12406 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 12407 SourceLocation DepLinMapLastLoc) { 12408 SourceLocation StartLoc = Locs.StartLoc; 12409 SourceLocation LParenLoc = Locs.LParenLoc; 12410 SourceLocation EndLoc = Locs.EndLoc; 12411 OMPClause *Res = nullptr; 12412 switch (Kind) { 12413 case OMPC_private: 12414 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12415 break; 12416 case OMPC_firstprivate: 12417 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12418 break; 12419 case OMPC_lastprivate: 12420 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 12421 "Unexpected lastprivate modifier."); 12422 Res = ActOnOpenMPLastprivateClause( 12423 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 12424 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 12425 break; 12426 case OMPC_shared: 12427 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12428 break; 12429 case OMPC_reduction: 12430 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12431 EndLoc, ReductionOrMapperIdScopeSpec, 12432 ReductionOrMapperId); 12433 break; 12434 case OMPC_task_reduction: 12435 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12436 EndLoc, ReductionOrMapperIdScopeSpec, 12437 ReductionOrMapperId); 12438 break; 12439 case OMPC_in_reduction: 12440 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12441 EndLoc, ReductionOrMapperIdScopeSpec, 12442 ReductionOrMapperId); 12443 break; 12444 case OMPC_linear: 12445 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 12446 "Unexpected linear modifier."); 12447 Res = ActOnOpenMPLinearClause( 12448 VarList, TailExpr, StartLoc, LParenLoc, 12449 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc, 12450 ColonLoc, EndLoc); 12451 break; 12452 case OMPC_aligned: 12453 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12454 ColonLoc, EndLoc); 12455 break; 12456 case OMPC_copyin: 12457 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12458 break; 12459 case OMPC_copyprivate: 12460 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12461 break; 12462 case OMPC_flush: 12463 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12464 break; 12465 case OMPC_depend: 12466 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 12467 "Unexpected depend modifier."); 12468 Res = ActOnOpenMPDependClause( 12469 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc, 12470 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 12471 break; 12472 case OMPC_map: 12473 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 12474 "Unexpected map modifier."); 12475 Res = ActOnOpenMPMapClause( 12476 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 12477 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 12478 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs); 12479 break; 12480 case OMPC_to: 12481 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12482 ReductionOrMapperId, Locs); 12483 break; 12484 case OMPC_from: 12485 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12486 ReductionOrMapperId, Locs); 12487 break; 12488 case OMPC_use_device_ptr: 12489 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12490 break; 12491 case OMPC_is_device_ptr: 12492 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12493 break; 12494 case OMPC_allocate: 12495 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12496 ColonLoc, EndLoc); 12497 break; 12498 case OMPC_nontemporal: 12499 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 12500 break; 12501 case OMPC_if: 12502 case OMPC_final: 12503 case OMPC_num_threads: 12504 case OMPC_safelen: 12505 case OMPC_simdlen: 12506 case OMPC_allocator: 12507 case OMPC_collapse: 12508 case OMPC_default: 12509 case OMPC_proc_bind: 12510 case OMPC_schedule: 12511 case OMPC_ordered: 12512 case OMPC_nowait: 12513 case OMPC_untied: 12514 case OMPC_mergeable: 12515 case OMPC_threadprivate: 12516 case OMPC_read: 12517 case OMPC_write: 12518 case OMPC_update: 12519 case OMPC_capture: 12520 case OMPC_seq_cst: 12521 case OMPC_device: 12522 case OMPC_threads: 12523 case OMPC_simd: 12524 case OMPC_num_teams: 12525 case OMPC_thread_limit: 12526 case OMPC_priority: 12527 case OMPC_grainsize: 12528 case OMPC_nogroup: 12529 case OMPC_num_tasks: 12530 case OMPC_hint: 12531 case OMPC_dist_schedule: 12532 case OMPC_defaultmap: 12533 case OMPC_unknown: 12534 case OMPC_uniform: 12535 case OMPC_unified_address: 12536 case OMPC_unified_shared_memory: 12537 case OMPC_reverse_offload: 12538 case OMPC_dynamic_allocators: 12539 case OMPC_atomic_default_mem_order: 12540 case OMPC_device_type: 12541 case OMPC_match: 12542 llvm_unreachable("Clause is not allowed."); 12543 } 12544 return Res; 12545 } 12546 12547 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12548 ExprObjectKind OK, SourceLocation Loc) { 12549 ExprResult Res = BuildDeclRefExpr( 12550 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12551 if (!Res.isUsable()) 12552 return ExprError(); 12553 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12554 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12555 if (!Res.isUsable()) 12556 return ExprError(); 12557 } 12558 if (VK != VK_LValue && Res.get()->isGLValue()) { 12559 Res = DefaultLvalueConversion(Res.get()); 12560 if (!Res.isUsable()) 12561 return ExprError(); 12562 } 12563 return Res; 12564 } 12565 12566 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12567 SourceLocation StartLoc, 12568 SourceLocation LParenLoc, 12569 SourceLocation EndLoc) { 12570 SmallVector<Expr *, 8> Vars; 12571 SmallVector<Expr *, 8> PrivateCopies; 12572 for (Expr *RefExpr : VarList) { 12573 assert(RefExpr && "NULL expr in OpenMP private clause."); 12574 SourceLocation ELoc; 12575 SourceRange ERange; 12576 Expr *SimpleRefExpr = RefExpr; 12577 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12578 if (Res.second) { 12579 // It will be analyzed later. 12580 Vars.push_back(RefExpr); 12581 PrivateCopies.push_back(nullptr); 12582 } 12583 ValueDecl *D = Res.first; 12584 if (!D) 12585 continue; 12586 12587 QualType Type = D->getType(); 12588 auto *VD = dyn_cast<VarDecl>(D); 12589 12590 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12591 // A variable that appears in a private clause must not have an incomplete 12592 // type or a reference type. 12593 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12594 continue; 12595 Type = Type.getNonReferenceType(); 12596 12597 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12598 // A variable that is privatized must not have a const-qualified type 12599 // unless it is of class type with a mutable member. This restriction does 12600 // not apply to the firstprivate clause. 12601 // 12602 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12603 // A variable that appears in a private clause must not have a 12604 // const-qualified type unless it is of class type with a mutable member. 12605 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12606 continue; 12607 12608 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12609 // in a Construct] 12610 // Variables with the predetermined data-sharing attributes may not be 12611 // listed in data-sharing attributes clauses, except for the cases 12612 // listed below. For these exceptions only, listing a predetermined 12613 // variable in a data-sharing attribute clause is allowed and overrides 12614 // the variable's predetermined data-sharing attributes. 12615 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12616 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12617 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12618 << getOpenMPClauseName(OMPC_private); 12619 reportOriginalDsa(*this, DSAStack, D, DVar); 12620 continue; 12621 } 12622 12623 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12624 // Variably modified types are not supported for tasks. 12625 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12626 isOpenMPTaskingDirective(CurrDir)) { 12627 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12628 << getOpenMPClauseName(OMPC_private) << Type 12629 << getOpenMPDirectiveName(CurrDir); 12630 bool IsDecl = 12631 !VD || 12632 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12633 Diag(D->getLocation(), 12634 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12635 << D; 12636 continue; 12637 } 12638 12639 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12640 // A list item cannot appear in both a map clause and a data-sharing 12641 // attribute clause on the same construct 12642 // 12643 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12644 // A list item cannot appear in both a map clause and a data-sharing 12645 // attribute clause on the same construct unless the construct is a 12646 // combined construct. 12647 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12648 CurrDir == OMPD_target) { 12649 OpenMPClauseKind ConflictKind; 12650 if (DSAStack->checkMappableExprComponentListsForDecl( 12651 VD, /*CurrentRegionOnly=*/true, 12652 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12653 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12654 ConflictKind = WhereFoundClauseKind; 12655 return true; 12656 })) { 12657 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12658 << getOpenMPClauseName(OMPC_private) 12659 << getOpenMPClauseName(ConflictKind) 12660 << getOpenMPDirectiveName(CurrDir); 12661 reportOriginalDsa(*this, DSAStack, D, DVar); 12662 continue; 12663 } 12664 } 12665 12666 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12667 // A variable of class type (or array thereof) that appears in a private 12668 // clause requires an accessible, unambiguous default constructor for the 12669 // class type. 12670 // Generate helper private variable and initialize it with the default 12671 // value. The address of the original variable is replaced by the address of 12672 // the new private variable in CodeGen. This new variable is not added to 12673 // IdResolver, so the code in the OpenMP region uses original variable for 12674 // proper diagnostics. 12675 Type = Type.getUnqualifiedType(); 12676 VarDecl *VDPrivate = 12677 buildVarDecl(*this, ELoc, Type, D->getName(), 12678 D->hasAttrs() ? &D->getAttrs() : nullptr, 12679 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12680 ActOnUninitializedDecl(VDPrivate); 12681 if (VDPrivate->isInvalidDecl()) 12682 continue; 12683 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12684 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12685 12686 DeclRefExpr *Ref = nullptr; 12687 if (!VD && !CurContext->isDependentContext()) 12688 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12689 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12690 Vars.push_back((VD || CurContext->isDependentContext()) 12691 ? RefExpr->IgnoreParens() 12692 : Ref); 12693 PrivateCopies.push_back(VDPrivateRefExpr); 12694 } 12695 12696 if (Vars.empty()) 12697 return nullptr; 12698 12699 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12700 PrivateCopies); 12701 } 12702 12703 namespace { 12704 class DiagsUninitializedSeveretyRAII { 12705 private: 12706 DiagnosticsEngine &Diags; 12707 SourceLocation SavedLoc; 12708 bool IsIgnored = false; 12709 12710 public: 12711 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12712 bool IsIgnored) 12713 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12714 if (!IsIgnored) { 12715 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12716 /*Map*/ diag::Severity::Ignored, Loc); 12717 } 12718 } 12719 ~DiagsUninitializedSeveretyRAII() { 12720 if (!IsIgnored) 12721 Diags.popMappings(SavedLoc); 12722 } 12723 }; 12724 } 12725 12726 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12727 SourceLocation StartLoc, 12728 SourceLocation LParenLoc, 12729 SourceLocation EndLoc) { 12730 SmallVector<Expr *, 8> Vars; 12731 SmallVector<Expr *, 8> PrivateCopies; 12732 SmallVector<Expr *, 8> Inits; 12733 SmallVector<Decl *, 4> ExprCaptures; 12734 bool IsImplicitClause = 12735 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12736 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12737 12738 for (Expr *RefExpr : VarList) { 12739 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12740 SourceLocation ELoc; 12741 SourceRange ERange; 12742 Expr *SimpleRefExpr = RefExpr; 12743 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12744 if (Res.second) { 12745 // It will be analyzed later. 12746 Vars.push_back(RefExpr); 12747 PrivateCopies.push_back(nullptr); 12748 Inits.push_back(nullptr); 12749 } 12750 ValueDecl *D = Res.first; 12751 if (!D) 12752 continue; 12753 12754 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12755 QualType Type = D->getType(); 12756 auto *VD = dyn_cast<VarDecl>(D); 12757 12758 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12759 // A variable that appears in a private clause must not have an incomplete 12760 // type or a reference type. 12761 if (RequireCompleteType(ELoc, Type, 12762 diag::err_omp_firstprivate_incomplete_type)) 12763 continue; 12764 Type = Type.getNonReferenceType(); 12765 12766 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12767 // A variable of class type (or array thereof) that appears in a private 12768 // clause requires an accessible, unambiguous copy constructor for the 12769 // class type. 12770 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12771 12772 // If an implicit firstprivate variable found it was checked already. 12773 DSAStackTy::DSAVarData TopDVar; 12774 if (!IsImplicitClause) { 12775 DSAStackTy::DSAVarData DVar = 12776 DSAStack->getTopDSA(D, /*FromParent=*/false); 12777 TopDVar = DVar; 12778 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12779 bool IsConstant = ElemType.isConstant(Context); 12780 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12781 // A list item that specifies a given variable may not appear in more 12782 // than one clause on the same directive, except that a variable may be 12783 // specified in both firstprivate and lastprivate clauses. 12784 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12785 // A list item may appear in a firstprivate or lastprivate clause but not 12786 // both. 12787 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12788 (isOpenMPDistributeDirective(CurrDir) || 12789 DVar.CKind != OMPC_lastprivate) && 12790 DVar.RefExpr) { 12791 Diag(ELoc, diag::err_omp_wrong_dsa) 12792 << getOpenMPClauseName(DVar.CKind) 12793 << getOpenMPClauseName(OMPC_firstprivate); 12794 reportOriginalDsa(*this, DSAStack, D, DVar); 12795 continue; 12796 } 12797 12798 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12799 // in a Construct] 12800 // Variables with the predetermined data-sharing attributes may not be 12801 // listed in data-sharing attributes clauses, except for the cases 12802 // listed below. For these exceptions only, listing a predetermined 12803 // variable in a data-sharing attribute clause is allowed and overrides 12804 // the variable's predetermined data-sharing attributes. 12805 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12806 // in a Construct, C/C++, p.2] 12807 // Variables with const-qualified type having no mutable member may be 12808 // listed in a firstprivate clause, even if they are static data members. 12809 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12810 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12811 Diag(ELoc, diag::err_omp_wrong_dsa) 12812 << getOpenMPClauseName(DVar.CKind) 12813 << getOpenMPClauseName(OMPC_firstprivate); 12814 reportOriginalDsa(*this, DSAStack, D, DVar); 12815 continue; 12816 } 12817 12818 // OpenMP [2.9.3.4, Restrictions, p.2] 12819 // A list item that is private within a parallel region must not appear 12820 // in a firstprivate clause on a worksharing construct if any of the 12821 // worksharing regions arising from the worksharing construct ever bind 12822 // to any of the parallel regions arising from the parallel construct. 12823 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12824 // A list item that is private within a teams region must not appear in a 12825 // firstprivate clause on a distribute construct if any of the distribute 12826 // regions arising from the distribute construct ever bind to any of the 12827 // teams regions arising from the teams construct. 12828 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12829 // A list item that appears in a reduction clause of a teams construct 12830 // must not appear in a firstprivate clause on a distribute construct if 12831 // any of the distribute regions arising from the distribute construct 12832 // ever bind to any of the teams regions arising from the teams construct. 12833 if ((isOpenMPWorksharingDirective(CurrDir) || 12834 isOpenMPDistributeDirective(CurrDir)) && 12835 !isOpenMPParallelDirective(CurrDir) && 12836 !isOpenMPTeamsDirective(CurrDir)) { 12837 DVar = DSAStack->getImplicitDSA(D, true); 12838 if (DVar.CKind != OMPC_shared && 12839 (isOpenMPParallelDirective(DVar.DKind) || 12840 isOpenMPTeamsDirective(DVar.DKind) || 12841 DVar.DKind == OMPD_unknown)) { 12842 Diag(ELoc, diag::err_omp_required_access) 12843 << getOpenMPClauseName(OMPC_firstprivate) 12844 << getOpenMPClauseName(OMPC_shared); 12845 reportOriginalDsa(*this, DSAStack, D, DVar); 12846 continue; 12847 } 12848 } 12849 // OpenMP [2.9.3.4, Restrictions, p.3] 12850 // A list item that appears in a reduction clause of a parallel construct 12851 // must not appear in a firstprivate clause on a worksharing or task 12852 // construct if any of the worksharing or task regions arising from the 12853 // worksharing or task construct ever bind to any of the parallel regions 12854 // arising from the parallel construct. 12855 // OpenMP [2.9.3.4, Restrictions, p.4] 12856 // A list item that appears in a reduction clause in worksharing 12857 // construct must not appear in a firstprivate clause in a task construct 12858 // encountered during execution of any of the worksharing regions arising 12859 // from the worksharing construct. 12860 if (isOpenMPTaskingDirective(CurrDir)) { 12861 DVar = DSAStack->hasInnermostDSA( 12862 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12863 [](OpenMPDirectiveKind K) { 12864 return isOpenMPParallelDirective(K) || 12865 isOpenMPWorksharingDirective(K) || 12866 isOpenMPTeamsDirective(K); 12867 }, 12868 /*FromParent=*/true); 12869 if (DVar.CKind == OMPC_reduction && 12870 (isOpenMPParallelDirective(DVar.DKind) || 12871 isOpenMPWorksharingDirective(DVar.DKind) || 12872 isOpenMPTeamsDirective(DVar.DKind))) { 12873 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12874 << getOpenMPDirectiveName(DVar.DKind); 12875 reportOriginalDsa(*this, DSAStack, D, DVar); 12876 continue; 12877 } 12878 } 12879 12880 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12881 // A list item cannot appear in both a map clause and a data-sharing 12882 // attribute clause on the same construct 12883 // 12884 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12885 // A list item cannot appear in both a map clause and a data-sharing 12886 // attribute clause on the same construct unless the construct is a 12887 // combined construct. 12888 if ((LangOpts.OpenMP <= 45 && 12889 isOpenMPTargetExecutionDirective(CurrDir)) || 12890 CurrDir == OMPD_target) { 12891 OpenMPClauseKind ConflictKind; 12892 if (DSAStack->checkMappableExprComponentListsForDecl( 12893 VD, /*CurrentRegionOnly=*/true, 12894 [&ConflictKind]( 12895 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12896 OpenMPClauseKind WhereFoundClauseKind) { 12897 ConflictKind = WhereFoundClauseKind; 12898 return true; 12899 })) { 12900 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12901 << getOpenMPClauseName(OMPC_firstprivate) 12902 << getOpenMPClauseName(ConflictKind) 12903 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12904 reportOriginalDsa(*this, DSAStack, D, DVar); 12905 continue; 12906 } 12907 } 12908 } 12909 12910 // Variably modified types are not supported for tasks. 12911 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12912 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12913 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12914 << getOpenMPClauseName(OMPC_firstprivate) << Type 12915 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12916 bool IsDecl = 12917 !VD || 12918 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12919 Diag(D->getLocation(), 12920 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12921 << D; 12922 continue; 12923 } 12924 12925 Type = Type.getUnqualifiedType(); 12926 VarDecl *VDPrivate = 12927 buildVarDecl(*this, ELoc, Type, D->getName(), 12928 D->hasAttrs() ? &D->getAttrs() : nullptr, 12929 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12930 // Generate helper private variable and initialize it with the value of the 12931 // original variable. The address of the original variable is replaced by 12932 // the address of the new private variable in the CodeGen. This new variable 12933 // is not added to IdResolver, so the code in the OpenMP region uses 12934 // original variable for proper diagnostics and variable capturing. 12935 Expr *VDInitRefExpr = nullptr; 12936 // For arrays generate initializer for single element and replace it by the 12937 // original array element in CodeGen. 12938 if (Type->isArrayType()) { 12939 VarDecl *VDInit = 12940 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12941 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12942 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12943 ElemType = ElemType.getUnqualifiedType(); 12944 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12945 ".firstprivate.temp"); 12946 InitializedEntity Entity = 12947 InitializedEntity::InitializeVariable(VDInitTemp); 12948 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12949 12950 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12951 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12952 if (Result.isInvalid()) 12953 VDPrivate->setInvalidDecl(); 12954 else 12955 VDPrivate->setInit(Result.getAs<Expr>()); 12956 // Remove temp variable declaration. 12957 Context.Deallocate(VDInitTemp); 12958 } else { 12959 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12960 ".firstprivate.temp"); 12961 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12962 RefExpr->getExprLoc()); 12963 AddInitializerToDecl(VDPrivate, 12964 DefaultLvalueConversion(VDInitRefExpr).get(), 12965 /*DirectInit=*/false); 12966 } 12967 if (VDPrivate->isInvalidDecl()) { 12968 if (IsImplicitClause) { 12969 Diag(RefExpr->getExprLoc(), 12970 diag::note_omp_task_predetermined_firstprivate_here); 12971 } 12972 continue; 12973 } 12974 CurContext->addDecl(VDPrivate); 12975 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12976 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12977 RefExpr->getExprLoc()); 12978 DeclRefExpr *Ref = nullptr; 12979 if (!VD && !CurContext->isDependentContext()) { 12980 if (TopDVar.CKind == OMPC_lastprivate) { 12981 Ref = TopDVar.PrivateCopy; 12982 } else { 12983 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12984 if (!isOpenMPCapturedDecl(D)) 12985 ExprCaptures.push_back(Ref->getDecl()); 12986 } 12987 } 12988 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12989 Vars.push_back((VD || CurContext->isDependentContext()) 12990 ? RefExpr->IgnoreParens() 12991 : Ref); 12992 PrivateCopies.push_back(VDPrivateRefExpr); 12993 Inits.push_back(VDInitRefExpr); 12994 } 12995 12996 if (Vars.empty()) 12997 return nullptr; 12998 12999 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13000 Vars, PrivateCopies, Inits, 13001 buildPreInits(Context, ExprCaptures)); 13002 } 13003 13004 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13005 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13006 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13007 SourceLocation LParenLoc, SourceLocation EndLoc) { 13008 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13009 assert(ColonLoc.isValid() && "Colon location must be valid."); 13010 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13011 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13012 /*Last=*/OMPC_LASTPRIVATE_unknown) 13013 << getOpenMPClauseName(OMPC_lastprivate); 13014 return nullptr; 13015 } 13016 13017 SmallVector<Expr *, 8> Vars; 13018 SmallVector<Expr *, 8> SrcExprs; 13019 SmallVector<Expr *, 8> DstExprs; 13020 SmallVector<Expr *, 8> AssignmentOps; 13021 SmallVector<Decl *, 4> ExprCaptures; 13022 SmallVector<Expr *, 4> ExprPostUpdates; 13023 for (Expr *RefExpr : VarList) { 13024 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13025 SourceLocation ELoc; 13026 SourceRange ERange; 13027 Expr *SimpleRefExpr = RefExpr; 13028 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13029 if (Res.second) { 13030 // It will be analyzed later. 13031 Vars.push_back(RefExpr); 13032 SrcExprs.push_back(nullptr); 13033 DstExprs.push_back(nullptr); 13034 AssignmentOps.push_back(nullptr); 13035 } 13036 ValueDecl *D = Res.first; 13037 if (!D) 13038 continue; 13039 13040 QualType Type = D->getType(); 13041 auto *VD = dyn_cast<VarDecl>(D); 13042 13043 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13044 // A variable that appears in a lastprivate clause must not have an 13045 // incomplete type or a reference type. 13046 if (RequireCompleteType(ELoc, Type, 13047 diag::err_omp_lastprivate_incomplete_type)) 13048 continue; 13049 Type = Type.getNonReferenceType(); 13050 13051 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13052 // A variable that is privatized must not have a const-qualified type 13053 // unless it is of class type with a mutable member. This restriction does 13054 // not apply to the firstprivate clause. 13055 // 13056 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13057 // A variable that appears in a lastprivate clause must not have a 13058 // const-qualified type unless it is of class type with a mutable member. 13059 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13060 continue; 13061 13062 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13063 // A list item that appears in a lastprivate clause with the conditional 13064 // modifier must be a scalar variable. 13065 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13066 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13067 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13068 VarDecl::DeclarationOnly; 13069 Diag(D->getLocation(), 13070 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13071 << D; 13072 continue; 13073 } 13074 13075 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13076 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13077 // in a Construct] 13078 // Variables with the predetermined data-sharing attributes may not be 13079 // listed in data-sharing attributes clauses, except for the cases 13080 // listed below. 13081 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13082 // A list item may appear in a firstprivate or lastprivate clause but not 13083 // both. 13084 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13085 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13086 (isOpenMPDistributeDirective(CurrDir) || 13087 DVar.CKind != OMPC_firstprivate) && 13088 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13089 Diag(ELoc, diag::err_omp_wrong_dsa) 13090 << getOpenMPClauseName(DVar.CKind) 13091 << getOpenMPClauseName(OMPC_lastprivate); 13092 reportOriginalDsa(*this, DSAStack, D, DVar); 13093 continue; 13094 } 13095 13096 // OpenMP [2.14.3.5, Restrictions, p.2] 13097 // A list item that is private within a parallel region, or that appears in 13098 // the reduction clause of a parallel construct, must not appear in a 13099 // lastprivate clause on a worksharing construct if any of the corresponding 13100 // worksharing regions ever binds to any of the corresponding parallel 13101 // regions. 13102 DSAStackTy::DSAVarData TopDVar = DVar; 13103 if (isOpenMPWorksharingDirective(CurrDir) && 13104 !isOpenMPParallelDirective(CurrDir) && 13105 !isOpenMPTeamsDirective(CurrDir)) { 13106 DVar = DSAStack->getImplicitDSA(D, true); 13107 if (DVar.CKind != OMPC_shared) { 13108 Diag(ELoc, diag::err_omp_required_access) 13109 << getOpenMPClauseName(OMPC_lastprivate) 13110 << getOpenMPClauseName(OMPC_shared); 13111 reportOriginalDsa(*this, DSAStack, D, DVar); 13112 continue; 13113 } 13114 } 13115 13116 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13117 // A variable of class type (or array thereof) that appears in a 13118 // lastprivate clause requires an accessible, unambiguous default 13119 // constructor for the class type, unless the list item is also specified 13120 // in a firstprivate clause. 13121 // A variable of class type (or array thereof) that appears in a 13122 // lastprivate clause requires an accessible, unambiguous copy assignment 13123 // operator for the class type. 13124 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13125 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13126 Type.getUnqualifiedType(), ".lastprivate.src", 13127 D->hasAttrs() ? &D->getAttrs() : nullptr); 13128 DeclRefExpr *PseudoSrcExpr = 13129 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13130 VarDecl *DstVD = 13131 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13132 D->hasAttrs() ? &D->getAttrs() : nullptr); 13133 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13134 // For arrays generate assignment operation for single element and replace 13135 // it by the original array element in CodeGen. 13136 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13137 PseudoDstExpr, PseudoSrcExpr); 13138 if (AssignmentOp.isInvalid()) 13139 continue; 13140 AssignmentOp = 13141 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13142 if (AssignmentOp.isInvalid()) 13143 continue; 13144 13145 DeclRefExpr *Ref = nullptr; 13146 if (!VD && !CurContext->isDependentContext()) { 13147 if (TopDVar.CKind == OMPC_firstprivate) { 13148 Ref = TopDVar.PrivateCopy; 13149 } else { 13150 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13151 if (!isOpenMPCapturedDecl(D)) 13152 ExprCaptures.push_back(Ref->getDecl()); 13153 } 13154 if (TopDVar.CKind == OMPC_firstprivate || 13155 (!isOpenMPCapturedDecl(D) && 13156 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13157 ExprResult RefRes = DefaultLvalueConversion(Ref); 13158 if (!RefRes.isUsable()) 13159 continue; 13160 ExprResult PostUpdateRes = 13161 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13162 RefRes.get()); 13163 if (!PostUpdateRes.isUsable()) 13164 continue; 13165 ExprPostUpdates.push_back( 13166 IgnoredValueConversions(PostUpdateRes.get()).get()); 13167 } 13168 } 13169 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13170 Vars.push_back((VD || CurContext->isDependentContext()) 13171 ? RefExpr->IgnoreParens() 13172 : Ref); 13173 SrcExprs.push_back(PseudoSrcExpr); 13174 DstExprs.push_back(PseudoDstExpr); 13175 AssignmentOps.push_back(AssignmentOp.get()); 13176 } 13177 13178 if (Vars.empty()) 13179 return nullptr; 13180 13181 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13182 Vars, SrcExprs, DstExprs, AssignmentOps, 13183 LPKind, LPKindLoc, ColonLoc, 13184 buildPreInits(Context, ExprCaptures), 13185 buildPostUpdate(*this, ExprPostUpdates)); 13186 } 13187 13188 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13189 SourceLocation StartLoc, 13190 SourceLocation LParenLoc, 13191 SourceLocation EndLoc) { 13192 SmallVector<Expr *, 8> Vars; 13193 for (Expr *RefExpr : VarList) { 13194 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13195 SourceLocation ELoc; 13196 SourceRange ERange; 13197 Expr *SimpleRefExpr = RefExpr; 13198 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13199 if (Res.second) { 13200 // It will be analyzed later. 13201 Vars.push_back(RefExpr); 13202 } 13203 ValueDecl *D = Res.first; 13204 if (!D) 13205 continue; 13206 13207 auto *VD = dyn_cast<VarDecl>(D); 13208 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13209 // in a Construct] 13210 // Variables with the predetermined data-sharing attributes may not be 13211 // listed in data-sharing attributes clauses, except for the cases 13212 // listed below. For these exceptions only, listing a predetermined 13213 // variable in a data-sharing attribute clause is allowed and overrides 13214 // the variable's predetermined data-sharing attributes. 13215 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13216 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13217 DVar.RefExpr) { 13218 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13219 << getOpenMPClauseName(OMPC_shared); 13220 reportOriginalDsa(*this, DSAStack, D, DVar); 13221 continue; 13222 } 13223 13224 DeclRefExpr *Ref = nullptr; 13225 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13226 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13227 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13228 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13229 ? RefExpr->IgnoreParens() 13230 : Ref); 13231 } 13232 13233 if (Vars.empty()) 13234 return nullptr; 13235 13236 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13237 } 13238 13239 namespace { 13240 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13241 DSAStackTy *Stack; 13242 13243 public: 13244 bool VisitDeclRefExpr(DeclRefExpr *E) { 13245 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13246 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13247 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13248 return false; 13249 if (DVar.CKind != OMPC_unknown) 13250 return true; 13251 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13252 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13253 /*FromParent=*/true); 13254 return DVarPrivate.CKind != OMPC_unknown; 13255 } 13256 return false; 13257 } 13258 bool VisitStmt(Stmt *S) { 13259 for (Stmt *Child : S->children()) { 13260 if (Child && Visit(Child)) 13261 return true; 13262 } 13263 return false; 13264 } 13265 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13266 }; 13267 } // namespace 13268 13269 namespace { 13270 // Transform MemberExpression for specified FieldDecl of current class to 13271 // DeclRefExpr to specified OMPCapturedExprDecl. 13272 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13273 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13274 ValueDecl *Field = nullptr; 13275 DeclRefExpr *CapturedExpr = nullptr; 13276 13277 public: 13278 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13279 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13280 13281 ExprResult TransformMemberExpr(MemberExpr *E) { 13282 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13283 E->getMemberDecl() == Field) { 13284 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13285 return CapturedExpr; 13286 } 13287 return BaseTransform::TransformMemberExpr(E); 13288 } 13289 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13290 }; 13291 } // namespace 13292 13293 template <typename T, typename U> 13294 static T filterLookupForUDReductionAndMapper( 13295 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13296 for (U &Set : Lookups) { 13297 for (auto *D : Set) { 13298 if (T Res = Gen(cast<ValueDecl>(D))) 13299 return Res; 13300 } 13301 } 13302 return T(); 13303 } 13304 13305 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13306 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13307 13308 for (auto RD : D->redecls()) { 13309 // Don't bother with extra checks if we already know this one isn't visible. 13310 if (RD == D) 13311 continue; 13312 13313 auto ND = cast<NamedDecl>(RD); 13314 if (LookupResult::isVisible(SemaRef, ND)) 13315 return ND; 13316 } 13317 13318 return nullptr; 13319 } 13320 13321 static void 13322 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13323 SourceLocation Loc, QualType Ty, 13324 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13325 // Find all of the associated namespaces and classes based on the 13326 // arguments we have. 13327 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13328 Sema::AssociatedClassSet AssociatedClasses; 13329 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13330 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13331 AssociatedClasses); 13332 13333 // C++ [basic.lookup.argdep]p3: 13334 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13335 // and let Y be the lookup set produced by argument dependent 13336 // lookup (defined as follows). If X contains [...] then Y is 13337 // empty. Otherwise Y is the set of declarations found in the 13338 // namespaces associated with the argument types as described 13339 // below. The set of declarations found by the lookup of the name 13340 // is the union of X and Y. 13341 // 13342 // Here, we compute Y and add its members to the overloaded 13343 // candidate set. 13344 for (auto *NS : AssociatedNamespaces) { 13345 // When considering an associated namespace, the lookup is the 13346 // same as the lookup performed when the associated namespace is 13347 // used as a qualifier (3.4.3.2) except that: 13348 // 13349 // -- Any using-directives in the associated namespace are 13350 // ignored. 13351 // 13352 // -- Any namespace-scope friend functions declared in 13353 // associated classes are visible within their respective 13354 // namespaces even if they are not visible during an ordinary 13355 // lookup (11.4). 13356 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13357 for (auto *D : R) { 13358 auto *Underlying = D; 13359 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13360 Underlying = USD->getTargetDecl(); 13361 13362 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13363 !isa<OMPDeclareMapperDecl>(Underlying)) 13364 continue; 13365 13366 if (!SemaRef.isVisible(D)) { 13367 D = findAcceptableDecl(SemaRef, D); 13368 if (!D) 13369 continue; 13370 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13371 Underlying = USD->getTargetDecl(); 13372 } 13373 Lookups.emplace_back(); 13374 Lookups.back().addDecl(Underlying); 13375 } 13376 } 13377 } 13378 13379 static ExprResult 13380 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13381 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13382 const DeclarationNameInfo &ReductionId, QualType Ty, 13383 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13384 if (ReductionIdScopeSpec.isInvalid()) 13385 return ExprError(); 13386 SmallVector<UnresolvedSet<8>, 4> Lookups; 13387 if (S) { 13388 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13389 Lookup.suppressDiagnostics(); 13390 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13391 NamedDecl *D = Lookup.getRepresentativeDecl(); 13392 do { 13393 S = S->getParent(); 13394 } while (S && !S->isDeclScope(D)); 13395 if (S) 13396 S = S->getParent(); 13397 Lookups.emplace_back(); 13398 Lookups.back().append(Lookup.begin(), Lookup.end()); 13399 Lookup.clear(); 13400 } 13401 } else if (auto *ULE = 13402 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13403 Lookups.push_back(UnresolvedSet<8>()); 13404 Decl *PrevD = nullptr; 13405 for (NamedDecl *D : ULE->decls()) { 13406 if (D == PrevD) 13407 Lookups.push_back(UnresolvedSet<8>()); 13408 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13409 Lookups.back().addDecl(DRD); 13410 PrevD = D; 13411 } 13412 } 13413 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13414 Ty->isInstantiationDependentType() || 13415 Ty->containsUnexpandedParameterPack() || 13416 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13417 return !D->isInvalidDecl() && 13418 (D->getType()->isDependentType() || 13419 D->getType()->isInstantiationDependentType() || 13420 D->getType()->containsUnexpandedParameterPack()); 13421 })) { 13422 UnresolvedSet<8> ResSet; 13423 for (const UnresolvedSet<8> &Set : Lookups) { 13424 if (Set.empty()) 13425 continue; 13426 ResSet.append(Set.begin(), Set.end()); 13427 // The last item marks the end of all declarations at the specified scope. 13428 ResSet.addDecl(Set[Set.size() - 1]); 13429 } 13430 return UnresolvedLookupExpr::Create( 13431 SemaRef.Context, /*NamingClass=*/nullptr, 13432 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13433 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13434 } 13435 // Lookup inside the classes. 13436 // C++ [over.match.oper]p3: 13437 // For a unary operator @ with an operand of a type whose 13438 // cv-unqualified version is T1, and for a binary operator @ with 13439 // a left operand of a type whose cv-unqualified version is T1 and 13440 // a right operand of a type whose cv-unqualified version is T2, 13441 // three sets of candidate functions, designated member 13442 // candidates, non-member candidates and built-in candidates, are 13443 // constructed as follows: 13444 // -- If T1 is a complete class type or a class currently being 13445 // defined, the set of member candidates is the result of the 13446 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13447 // the set of member candidates is empty. 13448 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13449 Lookup.suppressDiagnostics(); 13450 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13451 // Complete the type if it can be completed. 13452 // If the type is neither complete nor being defined, bail out now. 13453 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13454 TyRec->getDecl()->getDefinition()) { 13455 Lookup.clear(); 13456 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13457 if (Lookup.empty()) { 13458 Lookups.emplace_back(); 13459 Lookups.back().append(Lookup.begin(), Lookup.end()); 13460 } 13461 } 13462 } 13463 // Perform ADL. 13464 if (SemaRef.getLangOpts().CPlusPlus) 13465 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13466 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13467 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13468 if (!D->isInvalidDecl() && 13469 SemaRef.Context.hasSameType(D->getType(), Ty)) 13470 return D; 13471 return nullptr; 13472 })) 13473 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13474 VK_LValue, Loc); 13475 if (SemaRef.getLangOpts().CPlusPlus) { 13476 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13477 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13478 if (!D->isInvalidDecl() && 13479 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13480 !Ty.isMoreQualifiedThan(D->getType())) 13481 return D; 13482 return nullptr; 13483 })) { 13484 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13485 /*DetectVirtual=*/false); 13486 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13487 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13488 VD->getType().getUnqualifiedType()))) { 13489 if (SemaRef.CheckBaseClassAccess( 13490 Loc, VD->getType(), Ty, Paths.front(), 13491 /*DiagID=*/0) != Sema::AR_inaccessible) { 13492 SemaRef.BuildBasePathArray(Paths, BasePath); 13493 return SemaRef.BuildDeclRefExpr( 13494 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13495 } 13496 } 13497 } 13498 } 13499 } 13500 if (ReductionIdScopeSpec.isSet()) { 13501 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 13502 << Ty << Range; 13503 return ExprError(); 13504 } 13505 return ExprEmpty(); 13506 } 13507 13508 namespace { 13509 /// Data for the reduction-based clauses. 13510 struct ReductionData { 13511 /// List of original reduction items. 13512 SmallVector<Expr *, 8> Vars; 13513 /// List of private copies of the reduction items. 13514 SmallVector<Expr *, 8> Privates; 13515 /// LHS expressions for the reduction_op expressions. 13516 SmallVector<Expr *, 8> LHSs; 13517 /// RHS expressions for the reduction_op expressions. 13518 SmallVector<Expr *, 8> RHSs; 13519 /// Reduction operation expression. 13520 SmallVector<Expr *, 8> ReductionOps; 13521 /// Taskgroup descriptors for the corresponding reduction items in 13522 /// in_reduction clauses. 13523 SmallVector<Expr *, 8> TaskgroupDescriptors; 13524 /// List of captures for clause. 13525 SmallVector<Decl *, 4> ExprCaptures; 13526 /// List of postupdate expressions. 13527 SmallVector<Expr *, 4> ExprPostUpdates; 13528 ReductionData() = delete; 13529 /// Reserves required memory for the reduction data. 13530 ReductionData(unsigned Size) { 13531 Vars.reserve(Size); 13532 Privates.reserve(Size); 13533 LHSs.reserve(Size); 13534 RHSs.reserve(Size); 13535 ReductionOps.reserve(Size); 13536 TaskgroupDescriptors.reserve(Size); 13537 ExprCaptures.reserve(Size); 13538 ExprPostUpdates.reserve(Size); 13539 } 13540 /// Stores reduction item and reduction operation only (required for dependent 13541 /// reduction item). 13542 void push(Expr *Item, Expr *ReductionOp) { 13543 Vars.emplace_back(Item); 13544 Privates.emplace_back(nullptr); 13545 LHSs.emplace_back(nullptr); 13546 RHSs.emplace_back(nullptr); 13547 ReductionOps.emplace_back(ReductionOp); 13548 TaskgroupDescriptors.emplace_back(nullptr); 13549 } 13550 /// Stores reduction data. 13551 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13552 Expr *TaskgroupDescriptor) { 13553 Vars.emplace_back(Item); 13554 Privates.emplace_back(Private); 13555 LHSs.emplace_back(LHS); 13556 RHSs.emplace_back(RHS); 13557 ReductionOps.emplace_back(ReductionOp); 13558 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13559 } 13560 }; 13561 } // namespace 13562 13563 static bool checkOMPArraySectionConstantForReduction( 13564 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13565 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13566 const Expr *Length = OASE->getLength(); 13567 if (Length == nullptr) { 13568 // For array sections of the form [1:] or [:], we would need to analyze 13569 // the lower bound... 13570 if (OASE->getColonLoc().isValid()) 13571 return false; 13572 13573 // This is an array subscript which has implicit length 1! 13574 SingleElement = true; 13575 ArraySizes.push_back(llvm::APSInt::get(1)); 13576 } else { 13577 Expr::EvalResult Result; 13578 if (!Length->EvaluateAsInt(Result, Context)) 13579 return false; 13580 13581 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13582 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13583 ArraySizes.push_back(ConstantLengthValue); 13584 } 13585 13586 // Get the base of this array section and walk up from there. 13587 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13588 13589 // We require length = 1 for all array sections except the right-most to 13590 // guarantee that the memory region is contiguous and has no holes in it. 13591 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13592 Length = TempOASE->getLength(); 13593 if (Length == nullptr) { 13594 // For array sections of the form [1:] or [:], we would need to analyze 13595 // the lower bound... 13596 if (OASE->getColonLoc().isValid()) 13597 return false; 13598 13599 // This is an array subscript which has implicit length 1! 13600 ArraySizes.push_back(llvm::APSInt::get(1)); 13601 } else { 13602 Expr::EvalResult Result; 13603 if (!Length->EvaluateAsInt(Result, Context)) 13604 return false; 13605 13606 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13607 if (ConstantLengthValue.getSExtValue() != 1) 13608 return false; 13609 13610 ArraySizes.push_back(ConstantLengthValue); 13611 } 13612 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13613 } 13614 13615 // If we have a single element, we don't need to add the implicit lengths. 13616 if (!SingleElement) { 13617 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13618 // Has implicit length 1! 13619 ArraySizes.push_back(llvm::APSInt::get(1)); 13620 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13621 } 13622 } 13623 13624 // This array section can be privatized as a single value or as a constant 13625 // sized array. 13626 return true; 13627 } 13628 13629 static bool actOnOMPReductionKindClause( 13630 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13631 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13632 SourceLocation ColonLoc, SourceLocation EndLoc, 13633 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13634 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13635 DeclarationName DN = ReductionId.getName(); 13636 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13637 BinaryOperatorKind BOK = BO_Comma; 13638 13639 ASTContext &Context = S.Context; 13640 // OpenMP [2.14.3.6, reduction clause] 13641 // C 13642 // reduction-identifier is either an identifier or one of the following 13643 // operators: +, -, *, &, |, ^, && and || 13644 // C++ 13645 // reduction-identifier is either an id-expression or one of the following 13646 // operators: +, -, *, &, |, ^, && and || 13647 switch (OOK) { 13648 case OO_Plus: 13649 case OO_Minus: 13650 BOK = BO_Add; 13651 break; 13652 case OO_Star: 13653 BOK = BO_Mul; 13654 break; 13655 case OO_Amp: 13656 BOK = BO_And; 13657 break; 13658 case OO_Pipe: 13659 BOK = BO_Or; 13660 break; 13661 case OO_Caret: 13662 BOK = BO_Xor; 13663 break; 13664 case OO_AmpAmp: 13665 BOK = BO_LAnd; 13666 break; 13667 case OO_PipePipe: 13668 BOK = BO_LOr; 13669 break; 13670 case OO_New: 13671 case OO_Delete: 13672 case OO_Array_New: 13673 case OO_Array_Delete: 13674 case OO_Slash: 13675 case OO_Percent: 13676 case OO_Tilde: 13677 case OO_Exclaim: 13678 case OO_Equal: 13679 case OO_Less: 13680 case OO_Greater: 13681 case OO_LessEqual: 13682 case OO_GreaterEqual: 13683 case OO_PlusEqual: 13684 case OO_MinusEqual: 13685 case OO_StarEqual: 13686 case OO_SlashEqual: 13687 case OO_PercentEqual: 13688 case OO_CaretEqual: 13689 case OO_AmpEqual: 13690 case OO_PipeEqual: 13691 case OO_LessLess: 13692 case OO_GreaterGreater: 13693 case OO_LessLessEqual: 13694 case OO_GreaterGreaterEqual: 13695 case OO_EqualEqual: 13696 case OO_ExclaimEqual: 13697 case OO_Spaceship: 13698 case OO_PlusPlus: 13699 case OO_MinusMinus: 13700 case OO_Comma: 13701 case OO_ArrowStar: 13702 case OO_Arrow: 13703 case OO_Call: 13704 case OO_Subscript: 13705 case OO_Conditional: 13706 case OO_Coawait: 13707 case NUM_OVERLOADED_OPERATORS: 13708 llvm_unreachable("Unexpected reduction identifier"); 13709 case OO_None: 13710 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13711 if (II->isStr("max")) 13712 BOK = BO_GT; 13713 else if (II->isStr("min")) 13714 BOK = BO_LT; 13715 } 13716 break; 13717 } 13718 SourceRange ReductionIdRange; 13719 if (ReductionIdScopeSpec.isValid()) 13720 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13721 else 13722 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13723 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13724 13725 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13726 bool FirstIter = true; 13727 for (Expr *RefExpr : VarList) { 13728 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13729 // OpenMP [2.1, C/C++] 13730 // A list item is a variable or array section, subject to the restrictions 13731 // specified in Section 2.4 on page 42 and in each of the sections 13732 // describing clauses and directives for which a list appears. 13733 // OpenMP [2.14.3.3, Restrictions, p.1] 13734 // A variable that is part of another variable (as an array or 13735 // structure element) cannot appear in a private clause. 13736 if (!FirstIter && IR != ER) 13737 ++IR; 13738 FirstIter = false; 13739 SourceLocation ELoc; 13740 SourceRange ERange; 13741 Expr *SimpleRefExpr = RefExpr; 13742 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13743 /*AllowArraySection=*/true); 13744 if (Res.second) { 13745 // Try to find 'declare reduction' corresponding construct before using 13746 // builtin/overloaded operators. 13747 QualType Type = Context.DependentTy; 13748 CXXCastPath BasePath; 13749 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13750 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13751 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13752 Expr *ReductionOp = nullptr; 13753 if (S.CurContext->isDependentContext() && 13754 (DeclareReductionRef.isUnset() || 13755 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13756 ReductionOp = DeclareReductionRef.get(); 13757 // It will be analyzed later. 13758 RD.push(RefExpr, ReductionOp); 13759 } 13760 ValueDecl *D = Res.first; 13761 if (!D) 13762 continue; 13763 13764 Expr *TaskgroupDescriptor = nullptr; 13765 QualType Type; 13766 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13767 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13768 if (ASE) { 13769 Type = ASE->getType().getNonReferenceType(); 13770 } else if (OASE) { 13771 QualType BaseType = 13772 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13773 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13774 Type = ATy->getElementType(); 13775 else 13776 Type = BaseType->getPointeeType(); 13777 Type = Type.getNonReferenceType(); 13778 } else { 13779 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13780 } 13781 auto *VD = dyn_cast<VarDecl>(D); 13782 13783 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13784 // A variable that appears in a private clause must not have an incomplete 13785 // type or a reference type. 13786 if (S.RequireCompleteType(ELoc, D->getType(), 13787 diag::err_omp_reduction_incomplete_type)) 13788 continue; 13789 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13790 // A list item that appears in a reduction clause must not be 13791 // const-qualified. 13792 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13793 /*AcceptIfMutable*/ false, ASE || OASE)) 13794 continue; 13795 13796 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13797 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13798 // If a list-item is a reference type then it must bind to the same object 13799 // for all threads of the team. 13800 if (!ASE && !OASE) { 13801 if (VD) { 13802 VarDecl *VDDef = VD->getDefinition(); 13803 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13804 DSARefChecker Check(Stack); 13805 if (Check.Visit(VDDef->getInit())) { 13806 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13807 << getOpenMPClauseName(ClauseKind) << ERange; 13808 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13809 continue; 13810 } 13811 } 13812 } 13813 13814 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13815 // in a Construct] 13816 // Variables with the predetermined data-sharing attributes may not be 13817 // listed in data-sharing attributes clauses, except for the cases 13818 // listed below. For these exceptions only, listing a predetermined 13819 // variable in a data-sharing attribute clause is allowed and overrides 13820 // the variable's predetermined data-sharing attributes. 13821 // OpenMP [2.14.3.6, Restrictions, p.3] 13822 // Any number of reduction clauses can be specified on the directive, 13823 // but a list item can appear only once in the reduction clauses for that 13824 // directive. 13825 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13826 if (DVar.CKind == OMPC_reduction) { 13827 S.Diag(ELoc, diag::err_omp_once_referenced) 13828 << getOpenMPClauseName(ClauseKind); 13829 if (DVar.RefExpr) 13830 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13831 continue; 13832 } 13833 if (DVar.CKind != OMPC_unknown) { 13834 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13835 << getOpenMPClauseName(DVar.CKind) 13836 << getOpenMPClauseName(OMPC_reduction); 13837 reportOriginalDsa(S, Stack, D, DVar); 13838 continue; 13839 } 13840 13841 // OpenMP [2.14.3.6, Restrictions, p.1] 13842 // A list item that appears in a reduction clause of a worksharing 13843 // construct must be shared in the parallel regions to which any of the 13844 // worksharing regions arising from the worksharing construct bind. 13845 if (isOpenMPWorksharingDirective(CurrDir) && 13846 !isOpenMPParallelDirective(CurrDir) && 13847 !isOpenMPTeamsDirective(CurrDir)) { 13848 DVar = Stack->getImplicitDSA(D, true); 13849 if (DVar.CKind != OMPC_shared) { 13850 S.Diag(ELoc, diag::err_omp_required_access) 13851 << getOpenMPClauseName(OMPC_reduction) 13852 << getOpenMPClauseName(OMPC_shared); 13853 reportOriginalDsa(S, Stack, D, DVar); 13854 continue; 13855 } 13856 } 13857 } 13858 13859 // Try to find 'declare reduction' corresponding construct before using 13860 // builtin/overloaded operators. 13861 CXXCastPath BasePath; 13862 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13863 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13864 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13865 if (DeclareReductionRef.isInvalid()) 13866 continue; 13867 if (S.CurContext->isDependentContext() && 13868 (DeclareReductionRef.isUnset() || 13869 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13870 RD.push(RefExpr, DeclareReductionRef.get()); 13871 continue; 13872 } 13873 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13874 // Not allowed reduction identifier is found. 13875 S.Diag(ReductionId.getBeginLoc(), 13876 diag::err_omp_unknown_reduction_identifier) 13877 << Type << ReductionIdRange; 13878 continue; 13879 } 13880 13881 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13882 // The type of a list item that appears in a reduction clause must be valid 13883 // for the reduction-identifier. For a max or min reduction in C, the type 13884 // of the list item must be an allowed arithmetic data type: char, int, 13885 // float, double, or _Bool, possibly modified with long, short, signed, or 13886 // unsigned. For a max or min reduction in C++, the type of the list item 13887 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13888 // double, or bool, possibly modified with long, short, signed, or unsigned. 13889 if (DeclareReductionRef.isUnset()) { 13890 if ((BOK == BO_GT || BOK == BO_LT) && 13891 !(Type->isScalarType() || 13892 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13893 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13894 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13895 if (!ASE && !OASE) { 13896 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13897 VarDecl::DeclarationOnly; 13898 S.Diag(D->getLocation(), 13899 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13900 << D; 13901 } 13902 continue; 13903 } 13904 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13905 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13906 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13907 << getOpenMPClauseName(ClauseKind); 13908 if (!ASE && !OASE) { 13909 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13910 VarDecl::DeclarationOnly; 13911 S.Diag(D->getLocation(), 13912 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13913 << D; 13914 } 13915 continue; 13916 } 13917 } 13918 13919 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13920 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13921 D->hasAttrs() ? &D->getAttrs() : nullptr); 13922 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13923 D->hasAttrs() ? &D->getAttrs() : nullptr); 13924 QualType PrivateTy = Type; 13925 13926 // Try if we can determine constant lengths for all array sections and avoid 13927 // the VLA. 13928 bool ConstantLengthOASE = false; 13929 if (OASE) { 13930 bool SingleElement; 13931 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13932 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13933 Context, OASE, SingleElement, ArraySizes); 13934 13935 // If we don't have a single element, we must emit a constant array type. 13936 if (ConstantLengthOASE && !SingleElement) { 13937 for (llvm::APSInt &Size : ArraySizes) 13938 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13939 ArrayType::Normal, 13940 /*IndexTypeQuals=*/0); 13941 } 13942 } 13943 13944 if ((OASE && !ConstantLengthOASE) || 13945 (!OASE && !ASE && 13946 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13947 if (!Context.getTargetInfo().isVLASupported()) { 13948 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13949 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13950 S.Diag(ELoc, diag::note_vla_unsupported); 13951 } else { 13952 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13953 S.targetDiag(ELoc, diag::note_vla_unsupported); 13954 } 13955 continue; 13956 } 13957 // For arrays/array sections only: 13958 // Create pseudo array type for private copy. The size for this array will 13959 // be generated during codegen. 13960 // For array subscripts or single variables Private Ty is the same as Type 13961 // (type of the variable or single array element). 13962 PrivateTy = Context.getVariableArrayType( 13963 Type, 13964 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13965 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13966 } else if (!ASE && !OASE && 13967 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13968 PrivateTy = D->getType().getNonReferenceType(); 13969 } 13970 // Private copy. 13971 VarDecl *PrivateVD = 13972 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13973 D->hasAttrs() ? &D->getAttrs() : nullptr, 13974 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13975 // Add initializer for private variable. 13976 Expr *Init = nullptr; 13977 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13978 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13979 if (DeclareReductionRef.isUsable()) { 13980 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13981 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13982 if (DRD->getInitializer()) { 13983 Init = DRDRef; 13984 RHSVD->setInit(DRDRef); 13985 RHSVD->setInitStyle(VarDecl::CallInit); 13986 } 13987 } else { 13988 switch (BOK) { 13989 case BO_Add: 13990 case BO_Xor: 13991 case BO_Or: 13992 case BO_LOr: 13993 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13994 if (Type->isScalarType() || Type->isAnyComplexType()) 13995 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13996 break; 13997 case BO_Mul: 13998 case BO_LAnd: 13999 if (Type->isScalarType() || Type->isAnyComplexType()) { 14000 // '*' and '&&' reduction ops - initializer is '1'. 14001 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14002 } 14003 break; 14004 case BO_And: { 14005 // '&' reduction op - initializer is '~0'. 14006 QualType OrigType = Type; 14007 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14008 Type = ComplexTy->getElementType(); 14009 if (Type->isRealFloatingType()) { 14010 llvm::APFloat InitValue = 14011 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14012 /*isIEEE=*/true); 14013 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14014 Type, ELoc); 14015 } else if (Type->isScalarType()) { 14016 uint64_t Size = Context.getTypeSize(Type); 14017 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14018 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14019 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14020 } 14021 if (Init && OrigType->isAnyComplexType()) { 14022 // Init = 0xFFFF + 0xFFFFi; 14023 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14024 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14025 } 14026 Type = OrigType; 14027 break; 14028 } 14029 case BO_LT: 14030 case BO_GT: { 14031 // 'min' reduction op - initializer is 'Largest representable number in 14032 // the reduction list item type'. 14033 // 'max' reduction op - initializer is 'Least representable number in 14034 // the reduction list item type'. 14035 if (Type->isIntegerType() || Type->isPointerType()) { 14036 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14037 uint64_t Size = Context.getTypeSize(Type); 14038 QualType IntTy = 14039 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14040 llvm::APInt InitValue = 14041 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14042 : llvm::APInt::getMinValue(Size) 14043 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14044 : llvm::APInt::getMaxValue(Size); 14045 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14046 if (Type->isPointerType()) { 14047 // Cast to pointer type. 14048 ExprResult CastExpr = S.BuildCStyleCastExpr( 14049 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14050 if (CastExpr.isInvalid()) 14051 continue; 14052 Init = CastExpr.get(); 14053 } 14054 } else if (Type->isRealFloatingType()) { 14055 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14056 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14057 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14058 Type, ELoc); 14059 } 14060 break; 14061 } 14062 case BO_PtrMemD: 14063 case BO_PtrMemI: 14064 case BO_MulAssign: 14065 case BO_Div: 14066 case BO_Rem: 14067 case BO_Sub: 14068 case BO_Shl: 14069 case BO_Shr: 14070 case BO_LE: 14071 case BO_GE: 14072 case BO_EQ: 14073 case BO_NE: 14074 case BO_Cmp: 14075 case BO_AndAssign: 14076 case BO_XorAssign: 14077 case BO_OrAssign: 14078 case BO_Assign: 14079 case BO_AddAssign: 14080 case BO_SubAssign: 14081 case BO_DivAssign: 14082 case BO_RemAssign: 14083 case BO_ShlAssign: 14084 case BO_ShrAssign: 14085 case BO_Comma: 14086 llvm_unreachable("Unexpected reduction operation"); 14087 } 14088 } 14089 if (Init && DeclareReductionRef.isUnset()) 14090 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14091 else if (!Init) 14092 S.ActOnUninitializedDecl(RHSVD); 14093 if (RHSVD->isInvalidDecl()) 14094 continue; 14095 if (!RHSVD->hasInit() && 14096 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14097 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14098 << Type << ReductionIdRange; 14099 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14100 VarDecl::DeclarationOnly; 14101 S.Diag(D->getLocation(), 14102 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14103 << D; 14104 continue; 14105 } 14106 // Store initializer for single element in private copy. Will be used during 14107 // codegen. 14108 PrivateVD->setInit(RHSVD->getInit()); 14109 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14110 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14111 ExprResult ReductionOp; 14112 if (DeclareReductionRef.isUsable()) { 14113 QualType RedTy = DeclareReductionRef.get()->getType(); 14114 QualType PtrRedTy = Context.getPointerType(RedTy); 14115 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14116 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14117 if (!BasePath.empty()) { 14118 LHS = S.DefaultLvalueConversion(LHS.get()); 14119 RHS = S.DefaultLvalueConversion(RHS.get()); 14120 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14121 CK_UncheckedDerivedToBase, LHS.get(), 14122 &BasePath, LHS.get()->getValueKind()); 14123 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14124 CK_UncheckedDerivedToBase, RHS.get(), 14125 &BasePath, RHS.get()->getValueKind()); 14126 } 14127 FunctionProtoType::ExtProtoInfo EPI; 14128 QualType Params[] = {PtrRedTy, PtrRedTy}; 14129 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14130 auto *OVE = new (Context) OpaqueValueExpr( 14131 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14132 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14133 Expr *Args[] = {LHS.get(), RHS.get()}; 14134 ReductionOp = 14135 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14136 } else { 14137 ReductionOp = S.BuildBinOp( 14138 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14139 if (ReductionOp.isUsable()) { 14140 if (BOK != BO_LT && BOK != BO_GT) { 14141 ReductionOp = 14142 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14143 BO_Assign, LHSDRE, ReductionOp.get()); 14144 } else { 14145 auto *ConditionalOp = new (Context) 14146 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14147 Type, VK_LValue, OK_Ordinary); 14148 ReductionOp = 14149 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14150 BO_Assign, LHSDRE, ConditionalOp); 14151 } 14152 if (ReductionOp.isUsable()) 14153 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14154 /*DiscardedValue*/ false); 14155 } 14156 if (!ReductionOp.isUsable()) 14157 continue; 14158 } 14159 14160 // OpenMP [2.15.4.6, Restrictions, p.2] 14161 // A list item that appears in an in_reduction clause of a task construct 14162 // must appear in a task_reduction clause of a construct associated with a 14163 // taskgroup region that includes the participating task in its taskgroup 14164 // set. The construct associated with the innermost region that meets this 14165 // condition must specify the same reduction-identifier as the in_reduction 14166 // clause. 14167 if (ClauseKind == OMPC_in_reduction) { 14168 SourceRange ParentSR; 14169 BinaryOperatorKind ParentBOK; 14170 const Expr *ParentReductionOp; 14171 Expr *ParentBOKTD, *ParentReductionOpTD; 14172 DSAStackTy::DSAVarData ParentBOKDSA = 14173 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14174 ParentBOKTD); 14175 DSAStackTy::DSAVarData ParentReductionOpDSA = 14176 Stack->getTopMostTaskgroupReductionData( 14177 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14178 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14179 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14180 if (!IsParentBOK && !IsParentReductionOp) { 14181 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14182 continue; 14183 } 14184 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14185 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14186 IsParentReductionOp) { 14187 bool EmitError = true; 14188 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14189 llvm::FoldingSetNodeID RedId, ParentRedId; 14190 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14191 DeclareReductionRef.get()->Profile(RedId, Context, 14192 /*Canonical=*/true); 14193 EmitError = RedId != ParentRedId; 14194 } 14195 if (EmitError) { 14196 S.Diag(ReductionId.getBeginLoc(), 14197 diag::err_omp_reduction_identifier_mismatch) 14198 << ReductionIdRange << RefExpr->getSourceRange(); 14199 S.Diag(ParentSR.getBegin(), 14200 diag::note_omp_previous_reduction_identifier) 14201 << ParentSR 14202 << (IsParentBOK ? ParentBOKDSA.RefExpr 14203 : ParentReductionOpDSA.RefExpr) 14204 ->getSourceRange(); 14205 continue; 14206 } 14207 } 14208 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14209 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14210 } 14211 14212 DeclRefExpr *Ref = nullptr; 14213 Expr *VarsExpr = RefExpr->IgnoreParens(); 14214 if (!VD && !S.CurContext->isDependentContext()) { 14215 if (ASE || OASE) { 14216 TransformExprToCaptures RebuildToCapture(S, D); 14217 VarsExpr = 14218 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14219 Ref = RebuildToCapture.getCapturedExpr(); 14220 } else { 14221 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14222 } 14223 if (!S.isOpenMPCapturedDecl(D)) { 14224 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14225 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14226 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14227 if (!RefRes.isUsable()) 14228 continue; 14229 ExprResult PostUpdateRes = 14230 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14231 RefRes.get()); 14232 if (!PostUpdateRes.isUsable()) 14233 continue; 14234 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14235 Stack->getCurrentDirective() == OMPD_taskgroup) { 14236 S.Diag(RefExpr->getExprLoc(), 14237 diag::err_omp_reduction_non_addressable_expression) 14238 << RefExpr->getSourceRange(); 14239 continue; 14240 } 14241 RD.ExprPostUpdates.emplace_back( 14242 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14243 } 14244 } 14245 } 14246 // All reduction items are still marked as reduction (to do not increase 14247 // code base size). 14248 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14249 if (CurrDir == OMPD_taskgroup) { 14250 if (DeclareReductionRef.isUsable()) 14251 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14252 DeclareReductionRef.get()); 14253 else 14254 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14255 } 14256 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14257 TaskgroupDescriptor); 14258 } 14259 return RD.Vars.empty(); 14260 } 14261 14262 OMPClause *Sema::ActOnOpenMPReductionClause( 14263 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14264 SourceLocation ColonLoc, SourceLocation EndLoc, 14265 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14266 ArrayRef<Expr *> UnresolvedReductions) { 14267 ReductionData RD(VarList.size()); 14268 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14269 StartLoc, LParenLoc, ColonLoc, EndLoc, 14270 ReductionIdScopeSpec, ReductionId, 14271 UnresolvedReductions, RD)) 14272 return nullptr; 14273 14274 return OMPReductionClause::Create( 14275 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14276 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14277 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14278 buildPreInits(Context, RD.ExprCaptures), 14279 buildPostUpdate(*this, RD.ExprPostUpdates)); 14280 } 14281 14282 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14283 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14284 SourceLocation ColonLoc, SourceLocation EndLoc, 14285 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14286 ArrayRef<Expr *> UnresolvedReductions) { 14287 ReductionData RD(VarList.size()); 14288 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14289 StartLoc, LParenLoc, ColonLoc, EndLoc, 14290 ReductionIdScopeSpec, ReductionId, 14291 UnresolvedReductions, RD)) 14292 return nullptr; 14293 14294 return OMPTaskReductionClause::Create( 14295 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14296 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14297 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14298 buildPreInits(Context, RD.ExprCaptures), 14299 buildPostUpdate(*this, RD.ExprPostUpdates)); 14300 } 14301 14302 OMPClause *Sema::ActOnOpenMPInReductionClause( 14303 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14304 SourceLocation ColonLoc, SourceLocation EndLoc, 14305 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14306 ArrayRef<Expr *> UnresolvedReductions) { 14307 ReductionData RD(VarList.size()); 14308 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14309 StartLoc, LParenLoc, ColonLoc, EndLoc, 14310 ReductionIdScopeSpec, ReductionId, 14311 UnresolvedReductions, RD)) 14312 return nullptr; 14313 14314 return OMPInReductionClause::Create( 14315 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14316 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14317 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14318 buildPreInits(Context, RD.ExprCaptures), 14319 buildPostUpdate(*this, RD.ExprPostUpdates)); 14320 } 14321 14322 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14323 SourceLocation LinLoc) { 14324 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14325 LinKind == OMPC_LINEAR_unknown) { 14326 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14327 return true; 14328 } 14329 return false; 14330 } 14331 14332 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14333 OpenMPLinearClauseKind LinKind, 14334 QualType Type) { 14335 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14336 // A variable must not have an incomplete type or a reference type. 14337 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14338 return true; 14339 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14340 !Type->isReferenceType()) { 14341 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14342 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14343 return true; 14344 } 14345 Type = Type.getNonReferenceType(); 14346 14347 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14348 // A variable that is privatized must not have a const-qualified type 14349 // unless it is of class type with a mutable member. This restriction does 14350 // not apply to the firstprivate clause. 14351 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14352 return true; 14353 14354 // A list item must be of integral or pointer type. 14355 Type = Type.getUnqualifiedType().getCanonicalType(); 14356 const auto *Ty = Type.getTypePtrOrNull(); 14357 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 14358 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 14359 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14360 if (D) { 14361 bool IsDecl = 14362 !VD || 14363 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14364 Diag(D->getLocation(), 14365 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14366 << D; 14367 } 14368 return true; 14369 } 14370 return false; 14371 } 14372 14373 OMPClause *Sema::ActOnOpenMPLinearClause( 14374 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14375 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14376 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14377 SmallVector<Expr *, 8> Vars; 14378 SmallVector<Expr *, 8> Privates; 14379 SmallVector<Expr *, 8> Inits; 14380 SmallVector<Decl *, 4> ExprCaptures; 14381 SmallVector<Expr *, 4> ExprPostUpdates; 14382 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14383 LinKind = OMPC_LINEAR_val; 14384 for (Expr *RefExpr : VarList) { 14385 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14386 SourceLocation ELoc; 14387 SourceRange ERange; 14388 Expr *SimpleRefExpr = RefExpr; 14389 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14390 if (Res.second) { 14391 // It will be analyzed later. 14392 Vars.push_back(RefExpr); 14393 Privates.push_back(nullptr); 14394 Inits.push_back(nullptr); 14395 } 14396 ValueDecl *D = Res.first; 14397 if (!D) 14398 continue; 14399 14400 QualType Type = D->getType(); 14401 auto *VD = dyn_cast<VarDecl>(D); 14402 14403 // OpenMP [2.14.3.7, linear clause] 14404 // A list-item cannot appear in more than one linear clause. 14405 // A list-item that appears in a linear clause cannot appear in any 14406 // other data-sharing attribute clause. 14407 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14408 if (DVar.RefExpr) { 14409 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14410 << getOpenMPClauseName(OMPC_linear); 14411 reportOriginalDsa(*this, DSAStack, D, DVar); 14412 continue; 14413 } 14414 14415 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14416 continue; 14417 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14418 14419 // Build private copy of original var. 14420 VarDecl *Private = 14421 buildVarDecl(*this, ELoc, Type, D->getName(), 14422 D->hasAttrs() ? &D->getAttrs() : nullptr, 14423 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14424 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14425 // Build var to save initial value. 14426 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14427 Expr *InitExpr; 14428 DeclRefExpr *Ref = nullptr; 14429 if (!VD && !CurContext->isDependentContext()) { 14430 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14431 if (!isOpenMPCapturedDecl(D)) { 14432 ExprCaptures.push_back(Ref->getDecl()); 14433 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14434 ExprResult RefRes = DefaultLvalueConversion(Ref); 14435 if (!RefRes.isUsable()) 14436 continue; 14437 ExprResult PostUpdateRes = 14438 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14439 SimpleRefExpr, RefRes.get()); 14440 if (!PostUpdateRes.isUsable()) 14441 continue; 14442 ExprPostUpdates.push_back( 14443 IgnoredValueConversions(PostUpdateRes.get()).get()); 14444 } 14445 } 14446 } 14447 if (LinKind == OMPC_LINEAR_uval) 14448 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14449 else 14450 InitExpr = VD ? SimpleRefExpr : Ref; 14451 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14452 /*DirectInit=*/false); 14453 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14454 14455 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14456 Vars.push_back((VD || CurContext->isDependentContext()) 14457 ? RefExpr->IgnoreParens() 14458 : Ref); 14459 Privates.push_back(PrivateRef); 14460 Inits.push_back(InitRef); 14461 } 14462 14463 if (Vars.empty()) 14464 return nullptr; 14465 14466 Expr *StepExpr = Step; 14467 Expr *CalcStepExpr = nullptr; 14468 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14469 !Step->isInstantiationDependent() && 14470 !Step->containsUnexpandedParameterPack()) { 14471 SourceLocation StepLoc = Step->getBeginLoc(); 14472 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14473 if (Val.isInvalid()) 14474 return nullptr; 14475 StepExpr = Val.get(); 14476 14477 // Build var to save the step value. 14478 VarDecl *SaveVar = 14479 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14480 ExprResult SaveRef = 14481 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14482 ExprResult CalcStep = 14483 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14484 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14485 14486 // Warn about zero linear step (it would be probably better specified as 14487 // making corresponding variables 'const'). 14488 llvm::APSInt Result; 14489 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14490 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14491 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14492 << (Vars.size() > 1); 14493 if (!IsConstant && CalcStep.isUsable()) { 14494 // Calculate the step beforehand instead of doing this on each iteration. 14495 // (This is not used if the number of iterations may be kfold-ed). 14496 CalcStepExpr = CalcStep.get(); 14497 } 14498 } 14499 14500 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14501 ColonLoc, EndLoc, Vars, Privates, Inits, 14502 StepExpr, CalcStepExpr, 14503 buildPreInits(Context, ExprCaptures), 14504 buildPostUpdate(*this, ExprPostUpdates)); 14505 } 14506 14507 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14508 Expr *NumIterations, Sema &SemaRef, 14509 Scope *S, DSAStackTy *Stack) { 14510 // Walk the vars and build update/final expressions for the CodeGen. 14511 SmallVector<Expr *, 8> Updates; 14512 SmallVector<Expr *, 8> Finals; 14513 SmallVector<Expr *, 8> UsedExprs; 14514 Expr *Step = Clause.getStep(); 14515 Expr *CalcStep = Clause.getCalcStep(); 14516 // OpenMP [2.14.3.7, linear clause] 14517 // If linear-step is not specified it is assumed to be 1. 14518 if (!Step) 14519 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14520 else if (CalcStep) 14521 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14522 bool HasErrors = false; 14523 auto CurInit = Clause.inits().begin(); 14524 auto CurPrivate = Clause.privates().begin(); 14525 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14526 for (Expr *RefExpr : Clause.varlists()) { 14527 SourceLocation ELoc; 14528 SourceRange ERange; 14529 Expr *SimpleRefExpr = RefExpr; 14530 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14531 ValueDecl *D = Res.first; 14532 if (Res.second || !D) { 14533 Updates.push_back(nullptr); 14534 Finals.push_back(nullptr); 14535 HasErrors = true; 14536 continue; 14537 } 14538 auto &&Info = Stack->isLoopControlVariable(D); 14539 // OpenMP [2.15.11, distribute simd Construct] 14540 // A list item may not appear in a linear clause, unless it is the loop 14541 // iteration variable. 14542 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14543 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14544 SemaRef.Diag(ELoc, 14545 diag::err_omp_linear_distribute_var_non_loop_iteration); 14546 Updates.push_back(nullptr); 14547 Finals.push_back(nullptr); 14548 HasErrors = true; 14549 continue; 14550 } 14551 Expr *InitExpr = *CurInit; 14552 14553 // Build privatized reference to the current linear var. 14554 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14555 Expr *CapturedRef; 14556 if (LinKind == OMPC_LINEAR_uval) 14557 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14558 else 14559 CapturedRef = 14560 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14561 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14562 /*RefersToCapture=*/true); 14563 14564 // Build update: Var = InitExpr + IV * Step 14565 ExprResult Update; 14566 if (!Info.first) 14567 Update = buildCounterUpdate( 14568 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14569 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14570 else 14571 Update = *CurPrivate; 14572 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14573 /*DiscardedValue*/ false); 14574 14575 // Build final: Var = InitExpr + NumIterations * Step 14576 ExprResult Final; 14577 if (!Info.first) 14578 Final = 14579 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14580 InitExpr, NumIterations, Step, /*Subtract=*/false, 14581 /*IsNonRectangularLB=*/false); 14582 else 14583 Final = *CurPrivate; 14584 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14585 /*DiscardedValue*/ false); 14586 14587 if (!Update.isUsable() || !Final.isUsable()) { 14588 Updates.push_back(nullptr); 14589 Finals.push_back(nullptr); 14590 UsedExprs.push_back(nullptr); 14591 HasErrors = true; 14592 } else { 14593 Updates.push_back(Update.get()); 14594 Finals.push_back(Final.get()); 14595 if (!Info.first) 14596 UsedExprs.push_back(SimpleRefExpr); 14597 } 14598 ++CurInit; 14599 ++CurPrivate; 14600 } 14601 if (Expr *S = Clause.getStep()) 14602 UsedExprs.push_back(S); 14603 // Fill the remaining part with the nullptr. 14604 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14605 Clause.setUpdates(Updates); 14606 Clause.setFinals(Finals); 14607 Clause.setUsedExprs(UsedExprs); 14608 return HasErrors; 14609 } 14610 14611 OMPClause *Sema::ActOnOpenMPAlignedClause( 14612 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14613 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14614 SmallVector<Expr *, 8> Vars; 14615 for (Expr *RefExpr : VarList) { 14616 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14617 SourceLocation ELoc; 14618 SourceRange ERange; 14619 Expr *SimpleRefExpr = RefExpr; 14620 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14621 if (Res.second) { 14622 // It will be analyzed later. 14623 Vars.push_back(RefExpr); 14624 } 14625 ValueDecl *D = Res.first; 14626 if (!D) 14627 continue; 14628 14629 QualType QType = D->getType(); 14630 auto *VD = dyn_cast<VarDecl>(D); 14631 14632 // OpenMP [2.8.1, simd construct, Restrictions] 14633 // The type of list items appearing in the aligned clause must be 14634 // array, pointer, reference to array, or reference to pointer. 14635 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14636 const Type *Ty = QType.getTypePtrOrNull(); 14637 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14638 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14639 << QType << getLangOpts().CPlusPlus << ERange; 14640 bool IsDecl = 14641 !VD || 14642 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14643 Diag(D->getLocation(), 14644 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14645 << D; 14646 continue; 14647 } 14648 14649 // OpenMP [2.8.1, simd construct, Restrictions] 14650 // A list-item cannot appear in more than one aligned clause. 14651 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14652 Diag(ELoc, diag::err_omp_used_in_clause_twice) 14653 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 14654 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14655 << getOpenMPClauseName(OMPC_aligned); 14656 continue; 14657 } 14658 14659 DeclRefExpr *Ref = nullptr; 14660 if (!VD && isOpenMPCapturedDecl(D)) 14661 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14662 Vars.push_back(DefaultFunctionArrayConversion( 14663 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14664 .get()); 14665 } 14666 14667 // OpenMP [2.8.1, simd construct, Description] 14668 // The parameter of the aligned clause, alignment, must be a constant 14669 // positive integer expression. 14670 // If no optional parameter is specified, implementation-defined default 14671 // alignments for SIMD instructions on the target platforms are assumed. 14672 if (Alignment != nullptr) { 14673 ExprResult AlignResult = 14674 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14675 if (AlignResult.isInvalid()) 14676 return nullptr; 14677 Alignment = AlignResult.get(); 14678 } 14679 if (Vars.empty()) 14680 return nullptr; 14681 14682 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14683 EndLoc, Vars, Alignment); 14684 } 14685 14686 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14687 SourceLocation StartLoc, 14688 SourceLocation LParenLoc, 14689 SourceLocation EndLoc) { 14690 SmallVector<Expr *, 8> Vars; 14691 SmallVector<Expr *, 8> SrcExprs; 14692 SmallVector<Expr *, 8> DstExprs; 14693 SmallVector<Expr *, 8> AssignmentOps; 14694 for (Expr *RefExpr : VarList) { 14695 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14696 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14697 // It will be analyzed later. 14698 Vars.push_back(RefExpr); 14699 SrcExprs.push_back(nullptr); 14700 DstExprs.push_back(nullptr); 14701 AssignmentOps.push_back(nullptr); 14702 continue; 14703 } 14704 14705 SourceLocation ELoc = RefExpr->getExprLoc(); 14706 // OpenMP [2.1, C/C++] 14707 // A list item is a variable name. 14708 // OpenMP [2.14.4.1, Restrictions, p.1] 14709 // A list item that appears in a copyin clause must be threadprivate. 14710 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14711 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14712 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14713 << 0 << RefExpr->getSourceRange(); 14714 continue; 14715 } 14716 14717 Decl *D = DE->getDecl(); 14718 auto *VD = cast<VarDecl>(D); 14719 14720 QualType Type = VD->getType(); 14721 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14722 // It will be analyzed later. 14723 Vars.push_back(DE); 14724 SrcExprs.push_back(nullptr); 14725 DstExprs.push_back(nullptr); 14726 AssignmentOps.push_back(nullptr); 14727 continue; 14728 } 14729 14730 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14731 // A list item that appears in a copyin clause must be threadprivate. 14732 if (!DSAStack->isThreadPrivate(VD)) { 14733 Diag(ELoc, diag::err_omp_required_access) 14734 << getOpenMPClauseName(OMPC_copyin) 14735 << getOpenMPDirectiveName(OMPD_threadprivate); 14736 continue; 14737 } 14738 14739 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14740 // A variable of class type (or array thereof) that appears in a 14741 // copyin clause requires an accessible, unambiguous copy assignment 14742 // operator for the class type. 14743 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14744 VarDecl *SrcVD = 14745 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14746 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14747 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14748 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14749 VarDecl *DstVD = 14750 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14751 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14752 DeclRefExpr *PseudoDstExpr = 14753 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14754 // For arrays generate assignment operation for single element and replace 14755 // it by the original array element in CodeGen. 14756 ExprResult AssignmentOp = 14757 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14758 PseudoSrcExpr); 14759 if (AssignmentOp.isInvalid()) 14760 continue; 14761 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14762 /*DiscardedValue*/ false); 14763 if (AssignmentOp.isInvalid()) 14764 continue; 14765 14766 DSAStack->addDSA(VD, DE, OMPC_copyin); 14767 Vars.push_back(DE); 14768 SrcExprs.push_back(PseudoSrcExpr); 14769 DstExprs.push_back(PseudoDstExpr); 14770 AssignmentOps.push_back(AssignmentOp.get()); 14771 } 14772 14773 if (Vars.empty()) 14774 return nullptr; 14775 14776 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14777 SrcExprs, DstExprs, AssignmentOps); 14778 } 14779 14780 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14781 SourceLocation StartLoc, 14782 SourceLocation LParenLoc, 14783 SourceLocation EndLoc) { 14784 SmallVector<Expr *, 8> Vars; 14785 SmallVector<Expr *, 8> SrcExprs; 14786 SmallVector<Expr *, 8> DstExprs; 14787 SmallVector<Expr *, 8> AssignmentOps; 14788 for (Expr *RefExpr : VarList) { 14789 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14790 SourceLocation ELoc; 14791 SourceRange ERange; 14792 Expr *SimpleRefExpr = RefExpr; 14793 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14794 if (Res.second) { 14795 // It will be analyzed later. 14796 Vars.push_back(RefExpr); 14797 SrcExprs.push_back(nullptr); 14798 DstExprs.push_back(nullptr); 14799 AssignmentOps.push_back(nullptr); 14800 } 14801 ValueDecl *D = Res.first; 14802 if (!D) 14803 continue; 14804 14805 QualType Type = D->getType(); 14806 auto *VD = dyn_cast<VarDecl>(D); 14807 14808 // OpenMP [2.14.4.2, Restrictions, p.2] 14809 // A list item that appears in a copyprivate clause may not appear in a 14810 // private or firstprivate clause on the single construct. 14811 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14812 DSAStackTy::DSAVarData DVar = 14813 DSAStack->getTopDSA(D, /*FromParent=*/false); 14814 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14815 DVar.RefExpr) { 14816 Diag(ELoc, diag::err_omp_wrong_dsa) 14817 << getOpenMPClauseName(DVar.CKind) 14818 << getOpenMPClauseName(OMPC_copyprivate); 14819 reportOriginalDsa(*this, DSAStack, D, DVar); 14820 continue; 14821 } 14822 14823 // OpenMP [2.11.4.2, Restrictions, p.1] 14824 // All list items that appear in a copyprivate clause must be either 14825 // threadprivate or private in the enclosing context. 14826 if (DVar.CKind == OMPC_unknown) { 14827 DVar = DSAStack->getImplicitDSA(D, false); 14828 if (DVar.CKind == OMPC_shared) { 14829 Diag(ELoc, diag::err_omp_required_access) 14830 << getOpenMPClauseName(OMPC_copyprivate) 14831 << "threadprivate or private in the enclosing context"; 14832 reportOriginalDsa(*this, DSAStack, D, DVar); 14833 continue; 14834 } 14835 } 14836 } 14837 14838 // Variably modified types are not supported. 14839 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14840 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14841 << getOpenMPClauseName(OMPC_copyprivate) << Type 14842 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14843 bool IsDecl = 14844 !VD || 14845 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14846 Diag(D->getLocation(), 14847 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14848 << D; 14849 continue; 14850 } 14851 14852 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14853 // A variable of class type (or array thereof) that appears in a 14854 // copyin clause requires an accessible, unambiguous copy assignment 14855 // operator for the class type. 14856 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14857 .getUnqualifiedType(); 14858 VarDecl *SrcVD = 14859 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14860 D->hasAttrs() ? &D->getAttrs() : nullptr); 14861 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14862 VarDecl *DstVD = 14863 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14864 D->hasAttrs() ? &D->getAttrs() : nullptr); 14865 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14866 ExprResult AssignmentOp = BuildBinOp( 14867 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14868 if (AssignmentOp.isInvalid()) 14869 continue; 14870 AssignmentOp = 14871 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14872 if (AssignmentOp.isInvalid()) 14873 continue; 14874 14875 // No need to mark vars as copyprivate, they are already threadprivate or 14876 // implicitly private. 14877 assert(VD || isOpenMPCapturedDecl(D)); 14878 Vars.push_back( 14879 VD ? RefExpr->IgnoreParens() 14880 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14881 SrcExprs.push_back(PseudoSrcExpr); 14882 DstExprs.push_back(PseudoDstExpr); 14883 AssignmentOps.push_back(AssignmentOp.get()); 14884 } 14885 14886 if (Vars.empty()) 14887 return nullptr; 14888 14889 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14890 Vars, SrcExprs, DstExprs, AssignmentOps); 14891 } 14892 14893 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14894 SourceLocation StartLoc, 14895 SourceLocation LParenLoc, 14896 SourceLocation EndLoc) { 14897 if (VarList.empty()) 14898 return nullptr; 14899 14900 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14901 } 14902 14903 OMPClause * 14904 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14905 SourceLocation DepLoc, SourceLocation ColonLoc, 14906 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14907 SourceLocation LParenLoc, SourceLocation EndLoc) { 14908 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14909 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14910 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14911 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14912 return nullptr; 14913 } 14914 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14915 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14916 DepKind == OMPC_DEPEND_sink)) { 14917 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14918 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14919 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14920 /*Last=*/OMPC_DEPEND_unknown, Except) 14921 << getOpenMPClauseName(OMPC_depend); 14922 return nullptr; 14923 } 14924 SmallVector<Expr *, 8> Vars; 14925 DSAStackTy::OperatorOffsetTy OpsOffs; 14926 llvm::APSInt DepCounter(/*BitWidth=*/32); 14927 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14928 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14929 if (const Expr *OrderedCountExpr = 14930 DSAStack->getParentOrderedRegionParam().first) { 14931 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14932 TotalDepCount.setIsUnsigned(/*Val=*/true); 14933 } 14934 } 14935 for (Expr *RefExpr : VarList) { 14936 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14937 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14938 // It will be analyzed later. 14939 Vars.push_back(RefExpr); 14940 continue; 14941 } 14942 14943 SourceLocation ELoc = RefExpr->getExprLoc(); 14944 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14945 if (DepKind == OMPC_DEPEND_sink) { 14946 if (DSAStack->getParentOrderedRegionParam().first && 14947 DepCounter >= TotalDepCount) { 14948 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14949 continue; 14950 } 14951 ++DepCounter; 14952 // OpenMP [2.13.9, Summary] 14953 // depend(dependence-type : vec), where dependence-type is: 14954 // 'sink' and where vec is the iteration vector, which has the form: 14955 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14956 // where n is the value specified by the ordered clause in the loop 14957 // directive, xi denotes the loop iteration variable of the i-th nested 14958 // loop associated with the loop directive, and di is a constant 14959 // non-negative integer. 14960 if (CurContext->isDependentContext()) { 14961 // It will be analyzed later. 14962 Vars.push_back(RefExpr); 14963 continue; 14964 } 14965 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14966 OverloadedOperatorKind OOK = OO_None; 14967 SourceLocation OOLoc; 14968 Expr *LHS = SimpleExpr; 14969 Expr *RHS = nullptr; 14970 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14971 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14972 OOLoc = BO->getOperatorLoc(); 14973 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14974 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14975 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14976 OOK = OCE->getOperator(); 14977 OOLoc = OCE->getOperatorLoc(); 14978 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14979 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14980 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14981 OOK = MCE->getMethodDecl() 14982 ->getNameInfo() 14983 .getName() 14984 .getCXXOverloadedOperator(); 14985 OOLoc = MCE->getCallee()->getExprLoc(); 14986 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14987 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14988 } 14989 SourceLocation ELoc; 14990 SourceRange ERange; 14991 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14992 if (Res.second) { 14993 // It will be analyzed later. 14994 Vars.push_back(RefExpr); 14995 } 14996 ValueDecl *D = Res.first; 14997 if (!D) 14998 continue; 14999 15000 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15001 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15002 continue; 15003 } 15004 if (RHS) { 15005 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15006 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15007 if (RHSRes.isInvalid()) 15008 continue; 15009 } 15010 if (!CurContext->isDependentContext() && 15011 DSAStack->getParentOrderedRegionParam().first && 15012 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15013 const ValueDecl *VD = 15014 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15015 if (VD) 15016 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15017 << 1 << VD; 15018 else 15019 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15020 continue; 15021 } 15022 OpsOffs.emplace_back(RHS, OOK); 15023 } else { 15024 // OpenMP 5.0 [2.17.11, Restrictions] 15025 // List items used in depend clauses cannot be zero-length array sections. 15026 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15027 if (OASE) { 15028 const Expr *Length = OASE->getLength(); 15029 Expr::EvalResult Result; 15030 if (Length && !Length->isValueDependent() && 15031 Length->EvaluateAsInt(Result, Context) && 15032 Result.Val.getInt().isNullValue()) { 15033 Diag(ELoc, 15034 diag::err_omp_depend_zero_length_array_section_not_allowed) 15035 << SimpleExpr->getSourceRange(); 15036 continue; 15037 } 15038 } 15039 15040 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15041 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15042 (ASE && 15043 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 15044 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15045 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15046 << RefExpr->getSourceRange(); 15047 continue; 15048 } 15049 15050 ExprResult Res; 15051 { 15052 Sema::TentativeAnalysisScope Trap(*this); 15053 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15054 RefExpr->IgnoreParenImpCasts()); 15055 } 15056 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 15057 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15058 << RefExpr->getSourceRange(); 15059 continue; 15060 } 15061 } 15062 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15063 } 15064 15065 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15066 TotalDepCount > VarList.size() && 15067 DSAStack->getParentOrderedRegionParam().first && 15068 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15069 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15070 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15071 } 15072 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15073 Vars.empty()) 15074 return nullptr; 15075 15076 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15077 DepKind, DepLoc, ColonLoc, Vars, 15078 TotalDepCount.getZExtValue()); 15079 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15080 DSAStack->isParentOrderedRegion()) 15081 DSAStack->addDoacrossDependClause(C, OpsOffs); 15082 return C; 15083 } 15084 15085 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 15086 SourceLocation LParenLoc, 15087 SourceLocation EndLoc) { 15088 Expr *ValExpr = Device; 15089 Stmt *HelperValStmt = nullptr; 15090 15091 // OpenMP [2.9.1, Restrictions] 15092 // The device expression must evaluate to a non-negative integer value. 15093 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15094 /*StrictlyPositive=*/false)) 15095 return nullptr; 15096 15097 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15098 OpenMPDirectiveKind CaptureRegion = 15099 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15100 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15101 ValExpr = MakeFullExpr(ValExpr).get(); 15102 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15103 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15104 HelperValStmt = buildPreInits(Context, Captures); 15105 } 15106 15107 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 15108 StartLoc, LParenLoc, EndLoc); 15109 } 15110 15111 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15112 DSAStackTy *Stack, QualType QTy, 15113 bool FullCheck = true) { 15114 NamedDecl *ND; 15115 if (QTy->isIncompleteType(&ND)) { 15116 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15117 return false; 15118 } 15119 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15120 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15121 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15122 return true; 15123 } 15124 15125 /// Return true if it can be proven that the provided array expression 15126 /// (array section or array subscript) does NOT specify the whole size of the 15127 /// array whose base type is \a BaseQTy. 15128 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15129 const Expr *E, 15130 QualType BaseQTy) { 15131 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15132 15133 // If this is an array subscript, it refers to the whole size if the size of 15134 // the dimension is constant and equals 1. Also, an array section assumes the 15135 // format of an array subscript if no colon is used. 15136 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15137 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15138 return ATy->getSize().getSExtValue() != 1; 15139 // Size can't be evaluated statically. 15140 return false; 15141 } 15142 15143 assert(OASE && "Expecting array section if not an array subscript."); 15144 const Expr *LowerBound = OASE->getLowerBound(); 15145 const Expr *Length = OASE->getLength(); 15146 15147 // If there is a lower bound that does not evaluates to zero, we are not 15148 // covering the whole dimension. 15149 if (LowerBound) { 15150 Expr::EvalResult Result; 15151 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15152 return false; // Can't get the integer value as a constant. 15153 15154 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15155 if (ConstLowerBound.getSExtValue()) 15156 return true; 15157 } 15158 15159 // If we don't have a length we covering the whole dimension. 15160 if (!Length) 15161 return false; 15162 15163 // If the base is a pointer, we don't have a way to get the size of the 15164 // pointee. 15165 if (BaseQTy->isPointerType()) 15166 return false; 15167 15168 // We can only check if the length is the same as the size of the dimension 15169 // if we have a constant array. 15170 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15171 if (!CATy) 15172 return false; 15173 15174 Expr::EvalResult Result; 15175 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15176 return false; // Can't get the integer value as a constant. 15177 15178 llvm::APSInt ConstLength = Result.Val.getInt(); 15179 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15180 } 15181 15182 // Return true if it can be proven that the provided array expression (array 15183 // section or array subscript) does NOT specify a single element of the array 15184 // whose base type is \a BaseQTy. 15185 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15186 const Expr *E, 15187 QualType BaseQTy) { 15188 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15189 15190 // An array subscript always refer to a single element. Also, an array section 15191 // assumes the format of an array subscript if no colon is used. 15192 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15193 return false; 15194 15195 assert(OASE && "Expecting array section if not an array subscript."); 15196 const Expr *Length = OASE->getLength(); 15197 15198 // If we don't have a length we have to check if the array has unitary size 15199 // for this dimension. Also, we should always expect a length if the base type 15200 // is pointer. 15201 if (!Length) { 15202 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15203 return ATy->getSize().getSExtValue() != 1; 15204 // We cannot assume anything. 15205 return false; 15206 } 15207 15208 // Check if the length evaluates to 1. 15209 Expr::EvalResult Result; 15210 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15211 return false; // Can't get the integer value as a constant. 15212 15213 llvm::APSInt ConstLength = Result.Val.getInt(); 15214 return ConstLength.getSExtValue() != 1; 15215 } 15216 15217 // Return the expression of the base of the mappable expression or null if it 15218 // cannot be determined and do all the necessary checks to see if the expression 15219 // is valid as a standalone mappable expression. In the process, record all the 15220 // components of the expression. 15221 static const Expr *checkMapClauseExpressionBase( 15222 Sema &SemaRef, Expr *E, 15223 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15224 OpenMPClauseKind CKind, bool NoDiagnose) { 15225 SourceLocation ELoc = E->getExprLoc(); 15226 SourceRange ERange = E->getSourceRange(); 15227 15228 // The base of elements of list in a map clause have to be either: 15229 // - a reference to variable or field. 15230 // - a member expression. 15231 // - an array expression. 15232 // 15233 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15234 // reference to 'r'. 15235 // 15236 // If we have: 15237 // 15238 // struct SS { 15239 // Bla S; 15240 // foo() { 15241 // #pragma omp target map (S.Arr[:12]); 15242 // } 15243 // } 15244 // 15245 // We want to retrieve the member expression 'this->S'; 15246 15247 const Expr *RelevantExpr = nullptr; 15248 15249 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15250 // If a list item is an array section, it must specify contiguous storage. 15251 // 15252 // For this restriction it is sufficient that we make sure only references 15253 // to variables or fields and array expressions, and that no array sections 15254 // exist except in the rightmost expression (unless they cover the whole 15255 // dimension of the array). E.g. these would be invalid: 15256 // 15257 // r.ArrS[3:5].Arr[6:7] 15258 // 15259 // r.ArrS[3:5].x 15260 // 15261 // but these would be valid: 15262 // r.ArrS[3].Arr[6:7] 15263 // 15264 // r.ArrS[3].x 15265 15266 bool AllowUnitySizeArraySection = true; 15267 bool AllowWholeSizeArraySection = true; 15268 15269 while (!RelevantExpr) { 15270 E = E->IgnoreParenImpCasts(); 15271 15272 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 15273 if (!isa<VarDecl>(CurE->getDecl())) 15274 return nullptr; 15275 15276 RelevantExpr = CurE; 15277 15278 // If we got a reference to a declaration, we should not expect any array 15279 // section before that. 15280 AllowUnitySizeArraySection = false; 15281 AllowWholeSizeArraySection = false; 15282 15283 // Record the component. 15284 CurComponents.emplace_back(CurE, CurE->getDecl()); 15285 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 15286 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 15287 15288 if (isa<CXXThisExpr>(BaseE)) 15289 // We found a base expression: this->Val. 15290 RelevantExpr = CurE; 15291 else 15292 E = BaseE; 15293 15294 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 15295 if (!NoDiagnose) { 15296 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15297 << CurE->getSourceRange(); 15298 return nullptr; 15299 } 15300 if (RelevantExpr) 15301 return nullptr; 15302 continue; 15303 } 15304 15305 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 15306 15307 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15308 // A bit-field cannot appear in a map clause. 15309 // 15310 if (FD->isBitField()) { 15311 if (!NoDiagnose) { 15312 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15313 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 15314 return nullptr; 15315 } 15316 if (RelevantExpr) 15317 return nullptr; 15318 continue; 15319 } 15320 15321 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15322 // If the type of a list item is a reference to a type T then the type 15323 // will be considered to be T for all purposes of this clause. 15324 QualType CurType = BaseE->getType().getNonReferenceType(); 15325 15326 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15327 // A list item cannot be a variable that is a member of a structure with 15328 // a union type. 15329 // 15330 if (CurType->isUnionType()) { 15331 if (!NoDiagnose) { 15332 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15333 << CurE->getSourceRange(); 15334 return nullptr; 15335 } 15336 continue; 15337 } 15338 15339 // If we got a member expression, we should not expect any array section 15340 // before that: 15341 // 15342 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15343 // If a list item is an element of a structure, only the rightmost symbol 15344 // of the variable reference can be an array section. 15345 // 15346 AllowUnitySizeArraySection = false; 15347 AllowWholeSizeArraySection = false; 15348 15349 // Record the component. 15350 CurComponents.emplace_back(CurE, FD); 15351 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 15352 E = CurE->getBase()->IgnoreParenImpCasts(); 15353 15354 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15355 if (!NoDiagnose) { 15356 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15357 << 0 << CurE->getSourceRange(); 15358 return nullptr; 15359 } 15360 continue; 15361 } 15362 15363 // If we got an array subscript that express the whole dimension we 15364 // can have any array expressions before. If it only expressing part of 15365 // the dimension, we can only have unitary-size array expressions. 15366 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 15367 E->getType())) 15368 AllowWholeSizeArraySection = false; 15369 15370 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15371 Expr::EvalResult Result; 15372 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 15373 if (!Result.Val.getInt().isNullValue()) { 15374 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15375 diag::err_omp_invalid_map_this_expr); 15376 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15377 diag::note_omp_invalid_subscript_on_this_ptr_map); 15378 } 15379 } 15380 RelevantExpr = TE; 15381 } 15382 15383 // Record the component - we don't have any declaration associated. 15384 CurComponents.emplace_back(CurE, nullptr); 15385 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 15386 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15387 E = CurE->getBase()->IgnoreParenImpCasts(); 15388 15389 QualType CurType = 15390 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15391 15392 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15393 // If the type of a list item is a reference to a type T then the type 15394 // will be considered to be T for all purposes of this clause. 15395 if (CurType->isReferenceType()) 15396 CurType = CurType->getPointeeType(); 15397 15398 bool IsPointer = CurType->isAnyPointerType(); 15399 15400 if (!IsPointer && !CurType->isArrayType()) { 15401 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15402 << 0 << CurE->getSourceRange(); 15403 return nullptr; 15404 } 15405 15406 bool NotWhole = 15407 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 15408 bool NotUnity = 15409 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 15410 15411 if (AllowWholeSizeArraySection) { 15412 // Any array section is currently allowed. Allowing a whole size array 15413 // section implies allowing a unity array section as well. 15414 // 15415 // If this array section refers to the whole dimension we can still 15416 // accept other array sections before this one, except if the base is a 15417 // pointer. Otherwise, only unitary sections are accepted. 15418 if (NotWhole || IsPointer) 15419 AllowWholeSizeArraySection = false; 15420 } else if (AllowUnitySizeArraySection && NotUnity) { 15421 // A unity or whole array section is not allowed and that is not 15422 // compatible with the properties of the current array section. 15423 SemaRef.Diag( 15424 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15425 << CurE->getSourceRange(); 15426 return nullptr; 15427 } 15428 15429 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15430 Expr::EvalResult ResultR; 15431 Expr::EvalResult ResultL; 15432 if (CurE->getLength()->EvaluateAsInt(ResultR, 15433 SemaRef.getASTContext())) { 15434 if (!ResultR.Val.getInt().isOneValue()) { 15435 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15436 diag::err_omp_invalid_map_this_expr); 15437 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15438 diag::note_omp_invalid_length_on_this_ptr_mapping); 15439 } 15440 } 15441 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 15442 ResultL, SemaRef.getASTContext())) { 15443 if (!ResultL.Val.getInt().isNullValue()) { 15444 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15445 diag::err_omp_invalid_map_this_expr); 15446 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15447 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15448 } 15449 } 15450 RelevantExpr = TE; 15451 } 15452 15453 // Record the component - we don't have any declaration associated. 15454 CurComponents.emplace_back(CurE, nullptr); 15455 } else { 15456 if (!NoDiagnose) { 15457 // If nothing else worked, this is not a valid map clause expression. 15458 SemaRef.Diag( 15459 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15460 << ERange; 15461 } 15462 return nullptr; 15463 } 15464 } 15465 15466 return RelevantExpr; 15467 } 15468 15469 // Return true if expression E associated with value VD has conflicts with other 15470 // map information. 15471 static bool checkMapConflicts( 15472 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15473 bool CurrentRegionOnly, 15474 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15475 OpenMPClauseKind CKind) { 15476 assert(VD && E); 15477 SourceLocation ELoc = E->getExprLoc(); 15478 SourceRange ERange = E->getSourceRange(); 15479 15480 // In order to easily check the conflicts we need to match each component of 15481 // the expression under test with the components of the expressions that are 15482 // already in the stack. 15483 15484 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15485 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15486 "Map clause expression with unexpected base!"); 15487 15488 // Variables to help detecting enclosing problems in data environment nests. 15489 bool IsEnclosedByDataEnvironmentExpr = false; 15490 const Expr *EnclosingExpr = nullptr; 15491 15492 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15493 VD, CurrentRegionOnly, 15494 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15495 ERange, CKind, &EnclosingExpr, 15496 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15497 StackComponents, 15498 OpenMPClauseKind) { 15499 assert(!StackComponents.empty() && 15500 "Map clause expression with no components!"); 15501 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15502 "Map clause expression with unexpected base!"); 15503 (void)VD; 15504 15505 // The whole expression in the stack. 15506 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15507 15508 // Expressions must start from the same base. Here we detect at which 15509 // point both expressions diverge from each other and see if we can 15510 // detect if the memory referred to both expressions is contiguous and 15511 // do not overlap. 15512 auto CI = CurComponents.rbegin(); 15513 auto CE = CurComponents.rend(); 15514 auto SI = StackComponents.rbegin(); 15515 auto SE = StackComponents.rend(); 15516 for (; CI != CE && SI != SE; ++CI, ++SI) { 15517 15518 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15519 // At most one list item can be an array item derived from a given 15520 // variable in map clauses of the same construct. 15521 if (CurrentRegionOnly && 15522 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15523 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15524 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15525 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15526 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15527 diag::err_omp_multiple_array_items_in_map_clause) 15528 << CI->getAssociatedExpression()->getSourceRange(); 15529 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15530 diag::note_used_here) 15531 << SI->getAssociatedExpression()->getSourceRange(); 15532 return true; 15533 } 15534 15535 // Do both expressions have the same kind? 15536 if (CI->getAssociatedExpression()->getStmtClass() != 15537 SI->getAssociatedExpression()->getStmtClass()) 15538 break; 15539 15540 // Are we dealing with different variables/fields? 15541 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15542 break; 15543 } 15544 // Check if the extra components of the expressions in the enclosing 15545 // data environment are redundant for the current base declaration. 15546 // If they are, the maps completely overlap, which is legal. 15547 for (; SI != SE; ++SI) { 15548 QualType Type; 15549 if (const auto *ASE = 15550 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15551 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15552 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15553 SI->getAssociatedExpression())) { 15554 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15555 Type = 15556 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15557 } 15558 if (Type.isNull() || Type->isAnyPointerType() || 15559 checkArrayExpressionDoesNotReferToWholeSize( 15560 SemaRef, SI->getAssociatedExpression(), Type)) 15561 break; 15562 } 15563 15564 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15565 // List items of map clauses in the same construct must not share 15566 // original storage. 15567 // 15568 // If the expressions are exactly the same or one is a subset of the 15569 // other, it means they are sharing storage. 15570 if (CI == CE && SI == SE) { 15571 if (CurrentRegionOnly) { 15572 if (CKind == OMPC_map) { 15573 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15574 } else { 15575 assert(CKind == OMPC_to || CKind == OMPC_from); 15576 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15577 << ERange; 15578 } 15579 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15580 << RE->getSourceRange(); 15581 return true; 15582 } 15583 // If we find the same expression in the enclosing data environment, 15584 // that is legal. 15585 IsEnclosedByDataEnvironmentExpr = true; 15586 return false; 15587 } 15588 15589 QualType DerivedType = 15590 std::prev(CI)->getAssociatedDeclaration()->getType(); 15591 SourceLocation DerivedLoc = 15592 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15593 15594 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15595 // If the type of a list item is a reference to a type T then the type 15596 // will be considered to be T for all purposes of this clause. 15597 DerivedType = DerivedType.getNonReferenceType(); 15598 15599 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15600 // A variable for which the type is pointer and an array section 15601 // derived from that variable must not appear as list items of map 15602 // clauses of the same construct. 15603 // 15604 // Also, cover one of the cases in: 15605 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15606 // If any part of the original storage of a list item has corresponding 15607 // storage in the device data environment, all of the original storage 15608 // must have corresponding storage in the device data environment. 15609 // 15610 if (DerivedType->isAnyPointerType()) { 15611 if (CI == CE || SI == SE) { 15612 SemaRef.Diag( 15613 DerivedLoc, 15614 diag::err_omp_pointer_mapped_along_with_derived_section) 15615 << DerivedLoc; 15616 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15617 << RE->getSourceRange(); 15618 return true; 15619 } 15620 if (CI->getAssociatedExpression()->getStmtClass() != 15621 SI->getAssociatedExpression()->getStmtClass() || 15622 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15623 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15624 assert(CI != CE && SI != SE); 15625 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15626 << DerivedLoc; 15627 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15628 << RE->getSourceRange(); 15629 return true; 15630 } 15631 } 15632 15633 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15634 // List items of map clauses in the same construct must not share 15635 // original storage. 15636 // 15637 // An expression is a subset of the other. 15638 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15639 if (CKind == OMPC_map) { 15640 if (CI != CE || SI != SE) { 15641 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15642 // a pointer. 15643 auto Begin = 15644 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15645 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15646 auto It = Begin; 15647 while (It != End && !It->getAssociatedDeclaration()) 15648 std::advance(It, 1); 15649 assert(It != End && 15650 "Expected at least one component with the declaration."); 15651 if (It != Begin && It->getAssociatedDeclaration() 15652 ->getType() 15653 .getCanonicalType() 15654 ->isAnyPointerType()) { 15655 IsEnclosedByDataEnvironmentExpr = false; 15656 EnclosingExpr = nullptr; 15657 return false; 15658 } 15659 } 15660 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15661 } else { 15662 assert(CKind == OMPC_to || CKind == OMPC_from); 15663 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15664 << ERange; 15665 } 15666 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15667 << RE->getSourceRange(); 15668 return true; 15669 } 15670 15671 // The current expression uses the same base as other expression in the 15672 // data environment but does not contain it completely. 15673 if (!CurrentRegionOnly && SI != SE) 15674 EnclosingExpr = RE; 15675 15676 // The current expression is a subset of the expression in the data 15677 // environment. 15678 IsEnclosedByDataEnvironmentExpr |= 15679 (!CurrentRegionOnly && CI != CE && SI == SE); 15680 15681 return false; 15682 }); 15683 15684 if (CurrentRegionOnly) 15685 return FoundError; 15686 15687 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15688 // If any part of the original storage of a list item has corresponding 15689 // storage in the device data environment, all of the original storage must 15690 // have corresponding storage in the device data environment. 15691 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15692 // If a list item is an element of a structure, and a different element of 15693 // the structure has a corresponding list item in the device data environment 15694 // prior to a task encountering the construct associated with the map clause, 15695 // then the list item must also have a corresponding list item in the device 15696 // data environment prior to the task encountering the construct. 15697 // 15698 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15699 SemaRef.Diag(ELoc, 15700 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15701 << ERange; 15702 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15703 << EnclosingExpr->getSourceRange(); 15704 return true; 15705 } 15706 15707 return FoundError; 15708 } 15709 15710 // Look up the user-defined mapper given the mapper name and mapped type, and 15711 // build a reference to it. 15712 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15713 CXXScopeSpec &MapperIdScopeSpec, 15714 const DeclarationNameInfo &MapperId, 15715 QualType Type, 15716 Expr *UnresolvedMapper) { 15717 if (MapperIdScopeSpec.isInvalid()) 15718 return ExprError(); 15719 // Get the actual type for the array type. 15720 if (Type->isArrayType()) { 15721 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15722 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15723 } 15724 // Find all user-defined mappers with the given MapperId. 15725 SmallVector<UnresolvedSet<8>, 4> Lookups; 15726 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15727 Lookup.suppressDiagnostics(); 15728 if (S) { 15729 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15730 NamedDecl *D = Lookup.getRepresentativeDecl(); 15731 while (S && !S->isDeclScope(D)) 15732 S = S->getParent(); 15733 if (S) 15734 S = S->getParent(); 15735 Lookups.emplace_back(); 15736 Lookups.back().append(Lookup.begin(), Lookup.end()); 15737 Lookup.clear(); 15738 } 15739 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15740 // Extract the user-defined mappers with the given MapperId. 15741 Lookups.push_back(UnresolvedSet<8>()); 15742 for (NamedDecl *D : ULE->decls()) { 15743 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15744 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15745 Lookups.back().addDecl(DMD); 15746 } 15747 } 15748 // Defer the lookup for dependent types. The results will be passed through 15749 // UnresolvedMapper on instantiation. 15750 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15751 Type->isInstantiationDependentType() || 15752 Type->containsUnexpandedParameterPack() || 15753 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15754 return !D->isInvalidDecl() && 15755 (D->getType()->isDependentType() || 15756 D->getType()->isInstantiationDependentType() || 15757 D->getType()->containsUnexpandedParameterPack()); 15758 })) { 15759 UnresolvedSet<8> URS; 15760 for (const UnresolvedSet<8> &Set : Lookups) { 15761 if (Set.empty()) 15762 continue; 15763 URS.append(Set.begin(), Set.end()); 15764 } 15765 return UnresolvedLookupExpr::Create( 15766 SemaRef.Context, /*NamingClass=*/nullptr, 15767 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15768 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15769 } 15770 SourceLocation Loc = MapperId.getLoc(); 15771 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15772 // The type must be of struct, union or class type in C and C++ 15773 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15774 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15775 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15776 return ExprError(); 15777 } 15778 // Perform argument dependent lookup. 15779 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15780 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15781 // Return the first user-defined mapper with the desired type. 15782 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15783 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15784 if (!D->isInvalidDecl() && 15785 SemaRef.Context.hasSameType(D->getType(), Type)) 15786 return D; 15787 return nullptr; 15788 })) 15789 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15790 // Find the first user-defined mapper with a type derived from the desired 15791 // type. 15792 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15793 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15794 if (!D->isInvalidDecl() && 15795 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15796 !Type.isMoreQualifiedThan(D->getType())) 15797 return D; 15798 return nullptr; 15799 })) { 15800 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15801 /*DetectVirtual=*/false); 15802 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15803 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15804 VD->getType().getUnqualifiedType()))) { 15805 if (SemaRef.CheckBaseClassAccess( 15806 Loc, VD->getType(), Type, Paths.front(), 15807 /*DiagID=*/0) != Sema::AR_inaccessible) { 15808 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15809 } 15810 } 15811 } 15812 } 15813 // Report error if a mapper is specified, but cannot be found. 15814 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15815 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15816 << Type << MapperId.getName(); 15817 return ExprError(); 15818 } 15819 return ExprEmpty(); 15820 } 15821 15822 namespace { 15823 // Utility struct that gathers all the related lists associated with a mappable 15824 // expression. 15825 struct MappableVarListInfo { 15826 // The list of expressions. 15827 ArrayRef<Expr *> VarList; 15828 // The list of processed expressions. 15829 SmallVector<Expr *, 16> ProcessedVarList; 15830 // The mappble components for each expression. 15831 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15832 // The base declaration of the variable. 15833 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15834 // The reference to the user-defined mapper associated with every expression. 15835 SmallVector<Expr *, 16> UDMapperList; 15836 15837 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15838 // We have a list of components and base declarations for each entry in the 15839 // variable list. 15840 VarComponents.reserve(VarList.size()); 15841 VarBaseDeclarations.reserve(VarList.size()); 15842 } 15843 }; 15844 } 15845 15846 // Check the validity of the provided variable list for the provided clause kind 15847 // \a CKind. In the check process the valid expressions, mappable expression 15848 // components, variables, and user-defined mappers are extracted and used to 15849 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15850 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15851 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15852 static void checkMappableExpressionList( 15853 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15854 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15855 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15856 ArrayRef<Expr *> UnresolvedMappers, 15857 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15858 bool IsMapTypeImplicit = false) { 15859 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15860 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15861 "Unexpected clause kind with mappable expressions!"); 15862 15863 // If the identifier of user-defined mapper is not specified, it is "default". 15864 // We do not change the actual name in this clause to distinguish whether a 15865 // mapper is specified explicitly, i.e., it is not explicitly specified when 15866 // MapperId.getName() is empty. 15867 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15868 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15869 MapperId.setName(DeclNames.getIdentifier( 15870 &SemaRef.getASTContext().Idents.get("default"))); 15871 } 15872 15873 // Iterators to find the current unresolved mapper expression. 15874 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15875 bool UpdateUMIt = false; 15876 Expr *UnresolvedMapper = nullptr; 15877 15878 // Keep track of the mappable components and base declarations in this clause. 15879 // Each entry in the list is going to have a list of components associated. We 15880 // record each set of the components so that we can build the clause later on. 15881 // In the end we should have the same amount of declarations and component 15882 // lists. 15883 15884 for (Expr *RE : MVLI.VarList) { 15885 assert(RE && "Null expr in omp to/from/map clause"); 15886 SourceLocation ELoc = RE->getExprLoc(); 15887 15888 // Find the current unresolved mapper expression. 15889 if (UpdateUMIt && UMIt != UMEnd) { 15890 UMIt++; 15891 assert( 15892 UMIt != UMEnd && 15893 "Expect the size of UnresolvedMappers to match with that of VarList"); 15894 } 15895 UpdateUMIt = true; 15896 if (UMIt != UMEnd) 15897 UnresolvedMapper = *UMIt; 15898 15899 const Expr *VE = RE->IgnoreParenLValueCasts(); 15900 15901 if (VE->isValueDependent() || VE->isTypeDependent() || 15902 VE->isInstantiationDependent() || 15903 VE->containsUnexpandedParameterPack()) { 15904 // Try to find the associated user-defined mapper. 15905 ExprResult ER = buildUserDefinedMapperRef( 15906 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15907 VE->getType().getCanonicalType(), UnresolvedMapper); 15908 if (ER.isInvalid()) 15909 continue; 15910 MVLI.UDMapperList.push_back(ER.get()); 15911 // We can only analyze this information once the missing information is 15912 // resolved. 15913 MVLI.ProcessedVarList.push_back(RE); 15914 continue; 15915 } 15916 15917 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15918 15919 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15920 SemaRef.Diag(ELoc, 15921 diag::err_omp_expected_named_var_member_or_array_expression) 15922 << RE->getSourceRange(); 15923 continue; 15924 } 15925 15926 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15927 ValueDecl *CurDeclaration = nullptr; 15928 15929 // Obtain the array or member expression bases if required. Also, fill the 15930 // components array with all the components identified in the process. 15931 const Expr *BE = checkMapClauseExpressionBase( 15932 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15933 if (!BE) 15934 continue; 15935 15936 assert(!CurComponents.empty() && 15937 "Invalid mappable expression information."); 15938 15939 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15940 // Add store "this" pointer to class in DSAStackTy for future checking 15941 DSAS->addMappedClassesQualTypes(TE->getType()); 15942 // Try to find the associated user-defined mapper. 15943 ExprResult ER = buildUserDefinedMapperRef( 15944 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15945 VE->getType().getCanonicalType(), UnresolvedMapper); 15946 if (ER.isInvalid()) 15947 continue; 15948 MVLI.UDMapperList.push_back(ER.get()); 15949 // Skip restriction checking for variable or field declarations 15950 MVLI.ProcessedVarList.push_back(RE); 15951 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15952 MVLI.VarComponents.back().append(CurComponents.begin(), 15953 CurComponents.end()); 15954 MVLI.VarBaseDeclarations.push_back(nullptr); 15955 continue; 15956 } 15957 15958 // For the following checks, we rely on the base declaration which is 15959 // expected to be associated with the last component. The declaration is 15960 // expected to be a variable or a field (if 'this' is being mapped). 15961 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15962 assert(CurDeclaration && "Null decl on map clause."); 15963 assert( 15964 CurDeclaration->isCanonicalDecl() && 15965 "Expecting components to have associated only canonical declarations."); 15966 15967 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15968 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15969 15970 assert((VD || FD) && "Only variables or fields are expected here!"); 15971 (void)FD; 15972 15973 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15974 // threadprivate variables cannot appear in a map clause. 15975 // OpenMP 4.5 [2.10.5, target update Construct] 15976 // threadprivate variables cannot appear in a from clause. 15977 if (VD && DSAS->isThreadPrivate(VD)) { 15978 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15979 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15980 << getOpenMPClauseName(CKind); 15981 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15982 continue; 15983 } 15984 15985 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15986 // A list item cannot appear in both a map clause and a data-sharing 15987 // attribute clause on the same construct. 15988 15989 // Check conflicts with other map clause expressions. We check the conflicts 15990 // with the current construct separately from the enclosing data 15991 // environment, because the restrictions are different. We only have to 15992 // check conflicts across regions for the map clauses. 15993 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15994 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15995 break; 15996 if (CKind == OMPC_map && 15997 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15998 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15999 break; 16000 16001 // OpenMP 4.5 [2.10.5, target update Construct] 16002 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16003 // If the type of a list item is a reference to a type T then the type will 16004 // be considered to be T for all purposes of this clause. 16005 auto I = llvm::find_if( 16006 CurComponents, 16007 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16008 return MC.getAssociatedDeclaration(); 16009 }); 16010 assert(I != CurComponents.end() && "Null decl on map clause."); 16011 QualType Type; 16012 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16013 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16014 if (ASE) { 16015 Type = ASE->getType().getNonReferenceType(); 16016 } else if (OASE) { 16017 QualType BaseType = 16018 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16019 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16020 Type = ATy->getElementType(); 16021 else 16022 Type = BaseType->getPointeeType(); 16023 Type = Type.getNonReferenceType(); 16024 } else { 16025 Type = VE->getType(); 16026 } 16027 16028 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16029 // A list item in a to or from clause must have a mappable type. 16030 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16031 // A list item must have a mappable type. 16032 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16033 DSAS, Type)) 16034 continue; 16035 16036 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16037 16038 if (CKind == OMPC_map) { 16039 // target enter data 16040 // OpenMP [2.10.2, Restrictions, p. 99] 16041 // A map-type must be specified in all map clauses and must be either 16042 // to or alloc. 16043 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16044 if (DKind == OMPD_target_enter_data && 16045 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16046 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16047 << (IsMapTypeImplicit ? 1 : 0) 16048 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16049 << getOpenMPDirectiveName(DKind); 16050 continue; 16051 } 16052 16053 // target exit_data 16054 // OpenMP [2.10.3, Restrictions, p. 102] 16055 // A map-type must be specified in all map clauses and must be either 16056 // from, release, or delete. 16057 if (DKind == OMPD_target_exit_data && 16058 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16059 MapType == OMPC_MAP_delete)) { 16060 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16061 << (IsMapTypeImplicit ? 1 : 0) 16062 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16063 << getOpenMPDirectiveName(DKind); 16064 continue; 16065 } 16066 16067 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 16068 // A list item cannot appear in both a map clause and a data-sharing 16069 // attribute clause on the same construct 16070 // 16071 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 16072 // A list item cannot appear in both a map clause and a data-sharing 16073 // attribute clause on the same construct unless the construct is a 16074 // combined construct. 16075 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 16076 isOpenMPTargetExecutionDirective(DKind)) || 16077 DKind == OMPD_target)) { 16078 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16079 if (isOpenMPPrivate(DVar.CKind)) { 16080 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16081 << getOpenMPClauseName(DVar.CKind) 16082 << getOpenMPClauseName(OMPC_map) 16083 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 16084 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 16085 continue; 16086 } 16087 } 16088 } 16089 16090 // Try to find the associated user-defined mapper. 16091 ExprResult ER = buildUserDefinedMapperRef( 16092 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16093 Type.getCanonicalType(), UnresolvedMapper); 16094 if (ER.isInvalid()) 16095 continue; 16096 MVLI.UDMapperList.push_back(ER.get()); 16097 16098 // Save the current expression. 16099 MVLI.ProcessedVarList.push_back(RE); 16100 16101 // Store the components in the stack so that they can be used to check 16102 // against other clauses later on. 16103 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16104 /*WhereFoundClauseKind=*/OMPC_map); 16105 16106 // Save the components and declaration to create the clause. For purposes of 16107 // the clause creation, any component list that has has base 'this' uses 16108 // null as base declaration. 16109 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16110 MVLI.VarComponents.back().append(CurComponents.begin(), 16111 CurComponents.end()); 16112 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 16113 : CurDeclaration); 16114 } 16115 } 16116 16117 OMPClause *Sema::ActOnOpenMPMapClause( 16118 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 16119 ArrayRef<SourceLocation> MapTypeModifiersLoc, 16120 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 16121 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 16122 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 16123 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 16124 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 16125 OMPC_MAP_MODIFIER_unknown, 16126 OMPC_MAP_MODIFIER_unknown}; 16127 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 16128 16129 // Process map-type-modifiers, flag errors for duplicate modifiers. 16130 unsigned Count = 0; 16131 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 16132 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 16133 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 16134 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 16135 continue; 16136 } 16137 assert(Count < OMPMapClause::NumberOfModifiers && 16138 "Modifiers exceed the allowed number of map type modifiers"); 16139 Modifiers[Count] = MapTypeModifiers[I]; 16140 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16141 ++Count; 16142 } 16143 16144 MappableVarListInfo MVLI(VarList); 16145 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16146 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16147 MapType, IsMapTypeImplicit); 16148 16149 // We need to produce a map clause even if we don't have variables so that 16150 // other diagnostics related with non-existing map clauses are accurate. 16151 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16152 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16153 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16154 MapperIdScopeSpec.getWithLocInContext(Context), 16155 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16156 } 16157 16158 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16159 TypeResult ParsedType) { 16160 assert(ParsedType.isUsable()); 16161 16162 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16163 if (ReductionType.isNull()) 16164 return QualType(); 16165 16166 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16167 // A type name in a declare reduction directive cannot be a function type, an 16168 // array type, a reference type, or a type qualified with const, volatile or 16169 // restrict. 16170 if (ReductionType.hasQualifiers()) { 16171 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16172 return QualType(); 16173 } 16174 16175 if (ReductionType->isFunctionType()) { 16176 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16177 return QualType(); 16178 } 16179 if (ReductionType->isReferenceType()) { 16180 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16181 return QualType(); 16182 } 16183 if (ReductionType->isArrayType()) { 16184 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16185 return QualType(); 16186 } 16187 return ReductionType; 16188 } 16189 16190 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16191 Scope *S, DeclContext *DC, DeclarationName Name, 16192 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16193 AccessSpecifier AS, Decl *PrevDeclInScope) { 16194 SmallVector<Decl *, 8> Decls; 16195 Decls.reserve(ReductionTypes.size()); 16196 16197 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16198 forRedeclarationInCurContext()); 16199 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16200 // A reduction-identifier may not be re-declared in the current scope for the 16201 // same type or for a type that is compatible according to the base language 16202 // rules. 16203 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16204 OMPDeclareReductionDecl *PrevDRD = nullptr; 16205 bool InCompoundScope = true; 16206 if (S != nullptr) { 16207 // Find previous declaration with the same name not referenced in other 16208 // declarations. 16209 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16210 InCompoundScope = 16211 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16212 LookupName(Lookup, S); 16213 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16214 /*AllowInlineNamespace=*/false); 16215 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16216 LookupResult::Filter Filter = Lookup.makeFilter(); 16217 while (Filter.hasNext()) { 16218 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16219 if (InCompoundScope) { 16220 auto I = UsedAsPrevious.find(PrevDecl); 16221 if (I == UsedAsPrevious.end()) 16222 UsedAsPrevious[PrevDecl] = false; 16223 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16224 UsedAsPrevious[D] = true; 16225 } 16226 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16227 PrevDecl->getLocation(); 16228 } 16229 Filter.done(); 16230 if (InCompoundScope) { 16231 for (const auto &PrevData : UsedAsPrevious) { 16232 if (!PrevData.second) { 16233 PrevDRD = PrevData.first; 16234 break; 16235 } 16236 } 16237 } 16238 } else if (PrevDeclInScope != nullptr) { 16239 auto *PrevDRDInScope = PrevDRD = 16240 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16241 do { 16242 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16243 PrevDRDInScope->getLocation(); 16244 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16245 } while (PrevDRDInScope != nullptr); 16246 } 16247 for (const auto &TyData : ReductionTypes) { 16248 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16249 bool Invalid = false; 16250 if (I != PreviousRedeclTypes.end()) { 16251 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16252 << TyData.first; 16253 Diag(I->second, diag::note_previous_definition); 16254 Invalid = true; 16255 } 16256 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16257 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16258 Name, TyData.first, PrevDRD); 16259 DC->addDecl(DRD); 16260 DRD->setAccess(AS); 16261 Decls.push_back(DRD); 16262 if (Invalid) 16263 DRD->setInvalidDecl(); 16264 else 16265 PrevDRD = DRD; 16266 } 16267 16268 return DeclGroupPtrTy::make( 16269 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16270 } 16271 16272 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16273 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16274 16275 // Enter new function scope. 16276 PushFunctionScope(); 16277 setFunctionHasBranchProtectedScope(); 16278 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16279 16280 if (S != nullptr) 16281 PushDeclContext(S, DRD); 16282 else 16283 CurContext = DRD; 16284 16285 PushExpressionEvaluationContext( 16286 ExpressionEvaluationContext::PotentiallyEvaluated); 16287 16288 QualType ReductionType = DRD->getType(); 16289 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16290 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16291 // uses semantics of argument handles by value, but it should be passed by 16292 // reference. C lang does not support references, so pass all parameters as 16293 // pointers. 16294 // Create 'T omp_in;' variable. 16295 VarDecl *OmpInParm = 16296 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16297 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16298 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16299 // uses semantics of argument handles by value, but it should be passed by 16300 // reference. C lang does not support references, so pass all parameters as 16301 // pointers. 16302 // Create 'T omp_out;' variable. 16303 VarDecl *OmpOutParm = 16304 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16305 if (S != nullptr) { 16306 PushOnScopeChains(OmpInParm, S); 16307 PushOnScopeChains(OmpOutParm, S); 16308 } else { 16309 DRD->addDecl(OmpInParm); 16310 DRD->addDecl(OmpOutParm); 16311 } 16312 Expr *InE = 16313 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16314 Expr *OutE = 16315 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16316 DRD->setCombinerData(InE, OutE); 16317 } 16318 16319 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16320 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16321 DiscardCleanupsInEvaluationContext(); 16322 PopExpressionEvaluationContext(); 16323 16324 PopDeclContext(); 16325 PopFunctionScopeInfo(); 16326 16327 if (Combiner != nullptr) 16328 DRD->setCombiner(Combiner); 16329 else 16330 DRD->setInvalidDecl(); 16331 } 16332 16333 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16334 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16335 16336 // Enter new function scope. 16337 PushFunctionScope(); 16338 setFunctionHasBranchProtectedScope(); 16339 16340 if (S != nullptr) 16341 PushDeclContext(S, DRD); 16342 else 16343 CurContext = DRD; 16344 16345 PushExpressionEvaluationContext( 16346 ExpressionEvaluationContext::PotentiallyEvaluated); 16347 16348 QualType ReductionType = DRD->getType(); 16349 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16350 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16351 // uses semantics of argument handles by value, but it should be passed by 16352 // reference. C lang does not support references, so pass all parameters as 16353 // pointers. 16354 // Create 'T omp_priv;' variable. 16355 VarDecl *OmpPrivParm = 16356 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16357 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16358 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16359 // uses semantics of argument handles by value, but it should be passed by 16360 // reference. C lang does not support references, so pass all parameters as 16361 // pointers. 16362 // Create 'T omp_orig;' variable. 16363 VarDecl *OmpOrigParm = 16364 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16365 if (S != nullptr) { 16366 PushOnScopeChains(OmpPrivParm, S); 16367 PushOnScopeChains(OmpOrigParm, S); 16368 } else { 16369 DRD->addDecl(OmpPrivParm); 16370 DRD->addDecl(OmpOrigParm); 16371 } 16372 Expr *OrigE = 16373 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16374 Expr *PrivE = 16375 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16376 DRD->setInitializerData(OrigE, PrivE); 16377 return OmpPrivParm; 16378 } 16379 16380 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16381 VarDecl *OmpPrivParm) { 16382 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16383 DiscardCleanupsInEvaluationContext(); 16384 PopExpressionEvaluationContext(); 16385 16386 PopDeclContext(); 16387 PopFunctionScopeInfo(); 16388 16389 if (Initializer != nullptr) { 16390 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16391 } else if (OmpPrivParm->hasInit()) { 16392 DRD->setInitializer(OmpPrivParm->getInit(), 16393 OmpPrivParm->isDirectInit() 16394 ? OMPDeclareReductionDecl::DirectInit 16395 : OMPDeclareReductionDecl::CopyInit); 16396 } else { 16397 DRD->setInvalidDecl(); 16398 } 16399 } 16400 16401 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16402 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16403 for (Decl *D : DeclReductions.get()) { 16404 if (IsValid) { 16405 if (S) 16406 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16407 /*AddToContext=*/false); 16408 } else { 16409 D->setInvalidDecl(); 16410 } 16411 } 16412 return DeclReductions; 16413 } 16414 16415 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16416 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16417 QualType T = TInfo->getType(); 16418 if (D.isInvalidType()) 16419 return true; 16420 16421 if (getLangOpts().CPlusPlus) { 16422 // Check that there are no default arguments (C++ only). 16423 CheckExtraCXXDefaultArguments(D); 16424 } 16425 16426 return CreateParsedType(T, TInfo); 16427 } 16428 16429 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16430 TypeResult ParsedType) { 16431 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16432 16433 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16434 assert(!MapperType.isNull() && "Expect valid mapper type"); 16435 16436 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16437 // The type must be of struct, union or class type in C and C++ 16438 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16439 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16440 return QualType(); 16441 } 16442 return MapperType; 16443 } 16444 16445 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16446 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16447 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16448 Decl *PrevDeclInScope) { 16449 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16450 forRedeclarationInCurContext()); 16451 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16452 // A mapper-identifier may not be redeclared in the current scope for the 16453 // same type or for a type that is compatible according to the base language 16454 // rules. 16455 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16456 OMPDeclareMapperDecl *PrevDMD = nullptr; 16457 bool InCompoundScope = true; 16458 if (S != nullptr) { 16459 // Find previous declaration with the same name not referenced in other 16460 // declarations. 16461 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16462 InCompoundScope = 16463 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16464 LookupName(Lookup, S); 16465 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16466 /*AllowInlineNamespace=*/false); 16467 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16468 LookupResult::Filter Filter = Lookup.makeFilter(); 16469 while (Filter.hasNext()) { 16470 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16471 if (InCompoundScope) { 16472 auto I = UsedAsPrevious.find(PrevDecl); 16473 if (I == UsedAsPrevious.end()) 16474 UsedAsPrevious[PrevDecl] = false; 16475 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16476 UsedAsPrevious[D] = true; 16477 } 16478 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16479 PrevDecl->getLocation(); 16480 } 16481 Filter.done(); 16482 if (InCompoundScope) { 16483 for (const auto &PrevData : UsedAsPrevious) { 16484 if (!PrevData.second) { 16485 PrevDMD = PrevData.first; 16486 break; 16487 } 16488 } 16489 } 16490 } else if (PrevDeclInScope) { 16491 auto *PrevDMDInScope = PrevDMD = 16492 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16493 do { 16494 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16495 PrevDMDInScope->getLocation(); 16496 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16497 } while (PrevDMDInScope != nullptr); 16498 } 16499 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16500 bool Invalid = false; 16501 if (I != PreviousRedeclTypes.end()) { 16502 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16503 << MapperType << Name; 16504 Diag(I->second, diag::note_previous_definition); 16505 Invalid = true; 16506 } 16507 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16508 MapperType, VN, PrevDMD); 16509 DC->addDecl(DMD); 16510 DMD->setAccess(AS); 16511 if (Invalid) 16512 DMD->setInvalidDecl(); 16513 16514 // Enter new function scope. 16515 PushFunctionScope(); 16516 setFunctionHasBranchProtectedScope(); 16517 16518 CurContext = DMD; 16519 16520 return DMD; 16521 } 16522 16523 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16524 Scope *S, 16525 QualType MapperType, 16526 SourceLocation StartLoc, 16527 DeclarationName VN) { 16528 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16529 if (S) 16530 PushOnScopeChains(VD, S); 16531 else 16532 DMD->addDecl(VD); 16533 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16534 DMD->setMapperVarRef(MapperVarRefExpr); 16535 } 16536 16537 Sema::DeclGroupPtrTy 16538 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16539 ArrayRef<OMPClause *> ClauseList) { 16540 PopDeclContext(); 16541 PopFunctionScopeInfo(); 16542 16543 if (D) { 16544 if (S) 16545 PushOnScopeChains(D, S, /*AddToContext=*/false); 16546 D->CreateClauses(Context, ClauseList); 16547 } 16548 16549 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16550 } 16551 16552 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16553 SourceLocation StartLoc, 16554 SourceLocation LParenLoc, 16555 SourceLocation EndLoc) { 16556 Expr *ValExpr = NumTeams; 16557 Stmt *HelperValStmt = nullptr; 16558 16559 // OpenMP [teams Constrcut, Restrictions] 16560 // The num_teams expression must evaluate to a positive integer value. 16561 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16562 /*StrictlyPositive=*/true)) 16563 return nullptr; 16564 16565 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16566 OpenMPDirectiveKind CaptureRegion = 16567 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 16568 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16569 ValExpr = MakeFullExpr(ValExpr).get(); 16570 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16571 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16572 HelperValStmt = buildPreInits(Context, Captures); 16573 } 16574 16575 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16576 StartLoc, LParenLoc, EndLoc); 16577 } 16578 16579 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16580 SourceLocation StartLoc, 16581 SourceLocation LParenLoc, 16582 SourceLocation EndLoc) { 16583 Expr *ValExpr = ThreadLimit; 16584 Stmt *HelperValStmt = nullptr; 16585 16586 // OpenMP [teams Constrcut, Restrictions] 16587 // The thread_limit expression must evaluate to a positive integer value. 16588 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16589 /*StrictlyPositive=*/true)) 16590 return nullptr; 16591 16592 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16593 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 16594 DKind, OMPC_thread_limit, LangOpts.OpenMP); 16595 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16596 ValExpr = MakeFullExpr(ValExpr).get(); 16597 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16598 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16599 HelperValStmt = buildPreInits(Context, Captures); 16600 } 16601 16602 return new (Context) OMPThreadLimitClause( 16603 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16604 } 16605 16606 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16607 SourceLocation StartLoc, 16608 SourceLocation LParenLoc, 16609 SourceLocation EndLoc) { 16610 Expr *ValExpr = Priority; 16611 Stmt *HelperValStmt = nullptr; 16612 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16613 16614 // OpenMP [2.9.1, task Constrcut] 16615 // The priority-value is a non-negative numerical scalar expression. 16616 if (!isNonNegativeIntegerValue( 16617 ValExpr, *this, OMPC_priority, 16618 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16619 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16620 return nullptr; 16621 16622 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16623 StartLoc, LParenLoc, EndLoc); 16624 } 16625 16626 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16627 SourceLocation StartLoc, 16628 SourceLocation LParenLoc, 16629 SourceLocation EndLoc) { 16630 Expr *ValExpr = Grainsize; 16631 Stmt *HelperValStmt = nullptr; 16632 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16633 16634 // OpenMP [2.9.2, taskloop Constrcut] 16635 // The parameter of the grainsize clause must be a positive integer 16636 // expression. 16637 if (!isNonNegativeIntegerValue( 16638 ValExpr, *this, OMPC_grainsize, 16639 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16640 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16641 return nullptr; 16642 16643 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16644 StartLoc, LParenLoc, EndLoc); 16645 } 16646 16647 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16648 SourceLocation StartLoc, 16649 SourceLocation LParenLoc, 16650 SourceLocation EndLoc) { 16651 Expr *ValExpr = NumTasks; 16652 Stmt *HelperValStmt = nullptr; 16653 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16654 16655 // OpenMP [2.9.2, taskloop Constrcut] 16656 // The parameter of the num_tasks clause must be a positive integer 16657 // expression. 16658 if (!isNonNegativeIntegerValue( 16659 ValExpr, *this, OMPC_num_tasks, 16660 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16661 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16662 return nullptr; 16663 16664 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16665 StartLoc, LParenLoc, EndLoc); 16666 } 16667 16668 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16669 SourceLocation LParenLoc, 16670 SourceLocation EndLoc) { 16671 // OpenMP [2.13.2, critical construct, Description] 16672 // ... where hint-expression is an integer constant expression that evaluates 16673 // to a valid lock hint. 16674 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16675 if (HintExpr.isInvalid()) 16676 return nullptr; 16677 return new (Context) 16678 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16679 } 16680 16681 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16682 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16683 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16684 SourceLocation EndLoc) { 16685 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16686 std::string Values; 16687 Values += "'"; 16688 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16689 Values += "'"; 16690 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16691 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16692 return nullptr; 16693 } 16694 Expr *ValExpr = ChunkSize; 16695 Stmt *HelperValStmt = nullptr; 16696 if (ChunkSize) { 16697 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16698 !ChunkSize->isInstantiationDependent() && 16699 !ChunkSize->containsUnexpandedParameterPack()) { 16700 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16701 ExprResult Val = 16702 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16703 if (Val.isInvalid()) 16704 return nullptr; 16705 16706 ValExpr = Val.get(); 16707 16708 // OpenMP [2.7.1, Restrictions] 16709 // chunk_size must be a loop invariant integer expression with a positive 16710 // value. 16711 llvm::APSInt Result; 16712 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16713 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16714 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16715 << "dist_schedule" << ChunkSize->getSourceRange(); 16716 return nullptr; 16717 } 16718 } else if (getOpenMPCaptureRegionForClause( 16719 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 16720 LangOpts.OpenMP) != OMPD_unknown && 16721 !CurContext->isDependentContext()) { 16722 ValExpr = MakeFullExpr(ValExpr).get(); 16723 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16724 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16725 HelperValStmt = buildPreInits(Context, Captures); 16726 } 16727 } 16728 } 16729 16730 return new (Context) 16731 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16732 Kind, ValExpr, HelperValStmt); 16733 } 16734 16735 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16736 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16737 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16738 SourceLocation KindLoc, SourceLocation EndLoc) { 16739 if (getLangOpts().OpenMP < 50) { 16740 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16741 Kind != OMPC_DEFAULTMAP_scalar) { 16742 std::string Value; 16743 SourceLocation Loc; 16744 Value += "'"; 16745 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16746 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16747 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16748 Loc = MLoc; 16749 } else { 16750 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16751 OMPC_DEFAULTMAP_scalar); 16752 Loc = KindLoc; 16753 } 16754 Value += "'"; 16755 Diag(Loc, diag::err_omp_unexpected_clause_value) 16756 << Value << getOpenMPClauseName(OMPC_defaultmap); 16757 return nullptr; 16758 } 16759 } else { 16760 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 16761 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 16762 if (!isDefaultmapKind || !isDefaultmapModifier) { 16763 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 16764 "'firstprivate', 'none', 'default'"; 16765 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 16766 if (!isDefaultmapKind && isDefaultmapModifier) { 16767 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16768 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16769 } else if (isDefaultmapKind && !isDefaultmapModifier) { 16770 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16771 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16772 } else { 16773 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16774 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16775 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16776 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16777 } 16778 return nullptr; 16779 } 16780 16781 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 16782 // At most one defaultmap clause for each category can appear on the 16783 // directive. 16784 if (DSAStack->checkDefaultmapCategory(Kind)) { 16785 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 16786 return nullptr; 16787 } 16788 } 16789 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 16790 16791 return new (Context) 16792 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16793 } 16794 16795 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16796 DeclContext *CurLexicalContext = getCurLexicalContext(); 16797 if (!CurLexicalContext->isFileContext() && 16798 !CurLexicalContext->isExternCContext() && 16799 !CurLexicalContext->isExternCXXContext() && 16800 !isa<CXXRecordDecl>(CurLexicalContext) && 16801 !isa<ClassTemplateDecl>(CurLexicalContext) && 16802 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16803 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16804 Diag(Loc, diag::err_omp_region_not_file_context); 16805 return false; 16806 } 16807 ++DeclareTargetNestingLevel; 16808 return true; 16809 } 16810 16811 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16812 assert(DeclareTargetNestingLevel > 0 && 16813 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16814 --DeclareTargetNestingLevel; 16815 } 16816 16817 NamedDecl * 16818 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16819 const DeclarationNameInfo &Id, 16820 NamedDeclSetType &SameDirectiveDecls) { 16821 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16822 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16823 16824 if (Lookup.isAmbiguous()) 16825 return nullptr; 16826 Lookup.suppressDiagnostics(); 16827 16828 if (!Lookup.isSingleResult()) { 16829 VarOrFuncDeclFilterCCC CCC(*this); 16830 if (TypoCorrection Corrected = 16831 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16832 CTK_ErrorRecovery)) { 16833 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16834 << Id.getName()); 16835 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16836 return nullptr; 16837 } 16838 16839 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16840 return nullptr; 16841 } 16842 16843 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16844 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16845 !isa<FunctionTemplateDecl>(ND)) { 16846 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16847 return nullptr; 16848 } 16849 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16850 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16851 return ND; 16852 } 16853 16854 void Sema::ActOnOpenMPDeclareTargetName( 16855 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16856 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16857 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16858 isa<FunctionTemplateDecl>(ND)) && 16859 "Expected variable, function or function template."); 16860 16861 // Diagnose marking after use as it may lead to incorrect diagnosis and 16862 // codegen. 16863 if (LangOpts.OpenMP >= 50 && 16864 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16865 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16866 16867 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16868 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16869 if (DevTy.hasValue() && *DevTy != DT) { 16870 Diag(Loc, diag::err_omp_device_type_mismatch) 16871 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16872 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16873 return; 16874 } 16875 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16876 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16877 if (!Res) { 16878 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16879 SourceRange(Loc, Loc)); 16880 ND->addAttr(A); 16881 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16882 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16883 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16884 } else if (*Res != MT) { 16885 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16886 } 16887 } 16888 16889 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16890 Sema &SemaRef, Decl *D) { 16891 if (!D || !isa<VarDecl>(D)) 16892 return; 16893 auto *VD = cast<VarDecl>(D); 16894 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16895 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16896 if (SemaRef.LangOpts.OpenMP >= 50 && 16897 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16898 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16899 VD->hasGlobalStorage()) { 16900 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16901 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16902 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16903 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16904 // If a lambda declaration and definition appears between a 16905 // declare target directive and the matching end declare target 16906 // directive, all variables that are captured by the lambda 16907 // expression must also appear in a to clause. 16908 SemaRef.Diag(VD->getLocation(), 16909 diag::err_omp_lambda_capture_in_declare_target_not_to); 16910 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16911 << VD << 0 << SR; 16912 return; 16913 } 16914 } 16915 if (MapTy.hasValue()) 16916 return; 16917 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16918 SemaRef.Diag(SL, diag::note_used_here) << SR; 16919 } 16920 16921 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16922 Sema &SemaRef, DSAStackTy *Stack, 16923 ValueDecl *VD) { 16924 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16925 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16926 /*FullCheck=*/false); 16927 } 16928 16929 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16930 SourceLocation IdLoc) { 16931 if (!D || D->isInvalidDecl()) 16932 return; 16933 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16934 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16935 if (auto *VD = dyn_cast<VarDecl>(D)) { 16936 // Only global variables can be marked as declare target. 16937 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16938 !VD->isStaticDataMember()) 16939 return; 16940 // 2.10.6: threadprivate variable cannot appear in a declare target 16941 // directive. 16942 if (DSAStack->isThreadPrivate(VD)) { 16943 Diag(SL, diag::err_omp_threadprivate_in_target); 16944 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16945 return; 16946 } 16947 } 16948 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16949 D = FTD->getTemplatedDecl(); 16950 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16951 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16952 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16953 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16954 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16955 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16956 return; 16957 } 16958 // Mark the function as must be emitted for the device. 16959 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16960 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16961 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16962 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16963 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16964 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16965 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16966 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16967 } 16968 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16969 // Problem if any with var declared with incomplete type will be reported 16970 // as normal, so no need to check it here. 16971 if ((E || !VD->getType()->isIncompleteType()) && 16972 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16973 return; 16974 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16975 // Checking declaration inside declare target region. 16976 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16977 isa<FunctionTemplateDecl>(D)) { 16978 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16979 Context, OMPDeclareTargetDeclAttr::MT_To, 16980 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16981 D->addAttr(A); 16982 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16983 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16984 } 16985 return; 16986 } 16987 } 16988 if (!E) 16989 return; 16990 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16991 } 16992 16993 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16994 CXXScopeSpec &MapperIdScopeSpec, 16995 DeclarationNameInfo &MapperId, 16996 const OMPVarListLocTy &Locs, 16997 ArrayRef<Expr *> UnresolvedMappers) { 16998 MappableVarListInfo MVLI(VarList); 16999 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17000 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17001 if (MVLI.ProcessedVarList.empty()) 17002 return nullptr; 17003 17004 return OMPToClause::Create( 17005 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17006 MVLI.VarComponents, MVLI.UDMapperList, 17007 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17008 } 17009 17010 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17011 CXXScopeSpec &MapperIdScopeSpec, 17012 DeclarationNameInfo &MapperId, 17013 const OMPVarListLocTy &Locs, 17014 ArrayRef<Expr *> UnresolvedMappers) { 17015 MappableVarListInfo MVLI(VarList); 17016 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 17017 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17018 if (MVLI.ProcessedVarList.empty()) 17019 return nullptr; 17020 17021 return OMPFromClause::Create( 17022 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17023 MVLI.VarComponents, MVLI.UDMapperList, 17024 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17025 } 17026 17027 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 17028 const OMPVarListLocTy &Locs) { 17029 MappableVarListInfo MVLI(VarList); 17030 SmallVector<Expr *, 8> PrivateCopies; 17031 SmallVector<Expr *, 8> Inits; 17032 17033 for (Expr *RefExpr : VarList) { 17034 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 17035 SourceLocation ELoc; 17036 SourceRange ERange; 17037 Expr *SimpleRefExpr = RefExpr; 17038 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17039 if (Res.second) { 17040 // It will be analyzed later. 17041 MVLI.ProcessedVarList.push_back(RefExpr); 17042 PrivateCopies.push_back(nullptr); 17043 Inits.push_back(nullptr); 17044 } 17045 ValueDecl *D = Res.first; 17046 if (!D) 17047 continue; 17048 17049 QualType Type = D->getType(); 17050 Type = Type.getNonReferenceType().getUnqualifiedType(); 17051 17052 auto *VD = dyn_cast<VarDecl>(D); 17053 17054 // Item should be a pointer or reference to pointer. 17055 if (!Type->isPointerType()) { 17056 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 17057 << 0 << RefExpr->getSourceRange(); 17058 continue; 17059 } 17060 17061 // Build the private variable and the expression that refers to it. 17062 auto VDPrivate = 17063 buildVarDecl(*this, ELoc, Type, D->getName(), 17064 D->hasAttrs() ? &D->getAttrs() : nullptr, 17065 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17066 if (VDPrivate->isInvalidDecl()) 17067 continue; 17068 17069 CurContext->addDecl(VDPrivate); 17070 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17071 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17072 17073 // Add temporary variable to initialize the private copy of the pointer. 17074 VarDecl *VDInit = 17075 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 17076 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 17077 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 17078 AddInitializerToDecl(VDPrivate, 17079 DefaultLvalueConversion(VDInitRefExpr).get(), 17080 /*DirectInit=*/false); 17081 17082 // If required, build a capture to implement the privatization initialized 17083 // with the current list item value. 17084 DeclRefExpr *Ref = nullptr; 17085 if (!VD) 17086 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17087 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 17088 PrivateCopies.push_back(VDPrivateRefExpr); 17089 Inits.push_back(VDInitRefExpr); 17090 17091 // We need to add a data sharing attribute for this variable to make sure it 17092 // is correctly captured. A variable that shows up in a use_device_ptr has 17093 // similar properties of a first private variable. 17094 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17095 17096 // Create a mappable component for the list item. List items in this clause 17097 // only need a component. 17098 MVLI.VarBaseDeclarations.push_back(D); 17099 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17100 MVLI.VarComponents.back().push_back( 17101 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 17102 } 17103 17104 if (MVLI.ProcessedVarList.empty()) 17105 return nullptr; 17106 17107 return OMPUseDevicePtrClause::Create( 17108 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 17109 MVLI.VarBaseDeclarations, MVLI.VarComponents); 17110 } 17111 17112 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 17113 const OMPVarListLocTy &Locs) { 17114 MappableVarListInfo MVLI(VarList); 17115 for (Expr *RefExpr : VarList) { 17116 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 17117 SourceLocation ELoc; 17118 SourceRange ERange; 17119 Expr *SimpleRefExpr = RefExpr; 17120 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17121 if (Res.second) { 17122 // It will be analyzed later. 17123 MVLI.ProcessedVarList.push_back(RefExpr); 17124 } 17125 ValueDecl *D = Res.first; 17126 if (!D) 17127 continue; 17128 17129 QualType Type = D->getType(); 17130 // item should be a pointer or array or reference to pointer or array 17131 if (!Type.getNonReferenceType()->isPointerType() && 17132 !Type.getNonReferenceType()->isArrayType()) { 17133 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 17134 << 0 << RefExpr->getSourceRange(); 17135 continue; 17136 } 17137 17138 // Check if the declaration in the clause does not show up in any data 17139 // sharing attribute. 17140 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17141 if (isOpenMPPrivate(DVar.CKind)) { 17142 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17143 << getOpenMPClauseName(DVar.CKind) 17144 << getOpenMPClauseName(OMPC_is_device_ptr) 17145 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17146 reportOriginalDsa(*this, DSAStack, D, DVar); 17147 continue; 17148 } 17149 17150 const Expr *ConflictExpr; 17151 if (DSAStack->checkMappableExprComponentListsForDecl( 17152 D, /*CurrentRegionOnly=*/true, 17153 [&ConflictExpr]( 17154 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17155 OpenMPClauseKind) -> bool { 17156 ConflictExpr = R.front().getAssociatedExpression(); 17157 return true; 17158 })) { 17159 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17160 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17161 << ConflictExpr->getSourceRange(); 17162 continue; 17163 } 17164 17165 // Store the components in the stack so that they can be used to check 17166 // against other clauses later on. 17167 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17168 DSAStack->addMappableExpressionComponents( 17169 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17170 17171 // Record the expression we've just processed. 17172 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17173 17174 // Create a mappable component for the list item. List items in this clause 17175 // only need a component. We use a null declaration to signal fields in 17176 // 'this'. 17177 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17178 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17179 "Unexpected device pointer expression!"); 17180 MVLI.VarBaseDeclarations.push_back( 17181 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17182 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17183 MVLI.VarComponents.back().push_back(MC); 17184 } 17185 17186 if (MVLI.ProcessedVarList.empty()) 17187 return nullptr; 17188 17189 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17190 MVLI.VarBaseDeclarations, 17191 MVLI.VarComponents); 17192 } 17193 17194 OMPClause *Sema::ActOnOpenMPAllocateClause( 17195 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17196 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17197 if (Allocator) { 17198 // OpenMP [2.11.4 allocate Clause, Description] 17199 // allocator is an expression of omp_allocator_handle_t type. 17200 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17201 return nullptr; 17202 17203 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17204 if (AllocatorRes.isInvalid()) 17205 return nullptr; 17206 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17207 DSAStack->getOMPAllocatorHandleT(), 17208 Sema::AA_Initializing, 17209 /*AllowExplicit=*/true); 17210 if (AllocatorRes.isInvalid()) 17211 return nullptr; 17212 Allocator = AllocatorRes.get(); 17213 } else { 17214 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17215 // allocate clauses that appear on a target construct or on constructs in a 17216 // target region must specify an allocator expression unless a requires 17217 // directive with the dynamic_allocators clause is present in the same 17218 // compilation unit. 17219 if (LangOpts.OpenMPIsDevice && 17220 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17221 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17222 } 17223 // Analyze and build list of variables. 17224 SmallVector<Expr *, 8> Vars; 17225 for (Expr *RefExpr : VarList) { 17226 assert(RefExpr && "NULL expr in OpenMP private clause."); 17227 SourceLocation ELoc; 17228 SourceRange ERange; 17229 Expr *SimpleRefExpr = RefExpr; 17230 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17231 if (Res.second) { 17232 // It will be analyzed later. 17233 Vars.push_back(RefExpr); 17234 } 17235 ValueDecl *D = Res.first; 17236 if (!D) 17237 continue; 17238 17239 auto *VD = dyn_cast<VarDecl>(D); 17240 DeclRefExpr *Ref = nullptr; 17241 if (!VD && !CurContext->isDependentContext()) 17242 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17243 Vars.push_back((VD || CurContext->isDependentContext()) 17244 ? RefExpr->IgnoreParens() 17245 : Ref); 17246 } 17247 17248 if (Vars.empty()) 17249 return nullptr; 17250 17251 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17252 ColonLoc, EndLoc, Vars); 17253 } 17254 17255 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 17256 SourceLocation StartLoc, 17257 SourceLocation LParenLoc, 17258 SourceLocation EndLoc) { 17259 SmallVector<Expr *, 8> Vars; 17260 for (Expr *RefExpr : VarList) { 17261 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 17262 SourceLocation ELoc; 17263 SourceRange ERange; 17264 Expr *SimpleRefExpr = RefExpr; 17265 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17266 if (Res.second) 17267 // It will be analyzed later. 17268 Vars.push_back(RefExpr); 17269 ValueDecl *D = Res.first; 17270 if (!D) 17271 continue; 17272 17273 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 17274 // A list-item cannot appear in more than one nontemporal clause. 17275 if (const Expr *PrevRef = 17276 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 17277 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17278 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 17279 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17280 << getOpenMPClauseName(OMPC_nontemporal); 17281 continue; 17282 } 17283 17284 Vars.push_back(RefExpr); 17285 } 17286 17287 if (Vars.empty()) 17288 return nullptr; 17289 17290 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17291 Vars); 17292 } 17293